From c02c81e05b312674fd8e98de31641af1c36c2aaf Mon Sep 17 00:00:00 2001 From: Andrew Carlson Date: Thu, 18 Jun 2020 17:37:55 -0400 Subject: [PATCH 01/25] add custom event listener option --- src/codeflask.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/codeflask.js b/src/codeflask.js index 241a318d..74ecef80 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -100,6 +100,7 @@ export default class CodeFlask { this.opts.areaId = this.opts.areaId || null this.opts.ariaLabelledby = this.opts.ariaLabelledby || null this.opts.readonly = this.opts.readonly || null + this.opts.customEventListeners = this.opts.customEventListeners || {} // if handleTabs is not either true or false, make it true by default if (typeof this.opts.handleTabs !== 'boolean') { @@ -159,6 +160,13 @@ export default class CodeFlask { } listenTextarea () { + const customEventListeners = this.opts.customEventListeners + for (const eventName in customEventListeners) { + if (customEventListeners.hasOwnProperty(eventName)) { + this.elTextarea.addEventListener(eventName, customEventListeners[eventName]) + } + } + this.elTextarea.addEventListener('input', (e) => { this.code = e.target.value this.elCode.innerHTML = escapeHtml(e.target.value) From d90ac22d34d50887b34453f2ac3a8ea917abbf39 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Sun, 6 Mar 2022 12:32:45 -0500 Subject: [PATCH 02/25] publish forked package --- README.md | 168 +++++--------------------------------- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- index.d.ts | 5 ++ package.json | 4 +- 5 files changed, 28 insertions(+), 153 deletions(-) diff --git a/README.md b/README.md index 11e2d9a1..c63f1a2e 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,20 @@ -[![npm version](https://badge.fury.io/js/codeflask.svg)](https://www.npmjs.com/package/codeflask) -[![Build Status](https://travis-ci.org/kazzkiq/CodeFlask.svg?branch=master)](https://travis-ci.org/kazzkiq/CodeFlask) - -

-
- CodeFlask: A micro code-editor for awesome web pages. -

- -

- -

- -## Installation - -You can install CodeFlask via npm: - -``` -npm install codeflask -``` - -Or use it directly in browser via cdn service: - -``` -https://unpkg.com/codeflask/build/codeflask.min.js -``` - -## Usage - -```js -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { language: 'js' }); -``` -You can also pass a DOM element instead of a selector: -```js -import CodeFlask from 'codeflask'; - -const editorElem = document.getElementById('editor'); -const flask = new CodeFlask(editorElem, { language: 'js' }); -``` -Usage with Shadow DOM: -```js -import CodeFlask from 'codeflask'; -... -const shadowElem = this.shadowRoot.querySelector('#editor'); -const flask = new CodeFlask(shadowElem, { language: 'js', styleParent: this.shadowRoot }); -``` -### Listening for changes in editor - -```js -flask.onUpdate((code) => { - // do something with code here. - // this will trigger whenever the code - // in the editor changes. -}); -``` - -### Updating the editor programatically - -```js -// This will also trigger .onUpdate() -flask.updateCode('const my_new_code_here = "Blabla"'); -``` - -### Getting the current code from editor - -```js -const code = flask.getCode(); -``` - -### Enabling line numbers - -```js -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { - language: 'js', - lineNumbers: true -}); -``` - -### Enabling rtl (right to left writing) - -```js -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { - language: 'js', - rtl: true -}); -``` - -### Enabling read only mode - -```js -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { - language: 'js', - readonly: true -}); -``` - -### Adding other languages support: - -```js -flask.addLanguage('ruby', options) -``` - -#### For Example to add 'Ruby' - -```js -import Prism from 'prismjs'; -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { - language: 'ruby', - readonly: true -}); - -flask.addLanguage('ruby', Prism.languages['ruby']); -``` - -This API is simply a proxy to add a new language to [Prism](http://prismjs.com/) itself (the code highlighter). The `options` parameter must be the same accepted in Prism. You can read more about it [here](http://prismjs.com/extending.html#language-definitions). - -By default, CodeFlask supports the following languages (which are also the default supported in Prism): - -- Markup (HTML/XML); -- CSS; -- C-like; -- JavaScript; - -### Adding your own theme to CodeFlask - -By default, CodeFlask comes with a simple theme made from scratch called **[CodeNoon](https://github.com/kazzkiq/CodeFlask.js/blob/master/src/styles/theme-default.js)**. - -You can easily override this theme with your own by writting your own CSS and adding it to your project. If that's the case, you should also disable **CodeNoon** with the `defaultTheme` option: - -```js -import CodeFlask from 'codeflask'; - -const flask = new CodeFlask('#my-selector', { - language: 'js', - defaultTheme: false -}); +I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to attach custom event listeners. + +```bash +npm i '@acarl005/codeflask' +``` + +```javascript +const flask = new CodeFlask(editor, { + language: "html", + customEventListeners: { + "keydown": e => { + if (e.key == "Enter") { + e.preventDefault() + e.stopImmediatePropagation() + // do custom stuff + } + } + } +}) ``` - -# Credits & Thanks - -CodeFlask.js was made possible by awesome open-source projects such as [Prism.js](https://github.com/PrismJS/prism) and [Rollup](https://github.com/rollup/rollup). diff --git a/build/codeflask.min.js b/build/codeflask.min.js index faa1b340..6dd92b0f 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,a='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",(CSS?CSS.supports(e,t):(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+a+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+a+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=a,s.appendChild(i),!0}var r={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function o(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return r[e]})}var l="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var c,u=(function(e){var t="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},n=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,n=0,a=t.Prism={manual:t.Prism&&t.Prism.manual,disableWorkerMessageHandler:t.Prism&&t.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof s?new s(e.type,a.util.encode(e.content),e.alias):"Array"===a.util.type(e)?e.map(a.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(x instanceof l)){if(f&&k!=t.length-1){if(h.lastIndex=v,!(L=h.exec(e)))break;for(var w=L.index+(g?L[1].length:0),C=L.index+L[0].length,S=k,T=v,A=t.length;S=(T+=t[S].length)&&(++k,v=T);if(t[k]instanceof l)continue;F=S-k,x=e.slice(v,T),L.index-=v}else{h.lastIndex=0;var L=h.exec(x),F=1}if(L){g&&(m=L[1]?L[1].length:0);C=(w=L.index+m)+(L=L[0].slice(m)).length;var E=x.slice(0,w),_=x.slice(C),N=[k,F];E&&(++k,v+=E.length,N.push(E));var j=new l(c,p?a.tokenize(L,p):L,b,L,f);if(N.push(j),_&&N.push(_),Array.prototype.splice.apply(t,N),1!=F&&a.matchGrammar(e,t,n,k,v,!0,c),r)break}else if(r)break}}}}},tokenize:function(e,t,n){var s=[e],i=t.rest;if(i){for(var r in i)t[r]=i[r];delete t.rest}return a.matchGrammar(e,s,t,0,0,!1),s},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var s,i=0;s=n[i++];)s(t)}}},s=a.Token=function(e,t,n,a,s){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!s};if(s.stringify=function(e,t,n){if("string"==typeof e)return e;if("Array"===a.util.type(e))return e.map(function(n){return s.stringify(n,t,e)}).join("");var i={type:e.type,content:s.stringify(e.content,t,n),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:n};if(e.alias){var r="Array"===a.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,r)}a.hooks.run("wrap",i);var o=Object.keys(i.attributes).map(function(e){return e+'="'+(i.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+""},!t.document)return t.addEventListener?(a.disableWorkerMessageHandler||t.addEventListener("message",function(e){var n=JSON.parse(e.data),s=n.language,i=n.code,r=n.immediateClose;t.postMessage(a.highlight(i,a.languages[s],s)),r&&t.close()},!1),t.Prism):t.Prism;var i=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return i&&(a.filename=i.src,a.manual||i.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(a.highlightAll):window.setTimeout(a.highlightAll,16):document.addEventListener("DOMContentLoaded",a.highlightAll))),t.Prism}();e.exports&&(e.exports=n),void 0!==l&&(l.Prism=n),n.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),n.languages.xml=n.languages.markup,n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},n.languages.css.atrule.inside.rest=n.languages.css,n.languages.markup&&(n.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:n.languages.css,alias:"language-css",greedy:!0}}),n.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:n.languages.css}},alias:"language-css"}},n.languages.markup.tag)),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/[a-z0-9_]+(?=\()/i,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{keyword:/\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,function:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),n.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"},constant:/\b[A-Z][A-Z\d_]*\b/}),n.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${[^}]+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}}}),n.languages.javascript["template-string"].inside.interpolation.inside.rest=n.languages.javascript,n.languages.markup&&n.languages.insertBefore("markup","tag",{script:{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:n.languages.javascript,alias:"language-javascript",greedy:!0}}),n.languages.js=n.languages.javascript,"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){for(var a,s=t.getAttribute("data-src"),i=t,r=/\blang(?:uage)?-([\w-]+)\b/i;i&&!r.test(i.className);)i=i.parentNode;if(i&&(a=(t.className.match(r)||[,""])[1]),!a){var o=(s.match(/\.(\w+)$/)||[,""])[1];a=e[o]||o}var l=document.createElement("code");l.className="language-"+a,t.textContent="",l.textContent="Loading…",t.appendChild(l);var c=new XMLHttpRequest;c.open("GET",s,!0),c.onreadystatechange=function(){4==c.readyState&&(c.status<400&&c.responseText?(l.textContent=c.responseText,n.highlightElement(l)):c.status>=400?l.textContent="✖ Error "+c.status+" while fetching file: "+c.statusText:l.textContent="✖ Error: File does not exist or is empty")},c.send(null)}),n.plugins.toolbar&&n.plugins.toolbar.registerButton("download-file",function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-src")&&t.hasAttribute("data-download-link")){var n=t.getAttribute("data-src"),a=document.createElement("a");return a.textContent=t.getAttribute("data-download-link-label")||"Download",a.setAttribute("download",""),a.href=n,a}})},document.addEventListener("DOMContentLoaded",self.Prism.fileHighlight))}(c={exports:{}},c.exports),c.exports),d=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};return d.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},d.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},d.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},d.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},d.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},d.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},d.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},d.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},d.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},d.prototype.listenTextarea=function(){var e=this;this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=o(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t)}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},d.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,i=t.value,r=i.substr(0,a),o=i.substring(a,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(a!==s&&o.length>=c.length){var u=a-r.split("\n").pop().length,d=c.length,h=c.length;if(e.shiftKey)i.substr(u,c.length)===c?(d=-d,u>a?(o=o.substring(0,u)+o.substring(u+c.length),h=0):u===a?(d=0,h=0,o=o.substring(c.length)):(h=-h,r=r.substring(0,u)+r.substring(u+c.length))):(d=0,h=0),o=o.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else r=r.substr(0,u)+c+r.substring(u,a),o=o.replace(/\n/g,"\n"+c);t.value=r+o+l,t.selectionStart=a+d,t.selectionEnd=a+o.length+h,t.selectionDirection=n}else t.value=r+c+l,t.selectionStart=a+c.length,t.selectionEnd=a+c.length;var p=t.value;this.updateCode(p),this.elTextarea.selectionEnd=s+this.opts.tabSize}},d.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},d.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},d.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,i=s.substr(0,n),r=s.substring(a),o=s.lastIndexOf("\n",n-1),l=o+s.slice(o+1).search(/[^ ]|$/),c=l>o?l-o:0,u=i+"\n"+" ".repeat(c)+r;t.value=u,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},d.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,i=!a&&["'",'"'].includes(e)?e:"",r=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(r),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var o=e;switch(e){case"(":o=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":o=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+o+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},d.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},d.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=o(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},d.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},d.prototype.addLanguage=function(e,t){u.languages[e]=t},d.prototype.populateDefault=function(){this.updateCode(this.code)},d.prototype.highlight=function(){u.highlightElement(this.elCode,!1)},d.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},d.prototype.getCode=function(){return this.code},d.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},d.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},d.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},d}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,a='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+a+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+a+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function r(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var r=document.createElement("style");return r.innerHTML=e,r.id=a,s.appendChild(r),!0}var i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function o(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return i[e]})}var l="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u,c=(function(e){var t=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);F+=w.value.length,w=w.next){var A=w.value;if(n.length>t.length)return;if(!(A instanceof r)){var C,E=1;if(y){if(!(C=i(x,F,t,b))||C.index>=t.length)break;var S=C.index,L=C.index+C[0].length,T=F;for(T+=w.value.length;S>=T;)w=w.next,T+=w.value.length;if(T-=w.value.length,F=T,w.value instanceof r)continue;for(var _=w;_!==n.tail&&(Td.reach&&(d.reach=z);var P=w.prev;N&&(P=o(n,P,N),F+=N.length),l(n,P,E);var M=new r(p,m?s.tokenize($,m):$,v,$);if(w=o(n,P,M),j&&o(n,w,j),E>1){var O={cause:p+","+g,reach:z};e(t,n,a,w.prev,F,O),d&&O.reach>d.reach&&(d.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=s.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=s.hooks.all[e];if(n&&n.length)for(var a,r=0;a=n[r++];)a(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function i(e,t,n,a){e.lastIndex=t;var s=e.exec(n);if(s&&a&&s[1]){var r=s[1].length;s.index+=r,s[0]=s[0].slice(r)}return s}function o(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function l(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()},!1),s):s;var u=s.util.currentScript();function c(){s.manual||s.highlightAll()}if(u&&(s.filename=u.src,u.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var d=document.readyState;"loading"===d||"interactive"===d&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=t),void 0!==l&&(l.Prism=t),t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(e,n){var a={};a["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[n]},a.cdata=/^$/i;var s={"included-cdata":{pattern://i,inside:a}};s["language-"+n]={pattern:/[\s\S]+/,inside:t.languages[n]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:s},t.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(e,n){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:t.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(t),t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript,function(){if(void 0!==t&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var e=function(e,t){return"✖ Error "+e+" while fetching file: "+t},n="✖ Error: File does not exist or is empty",a={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},s='pre[data-src]:not([data-src-status="loaded"]):not([data-src-status="loading"])';t.hooks.add("before-highlightall",function(e){e.selector+=", "+s}),t.hooks.add("before-sanity-check",function(r){var i=r.element;if(i.matches(s)){r.code="",i.setAttribute("data-src-status","loading");var o=i.appendChild(document.createElement("CODE"));o.textContent="Loading…";var l=i.getAttribute("data-src"),u=r.language;if("none"===u){var c=(/\.(\w+)$/.exec(l)||[,"none"])[1];u=a[c]||c}t.util.setLanguage(o,u),t.util.setLanguage(i,u);var d=t.plugins.autoloader;d&&d.loadLanguages(u),function(t,a,s){var r=new XMLHttpRequest;r.open("GET",t,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?a(r.responseText):r.status>=400?s(e(r.status,r.statusText)):s(n))},r.send(null)}(l,function(e){i.setAttribute("data-src-status","loaded");var n=function(e){var t=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"");if(t){var n=Number(t[1]),a=t[2],s=t[3];return a?s?[n,Number(s)]:[n,void 0]:[n,n]}}(i.getAttribute("data-range"));if(n){var a=e.split(/\r\n?|\n/g),s=n[0],r=null==n[1]?a.length:n[1];s<0&&(s+=a.length),s=Math.max(0,Math.min(s-1,a.length)),r<0&&(r+=a.length),r=Math.max(0,Math.min(r,a.length)),e=a.slice(s,r).join("\n"),i.hasAttribute("data-start")||i.setAttribute("data-start",String(s+1))}o.textContent=e,t.highlightElement(o)},function(e){i.setAttribute("data-src-status","failed"),o.textContent=e})}}),t.plugins.fileHighlight={highlight:function(e){for(var n,a=(e||document).querySelectorAll(s),r=0;n=a[r++];)t.highlightElement(n)}};var r=!1;t.fileHighlight=function(){r||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),r=!0),t.plugins.fileHighlight.highlight.apply(this,arguments)}}}()}(u={exports:{}},u.exports),u.exports),d=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};return d.prototype.startEditor=function(){if(!r(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},d.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},d.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},d.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},d.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},d.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},d.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},d.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&r("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},d.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},d.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=o(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},d.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,r=t.value,i=r.substr(0,a),o=r.substring(a,s),l=r.substring(s),u=" ".repeat(this.opts.tabSize);if(a!==s&&o.length>=u.length){var c=a-i.split("\n").pop().length,d=u.length,p=u.length;if(e.shiftKey)r.substr(c,u.length)===u?(d=-d,c>a?(o=o.substring(0,c)+o.substring(c+u.length),p=0):c===a?(d=0,p=0,o=o.substring(u.length)):(p=-p,i=i.substring(0,c)+i.substring(c+u.length))):(d=0,p=0),o=o.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+u+i.substring(c,a),o=o.replace(/\n/g,"\n"+u);t.value=i+o+l,t.selectionStart=a+d,t.selectionEnd=a+o.length+p,t.selectionDirection=n}else t.value=i+u+l,t.selectionStart=a+u.length,t.selectionEnd=a+u.length;var h=t.value;this.updateCode(h),this.elTextarea.selectionEnd=s+this.opts.tabSize}},d.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},d.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},d.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,r=s.substr(0,n),i=s.substring(a),o=s.lastIndexOf("\n",n-1),l=o+s.slice(o+1).search(/[^ ]|$/),u=l>o?l-o:0,c=r+"\n"+" ".repeat(u)+i;t.value=c,t.selectionStart=n+u+1,t.selectionEnd=n+u+1,this.updateCode(t.value)}},d.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,r=!a&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+r+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var o=e;switch(e){case"(":o=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":o=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),u=""+this.code.substring(0,t)+l+o+this.code.substring(n);this.updateCode(u)}this.elTextarea.selectionEnd=t},d.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},d.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=o(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},d.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},d.prototype.addLanguage=function(e,t){c.languages[e]=t},d.prototype.populateDefault=function(){this.updateCode(this.code)},d.prototype.highlight=function(){c.highlightElement(this.elCode,!1)},d.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},d.prototype.getCode=function(){return this.code},d.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},d.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},d.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},d}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 809faf3a..cd877ee2 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return CSS?CSS.supports(e,t):toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var o=document.createElement("style");return o.innerHTML=e,o.id=a,s.appendChild(o),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var commonjsGlobal="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var prism=createCommonjsModule(function(e){var t="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},n=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,n=0,a=t.Prism={manual:t.Prism&&t.Prism.manual,disableWorkerMessageHandler:t.Prism&&t.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof s?new s(e.type,a.util.encode(e.content),e.alias):"Array"===a.util.type(e)?e.map(a.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(v instanceof l)){if(f&&y!=t.length-1){if(h.lastIndex=C,!(_=h.exec(e)))break;for(var x=_.index+(g?_[1].length:0),w=_.index+_[0].length,F=y,T=C,L=t.length;F=(T+=t[F].length)&&(++y,C=T);if(t[y]instanceof l)continue;E=F-y,v=e.slice(C,T),_.index-=C}else{h.lastIndex=0;var _=h.exec(v),E=1}if(_){g&&(m=_[1]?_[1].length:0);w=(x=_.index+m)+(_=_[0].slice(m)).length;var N=v.slice(0,x),S=v.slice(w),A=[y,E];N&&(++y,C+=N.length,A.push(N));var I=new l(c,p?a.tokenize(_,p):_,b,_,f);if(A.push(I),S&&A.push(S),Array.prototype.splice.apply(t,A),1!=E&&a.matchGrammar(e,t,n,y,C,!0,c),i)break}else if(i)break}}}}},tokenize:function(e,t,n){var s=[e],o=t.rest;if(o){for(var i in o)t[i]=o[i];delete t.rest}return a.matchGrammar(e,s,t,0,0,!1),s},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var s,o=0;s=n[o++];)s(t)}}},s=a.Token=function(e,t,n,a,s){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!s};if(s.stringify=function(e,t,n){if("string"==typeof e)return e;if("Array"===a.util.type(e))return e.map(function(n){return s.stringify(n,t,e)}).join("");var o={type:e.type,content:s.stringify(e.content,t,n),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:n};if(e.alias){var i="Array"===a.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(o.classes,i)}a.hooks.run("wrap",o);var r=Object.keys(o.attributes).map(function(e){return e+'="'+(o.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+(r?" "+r:"")+">"+o.content+""},!t.document)return t.addEventListener?(a.disableWorkerMessageHandler||t.addEventListener("message",function(e){var n=JSON.parse(e.data),s=n.language,o=n.code,i=n.immediateClose;t.postMessage(a.highlight(o,a.languages[s],s)),i&&t.close()},!1),t.Prism):t.Prism;var o=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return o&&(a.filename=o.src,a.manual||o.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(a.highlightAll):window.setTimeout(a.highlightAll,16):document.addEventListener("DOMContentLoaded",a.highlightAll))),t.Prism}();e.exports&&(e.exports=n),void 0!==commonjsGlobal&&(commonjsGlobal.Prism=n),n.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),n.languages.xml=n.languages.markup,n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},n.languages.css.atrule.inside.rest=n.languages.css,n.languages.markup&&(n.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:n.languages.css,alias:"language-css",greedy:!0}}),n.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:n.languages.css}},alias:"language-css"}},n.languages.markup.tag)),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/[a-z0-9_]+(?=\()/i,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{keyword:/\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,function:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),n.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"},constant:/\b[A-Z][A-Z\d_]*\b/}),n.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${[^}]+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}}}),n.languages.javascript["template-string"].inside.interpolation.inside.rest=n.languages.javascript,n.languages.markup&&n.languages.insertBefore("markup","tag",{script:{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:n.languages.javascript,alias:"language-javascript",greedy:!0}}),n.languages.js=n.languages.javascript,"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){for(var a,s=t.getAttribute("data-src"),o=t,i=/\blang(?:uage)?-([\w-]+)\b/i;o&&!i.test(o.className);)o=o.parentNode;if(o&&(a=(t.className.match(i)||[,""])[1]),!a){var r=(s.match(/\.(\w+)$/)||[,""])[1];a=e[r]||r}var l=document.createElement("code");l.className="language-"+a,t.textContent="",l.textContent="Loading…",t.appendChild(l);var c=new XMLHttpRequest;c.open("GET",s,!0),c.onreadystatechange=function(){4==c.readyState&&(c.status<400&&c.responseText?(l.textContent=c.responseText,n.highlightElement(l)):c.status>=400?l.textContent="✖ Error "+c.status+" while fetching file: "+c.statusText:l.textContent="✖ Error: File does not exist or is empty")},c.send(null)}),n.plugins.toolbar&&n.plugins.toolbar.registerButton("download-file",function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-src")&&t.hasAttribute("data-download-link")){var n=t.getAttribute("data-src"),a=document.createElement("a");return a.textContent=t.getAttribute("data-download-link-label")||"Download",a.setAttribute("download",""),a.href=n,a}})},document.addEventListener("DOMContentLoaded",self.Prism.fileHighlight))}),CodeFlask=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this;this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t)}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,o=t.value,i=o.substr(0,a),r=o.substring(a,s),l=o.substring(s),c=" ".repeat(this.opts.tabSize);if(a!==s&&r.length>=c.length){var u=a-i.split("\n").pop().length,d=c.length,h=c.length;if(e.shiftKey)o.substr(u,c.length)===c?(d=-d,u>a?(r=r.substring(0,u)+r.substring(u+c.length),h=0):u===a?(d=0,h=0,r=r.substring(c.length)):(h=-h,i=i.substring(0,u)+i.substring(u+c.length))):(d=0,h=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else i=i.substr(0,u)+c+i.substring(u,a),r=r.replace(/\n/g,"\n"+c);t.value=i+r+l,t.selectionStart=a+d,t.selectionEnd=a+r.length+h,t.selectionDirection=n}else t.value=i+c+l,t.selectionStart=a+c.length,t.selectionEnd=a+c.length;var p=t.value;this.updateCode(p),this.elTextarea.selectionEnd=s+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,o=s.substr(0,n),i=s.substring(a),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,u=o+"\n"+" ".repeat(c)+i;t.value=u,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,o=!a&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+o+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var r=document.createElement("style");return r.innerHTML=e,r.id=a,s.appendChild(r),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var prism=createCommonjsModule(function(e){var t=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);C+=F.value.length,F=F.next){var w=F.value;if(n.length>t.length)return;if(!(w instanceof r)){var A,E=1;if(k){if(!(A=i(x,C,t,b))||A.index>=t.length)break;var _=A.index,L=A.index+A[0].length,T=C;for(T+=F.value.length;_>=T;)F=F.next,T+=F.value.length;if(T-=F.value.length,C=T,F.value instanceof r)continue;for(var S=F;S!==n.tail&&(Td.reach&&(d.reach=j);var M=F.prev;$&&(M=o(n,M,$),C+=$.length),l(n,M,E);var O=new r(p,m?s.tokenize(N,m):N,y,N);if(F=o(n,M,O),I&&o(n,F,I),E>1){var z={cause:p+","+g,reach:j};e(t,n,a,F.prev,C,z),d&&z.reach>d.reach&&(d.reach=z.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=s.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=s.hooks.all[e];if(n&&n.length)for(var a,r=0;a=n[r++];)a(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function i(e,t,n,a){e.lastIndex=t;var s=e.exec(n);if(s&&a&&s[1]){var r=s[1].length;s.index+=r,s[0]=s[0].slice(r)}return s}function o(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function l(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()},!1),s):s;var u=s.util.currentScript();function c(){s.manual||s.highlightAll()}if(u&&(s.filename=u.src,u.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var d=document.readyState;"loading"===d||"interactive"===d&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=t),void 0!==commonjsGlobal&&(commonjsGlobal.Prism=t),t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(e,n){var a={};a["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[n]},a.cdata=/^$/i;var s={"included-cdata":{pattern://i,inside:a}};s["language-"+n]={pattern:/[\s\S]+/,inside:t.languages[n]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:s},t.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(e,n){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:t.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(t),t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript,function(){if(void 0!==t&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var e=function(e,t){return"✖ Error "+e+" while fetching file: "+t},n="✖ Error: File does not exist or is empty",a={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},s='pre[data-src]:not([data-src-status="loaded"]):not([data-src-status="loading"])';t.hooks.add("before-highlightall",function(e){e.selector+=", "+s}),t.hooks.add("before-sanity-check",function(r){var i=r.element;if(i.matches(s)){r.code="",i.setAttribute("data-src-status","loading");var o=i.appendChild(document.createElement("CODE"));o.textContent="Loading…";var l=i.getAttribute("data-src"),u=r.language;if("none"===u){var c=(/\.(\w+)$/.exec(l)||[,"none"])[1];u=a[c]||c}t.util.setLanguage(o,u),t.util.setLanguage(i,u);var d=t.plugins.autoloader;d&&d.loadLanguages(u),function(t,a,s){var r=new XMLHttpRequest;r.open("GET",t,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?a(r.responseText):r.status>=400?s(e(r.status,r.statusText)):s(n))},r.send(null)}(l,function(e){i.setAttribute("data-src-status","loaded");var n=function(e){var t=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"");if(t){var n=Number(t[1]),a=t[2],s=t[3];return a?s?[n,Number(s)]:[n,void 0]:[n,n]}}(i.getAttribute("data-range"));if(n){var a=e.split(/\r\n?|\n/g),s=n[0],r=null==n[1]?a.length:n[1];s<0&&(s+=a.length),s=Math.max(0,Math.min(s-1,a.length)),r<0&&(r+=a.length),r=Math.max(0,Math.min(r,a.length)),e=a.slice(s,r).join("\n"),i.hasAttribute("data-start")||i.setAttribute("data-start",String(s+1))}o.textContent=e,t.highlightElement(o)},function(e){i.setAttribute("data-src-status","failed"),o.textContent=e})}}),t.plugins.fileHighlight={highlight:function(e){for(var n,a=(e||document).querySelectorAll(s),r=0;n=a[r++];)t.highlightElement(n)}};var r=!1;t.fileHighlight=function(){r||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),r=!0),t.plugins.fileHighlight.highlight.apply(this,arguments)}}}()}),CodeFlask=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,r=t.value,i=r.substr(0,a),o=r.substring(a,s),l=r.substring(s),u=" ".repeat(this.opts.tabSize);if(a!==s&&o.length>=u.length){var c=a-i.split("\n").pop().length,d=u.length,p=u.length;if(e.shiftKey)r.substr(c,u.length)===u?(d=-d,c>a?(o=o.substring(0,c)+o.substring(c+u.length),p=0):c===a?(d=0,p=0,o=o.substring(u.length)):(p=-p,i=i.substring(0,c)+i.substring(c+u.length))):(d=0,p=0),o=o.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+u+i.substring(c,a),o=o.replace(/\n/g,"\n"+u);t.value=i+o+l,t.selectionStart=a+d,t.selectionEnd=a+o.length+p,t.selectionDirection=n}else t.value=i+u+l,t.selectionStart=a+u.length,t.selectionEnd=a+u.length;var h=t.value;this.updateCode(h),this.elTextarea.selectionEnd=s+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,r=s.substr(0,n),i=s.substring(a),o=s.lastIndexOf("\n",n-1),l=o+s.slice(o+1).search(/[^ ]|$/),u=l>o?l-o:0,c=r+"\n"+" ".repeat(u)+i;t.value=c,t.selectionStart=n+u+1,t.selectionEnd=n+u+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,r=!a&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+r+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var o=e;switch(e){case"(":o=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":o=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),u=""+this.code.substring(0,t)+l+o+this.code.substring(n);this.updateCode(u)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/index.d.ts b/index.d.ts index 838e3556..265cdead 100644 --- a/index.d.ts +++ b/index.d.ts @@ -6,6 +6,10 @@ export type LanguageDefinition = { [token: string]: prism.LanguageDefinition | RegExp } +export type EventListeners = { + [index: string]: (UIEvent) => void +} + export interface CodeFlaskOptions { language?: string rtl?: boolean @@ -16,6 +20,7 @@ export interface CodeFlaskOptions { areaId?: string ariaLabelledby?: string readonly?: boolean + customEventListeners?: EventListeners } export default class CodeFlask { diff --git a/package.json b/package.json index bc417db3..f2518bc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "codeflask", - "version": "1.4.1", + "name": "@acarl005/codeflask", + "version": "1.4.2", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From fa848d3cc7e1d10ff14a7281ddd7186c93d3f57a Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 16 Mar 2022 00:44:42 -0400 Subject: [PATCH 03/25] make Prism a peer dependency --- README.md | 17 +++++++++++++++-- package.json | 6 ++++-- src/codeflask.js | 22 +++++++++++----------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c63f1a2e..605c164f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,19 @@ -I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to attach custom event listeners. +# CodeFlask Mod ```bash npm i '@acarl005/codeflask' ``` +I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to... + +1. Make PrismJS a peer dependency +1. Attach custom event listeners to the editor + ```javascript -const flask = new CodeFlask(editor, { +import CodeFlask from "codeflask" +import Prism from "prismjs" + +const flask = new CodeFlask(editor, Prism, { language: "html", customEventListeners: { "keydown": e => { @@ -18,3 +26,8 @@ const flask = new CodeFlask(editor, { } }) ``` + +PrismJS is highly customizable. +It actually offers custom builds with more plugins that you can opt into. +This is an awesome and rare feature b/c you can minimize the bundle by omitting unneeded functionality. +Therefore, it should be a peer dependency, b/c CodeFlask can't know which build with which plugins you'll need. \ No newline at end of file diff --git a/package.json b/package.json index f2518bc2..d7084f87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "1.4.2", + "version": "2.0.0", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", @@ -21,7 +21,9 @@ "prepublishOnly": "npm install && npm run build" }, "dependencies": { - "@types/prismjs": "^1.9.1", + "@types/prismjs": "^1.9.1" + }, + "peerDependencies": { "prismjs": "^1.14.0" }, "devDependencies": { diff --git a/src/codeflask.js b/src/codeflask.js index 74ecef80..c94d27d0 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -2,20 +2,19 @@ import { editorCss } from './styles/editor' import { injectCss } from './styles/injector' import { defaultCssTheme } from './styles/theme-default' import { escapeHtml } from './utils/html-escape' -import Prism from 'prismjs' export default class CodeFlask { - constructor (selectorOrElement, opts) { + constructor (selectorOrElement, Prism, opts) { if (!selectorOrElement) { - // If no selector or element is passed to CodeFlask, - // stop execution and throw error. - throw Error('CodeFlask expects a parameter which is Element or a String selector') + throw Error('CodeFlask expects 1st parameter to be an Element or a String selector') + } + + if (!Prism) { + throw Error('CodeFlask expects 2nd parameter to be the Prism peer dependency') } if (!opts) { - // If no selector or element is passed to CodeFlask, - // stop execution and throw error. - throw Error('CodeFlask expects an object containing options as second parameter') + throw Error('CodeFlask expects 3rd parameter to be an object containing options') } if (selectorOrElement.nodeType) { @@ -32,6 +31,7 @@ export default class CodeFlask { } } + this.Prism = Prism this.opts = opts this.startEditor() } @@ -161,7 +161,7 @@ export default class CodeFlask { listenTextarea () { const customEventListeners = this.opts.customEventListeners - for (const eventName in customEventListeners) { + for (const eventName in customEventListeners) { if (customEventListeners.hasOwnProperty(eventName)) { this.elTextarea.addEventListener(eventName, customEventListeners[eventName]) } @@ -400,7 +400,7 @@ export default class CodeFlask { } addLanguage (name, options) { - Prism.languages[name] = options + this.Prism.languages[name] = options } populateDefault () { @@ -408,7 +408,7 @@ export default class CodeFlask { } highlight () { - Prism.highlightElement(this.elCode, false) + this.Prism.highlightElement(this.elCode, false) } onUpdate (callback) { From 421fba2464da3107ac7d1c44105c6e3994ccc4ce Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 16 Mar 2022 01:13:32 -0400 Subject: [PATCH 04/25] allow any prism version --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 6dd92b0f..9c416158 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,a='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+a+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+a+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function r(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var r=document.createElement("style");return r.innerHTML=e,r.id=a,s.appendChild(r),!0}var i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function o(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return i[e]})}var l="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u,c=(function(e){var t=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);F+=w.value.length,w=w.next){var A=w.value;if(n.length>t.length)return;if(!(A instanceof r)){var C,E=1;if(y){if(!(C=i(x,F,t,b))||C.index>=t.length)break;var S=C.index,L=C.index+C[0].length,T=F;for(T+=w.value.length;S>=T;)w=w.next,T+=w.value.length;if(T-=w.value.length,F=T,w.value instanceof r)continue;for(var _=w;_!==n.tail&&(Td.reach&&(d.reach=z);var P=w.prev;N&&(P=o(n,P,N),F+=N.length),l(n,P,E);var M=new r(p,m?s.tokenize($,m):$,v,$);if(w=o(n,P,M),j&&o(n,w,j),E>1){var O={cause:p+","+g,reach:z};e(t,n,a,w.prev,F,O),d&&O.reach>d.reach&&(d.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=s.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=s.hooks.all[e];if(n&&n.length)for(var a,r=0;a=n[r++];)a(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function i(e,t,n,a){e.lastIndex=t;var s=e.exec(n);if(s&&a&&s[1]){var r=s[1].length;s.index+=r,s[0]=s[0].slice(r)}return s}function o(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function l(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()},!1),s):s;var u=s.util.currentScript();function c(){s.manual||s.highlightAll()}if(u&&(s.filename=u.src,u.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var d=document.readyState;"loading"===d||"interactive"===d&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=t),void 0!==l&&(l.Prism=t),t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(e,n){var a={};a["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[n]},a.cdata=/^$/i;var s={"included-cdata":{pattern://i,inside:a}};s["language-"+n]={pattern:/[\s\S]+/,inside:t.languages[n]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:s},t.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(e,n){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:t.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(t),t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript,function(){if(void 0!==t&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var e=function(e,t){return"✖ Error "+e+" while fetching file: "+t},n="✖ Error: File does not exist or is empty",a={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},s='pre[data-src]:not([data-src-status="loaded"]):not([data-src-status="loading"])';t.hooks.add("before-highlightall",function(e){e.selector+=", "+s}),t.hooks.add("before-sanity-check",function(r){var i=r.element;if(i.matches(s)){r.code="",i.setAttribute("data-src-status","loading");var o=i.appendChild(document.createElement("CODE"));o.textContent="Loading…";var l=i.getAttribute("data-src"),u=r.language;if("none"===u){var c=(/\.(\w+)$/.exec(l)||[,"none"])[1];u=a[c]||c}t.util.setLanguage(o,u),t.util.setLanguage(i,u);var d=t.plugins.autoloader;d&&d.loadLanguages(u),function(t,a,s){var r=new XMLHttpRequest;r.open("GET",t,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?a(r.responseText):r.status>=400?s(e(r.status,r.statusText)):s(n))},r.send(null)}(l,function(e){i.setAttribute("data-src-status","loaded");var n=function(e){var t=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"");if(t){var n=Number(t[1]),a=t[2],s=t[3];return a?s?[n,Number(s)]:[n,void 0]:[n,n]}}(i.getAttribute("data-range"));if(n){var a=e.split(/\r\n?|\n/g),s=n[0],r=null==n[1]?a.length:n[1];s<0&&(s+=a.length),s=Math.max(0,Math.min(s-1,a.length)),r<0&&(r+=a.length),r=Math.max(0,Math.min(r,a.length)),e=a.slice(s,r).join("\n"),i.hasAttribute("data-start")||i.setAttribute("data-start",String(s+1))}o.textContent=e,t.highlightElement(o)},function(e){i.setAttribute("data-src-status","failed"),o.textContent=e})}}),t.plugins.fileHighlight={highlight:function(e){for(var n,a=(e||document).querySelectorAll(s),r=0;n=a[r++];)t.highlightElement(n)}};var r=!1;t.fileHighlight=function(){r||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),r=!0),t.plugins.fileHighlight.highlight.apply(this,arguments)}}}()}(u={exports:{}},u.exports),u.exports),d=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};return d.prototype.startEditor=function(){if(!r(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},d.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},d.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},d.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},d.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},d.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},d.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},d.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&r("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},d.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},d.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=o(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},d.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,r=t.value,i=r.substr(0,a),o=r.substring(a,s),l=r.substring(s),u=" ".repeat(this.opts.tabSize);if(a!==s&&o.length>=u.length){var c=a-i.split("\n").pop().length,d=u.length,p=u.length;if(e.shiftKey)r.substr(c,u.length)===u?(d=-d,c>a?(o=o.substring(0,c)+o.substring(c+u.length),p=0):c===a?(d=0,p=0,o=o.substring(u.length)):(p=-p,i=i.substring(0,c)+i.substring(c+u.length))):(d=0,p=0),o=o.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+u+i.substring(c,a),o=o.replace(/\n/g,"\n"+u);t.value=i+o+l,t.selectionStart=a+d,t.selectionEnd=a+o.length+p,t.selectionDirection=n}else t.value=i+u+l,t.selectionStart=a+u.length,t.selectionEnd=a+u.length;var h=t.value;this.updateCode(h),this.elTextarea.selectionEnd=s+this.opts.tabSize}},d.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},d.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},d.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,r=s.substr(0,n),i=s.substring(a),o=s.lastIndexOf("\n",n-1),l=o+s.slice(o+1).search(/[^ ]|$/),u=l>o?l-o:0,c=r+"\n"+" ".repeat(u)+i;t.value=c,t.selectionStart=n+u+1,t.selectionEnd=n+u+1,this.updateCode(t.value)}},d.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,r=!a&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+r+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var o=e;switch(e){case"(":o=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":o=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),u=""+this.code.substring(0,t)+l+o+this.code.substring(n);this.updateCode(u)}this.elTextarea.selectionEnd=t},d.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},d.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=o(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},d.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},d.prototype.addLanguage=function(e,t){c.languages[e]=t},d.prototype.populateDefault=function(){this.updateCode(this.code)},d.prototype.highlight=function(){c.highlightElement(this.elCode,!1)},d.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},d.prototype.getCode=function(){return this.code},d.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},d.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},d.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},d}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function a(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=o,s.appendChild(a),!0}var i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return i[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!a(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,a=t.value,i=a.substr(0,o),r=a.substring(o,s),l=a.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-i.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)a.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,i=i.substring(0,d)+i.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else i=i.substr(0,d)+c+i.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=i+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=i+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,a=s.substr(0,n),i=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=a+"\n"+" ".repeat(c)+i;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,a=!o&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index cd877ee2..eb9bd088 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var a=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(a))return!0;var r=document.createElement("style");return r.innerHTML=e,r.id=a,s.appendChild(r),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var prism=createCommonjsModule(function(e){var t=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);C+=F.value.length,F=F.next){var w=F.value;if(n.length>t.length)return;if(!(w instanceof r)){var A,E=1;if(k){if(!(A=i(x,C,t,b))||A.index>=t.length)break;var _=A.index,L=A.index+A[0].length,T=C;for(T+=F.value.length;_>=T;)F=F.next,T+=F.value.length;if(T-=F.value.length,C=T,F.value instanceof r)continue;for(var S=F;S!==n.tail&&(Td.reach&&(d.reach=j);var M=F.prev;$&&(M=o(n,M,$),C+=$.length),l(n,M,E);var O=new r(p,m?s.tokenize(N,m):N,y,N);if(F=o(n,M,O),I&&o(n,F,I),E>1){var z={cause:p+","+g,reach:j};e(t,n,a,F.prev,C,z),d&&z.reach>d.reach&&(d.reach=z.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=s.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=s.hooks.all[e];if(n&&n.length)for(var a,r=0;a=n[r++];)a(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function i(e,t,n,a){e.lastIndex=t;var s=e.exec(n);if(s&&a&&s[1]){var r=s[1].length;s.index+=r,s[0]=s[0].slice(r)}return s}function o(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function l(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()},!1),s):s;var u=s.util.currentScript();function c(){s.manual||s.highlightAll()}if(u&&(s.filename=u.src,u.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var d=document.readyState;"loading"===d||"interactive"===d&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=t),void 0!==commonjsGlobal&&(commonjsGlobal.Prism=t),t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(e,n){var a={};a["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[n]},a.cdata=/^$/i;var s={"included-cdata":{pattern://i,inside:a}};s["language-"+n]={pattern:/[\s\S]+/,inside:t.languages[n]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:s},t.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(e,n){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:t.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(t),t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript,function(){if(void 0!==t&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var e=function(e,t){return"✖ Error "+e+" while fetching file: "+t},n="✖ Error: File does not exist or is empty",a={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},s='pre[data-src]:not([data-src-status="loaded"]):not([data-src-status="loading"])';t.hooks.add("before-highlightall",function(e){e.selector+=", "+s}),t.hooks.add("before-sanity-check",function(r){var i=r.element;if(i.matches(s)){r.code="",i.setAttribute("data-src-status","loading");var o=i.appendChild(document.createElement("CODE"));o.textContent="Loading…";var l=i.getAttribute("data-src"),u=r.language;if("none"===u){var c=(/\.(\w+)$/.exec(l)||[,"none"])[1];u=a[c]||c}t.util.setLanguage(o,u),t.util.setLanguage(i,u);var d=t.plugins.autoloader;d&&d.loadLanguages(u),function(t,a,s){var r=new XMLHttpRequest;r.open("GET",t,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?a(r.responseText):r.status>=400?s(e(r.status,r.statusText)):s(n))},r.send(null)}(l,function(e){i.setAttribute("data-src-status","loaded");var n=function(e){var t=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"");if(t){var n=Number(t[1]),a=t[2],s=t[3];return a?s?[n,Number(s)]:[n,void 0]:[n,n]}}(i.getAttribute("data-range"));if(n){var a=e.split(/\r\n?|\n/g),s=n[0],r=null==n[1]?a.length:n[1];s<0&&(s+=a.length),s=Math.max(0,Math.min(s-1,a.length)),r<0&&(r+=a.length),r=Math.max(0,Math.min(r,a.length)),e=a.slice(s,r).join("\n"),i.hasAttribute("data-start")||i.setAttribute("data-start",String(s+1))}o.textContent=e,t.highlightElement(o)},function(e){i.setAttribute("data-src-status","failed"),o.textContent=e})}}),t.plugins.fileHighlight={highlight:function(e){for(var n,a=(e||document).querySelectorAll(s),r=0;n=a[r++];)t.highlightElement(n)}};var r=!1;t.fileHighlight=function(){r||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),r=!0),t.plugins.fileHighlight.highlight.apply(this,arguments)}}}()}),CodeFlask=function(e,t){if(!e)throw Error("CodeFlask expects a parameter which is Element or a String selector");if(!t)throw Error("CodeFlask expects an object containing options as second parameter");if(e.nodeType)this.editorRoot=e;else{var n=document.querySelector(e);n&&(this.editorRoot=n)}this.opts=t,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,a=t.selectionStart,s=t.selectionEnd,r=t.value,i=r.substr(0,a),o=r.substring(a,s),l=r.substring(s),u=" ".repeat(this.opts.tabSize);if(a!==s&&o.length>=u.length){var c=a-i.split("\n").pop().length,d=u.length,p=u.length;if(e.shiftKey)r.substr(c,u.length)===u?(d=-d,c>a?(o=o.substring(0,c)+o.substring(c+u.length),p=0):c===a?(d=0,p=0,o=o.substring(u.length)):(p=-p,i=i.substring(0,c)+i.substring(c+u.length))):(d=0,p=0),o=o.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+u+i.substring(c,a),o=o.replace(/\n/g,"\n"+u);t.value=i+o+l,t.selectionStart=a+d,t.selectionEnd=a+o.length+p,t.selectionDirection=n}else t.value=i+u+l,t.selectionStart=a+u.length,t.selectionEnd=a+u.length;var h=t.value;this.updateCode(h),this.elTextarea.selectionEnd=s+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,a=t.selectionEnd,s=t.value,r=s.substr(0,n),i=s.substring(a),o=s.lastIndexOf("\n",n-1),l=o+s.slice(o+1).search(/[^ ]|$/),u=l>o?l-o:0,c=r+"\n"+" ".repeat(u)+i;t.value=c,t.selectionStart=n+u+1,t.selectionEnd=n+u+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var a=this.code.substr(n,1)===e,s=a?n+1:n,r=!a&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+r+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var o=e;switch(e){case"(":o=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":o=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),u=""+this.code.substring(0,t)+l+o+this.code.substring(n);this.updateCode(u)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,a=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!a},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index d7084f87..e35d96f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.0", + "version": "2.0.1", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", @@ -21,7 +21,7 @@ "prepublishOnly": "npm install && npm run build" }, "dependencies": { - "@types/prismjs": "^1.9.1" + "@types/prismjs": "*" }, "peerDependencies": { "prismjs": "^1.14.0" From a00dd2f3bad0e93c445599ea9e9cd8b59ca3d881 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 16 Mar 2022 01:15:06 -0400 Subject: [PATCH 05/25] fix typo --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e35d96f9..ee9e57c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.1", + "version": "2.0.2", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", @@ -21,10 +21,10 @@ "prepublishOnly": "npm install && npm run build" }, "dependencies": { - "@types/prismjs": "*" + "@types/prismjs": "^1.9.1" }, "peerDependencies": { - "prismjs": "^1.14.0" + "prismjs": "*" }, "devDependencies": { "@wdio/cli": "^6.1.15", From d3c17e7fb08d0a68cf817ded7f6ab1264b0ab66d Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 18:41:43 -0400 Subject: [PATCH 06/25] support line highlight plugin in PrismJS --- src/codeflask.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/codeflask.js b/src/codeflask.js index c94d27d0..6bd73f71 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -411,6 +411,18 @@ export default class CodeFlask { this.Prism.highlightElement(this.elCode, false) } + highlightLines(lineSpec) { + /* This requires the "line-highlight" plugin in PrismJS + Examples + 5: The 5th line + 1-5: Lines 1 through 5 + 1,4: Line 1 and line 4 + 1-2, 5, 9-20: Lines 1 through 2, line 5, lines 9 through 20 + Pass empty string to remove highlighting from all lines + */ + this.elPre.setAttribute('data-line', lineSpec) + } + onUpdate (callback) { if (callback && {}.toString.call(callback) !== '[object Function]') { throw Error('CodeFlask expects callback of type Function') From eee80ab7a9ee2650a1303cc1719ffae6e94da7eb Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 18:41:59 -0400 Subject: [PATCH 07/25] bump patch version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee9e57c0..449276a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.2", + "version": "2.0.3", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From 3c9bb69773efefe93057698fa7afc273aebf5b59 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 18:42:20 -0400 Subject: [PATCH 08/25] build --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 9c416158..058d8d69 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function a(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=o,s.appendChild(a),!0}var i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return i[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!a(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,a=t.value,i=a.substr(0,o),r=a.substring(o,s),l=a.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-i.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)a.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,i=i.substring(0,d)+i.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else i=i.substr(0,d)+c+i.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=i+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=i+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,a=s.substr(0,n),i=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=a+"\n"+" ".repeat(c)+i;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,a=!o&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(s);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index eb9bd088..1143613e 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; From 63b4e4dde511296e2dd275b884d4da4f05b9aa4b Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 18:44:05 -0400 Subject: [PATCH 09/25] update readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 605c164f..408d9283 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to... 1. Make PrismJS a peer dependency 1. Attach custom event listeners to the editor +1. Support the [Line Highlight](https://prismjs.com/plugins/line-highlight/) plugin in PrismJS ```javascript import CodeFlask from "codeflask" @@ -25,6 +26,8 @@ const flask = new CodeFlask(editor, Prism, { } } }) + +flask.highlightLines("4-7") ``` PrismJS is highly customizable. From 7ef140330a7ca534959d8ada307f808398cfbd3e Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 18:46:51 -0400 Subject: [PATCH 10/25] update lines --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/codeflask.js | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 058d8d69..c13a8730 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,s='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',o="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+s+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+s+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(o,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,i=t.value,a=i.substr(0,s),r=i.substring(s,o),l=i.substring(o),c=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=c.length){var d=s-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>s?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===s?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,s),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=s+c.length,t.selectionEnd=s+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,i=o.substr(0,n),a=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(o);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),setTimeout(this.runUpdate.bind(this),1)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 1143613e..edc575f8 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index 449276a6..c8f10cd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.3", + "version": "2.0.4", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/codeflask.js b/src/codeflask.js index 6bd73f71..aadb835d 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -421,6 +421,7 @@ export default class CodeFlask { Pass empty string to remove highlighting from all lines */ this.elPre.setAttribute('data-line', lineSpec) + setTimeout(this.runUpdate.bind(this), 1) } onUpdate (callback) { From ea500953dac79fbd5f1bfd1e2ac55fbc164cbbbf Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 17 Mar 2022 19:11:02 -0400 Subject: [PATCH 11/25] fix bug where highlightLines doesnt update the dom --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/codeflask.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index c13a8730..2f2f8b1e 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,s='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',o="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+s+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+s+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(o,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,i=t.value,a=i.substr(0,s),r=i.substring(s,o),l=i.substring(o),c=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=c.length){var d=s-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>s?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===s?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,s),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=s+c.length,t.selectionEnd=s+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,i=o.substr(0,n),a=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(o);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),setTimeout(this.runUpdate.bind(this),1)},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index edc575f8..9d31f476 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index c8f10cd1..4fe89eaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.4", + "version": "2.0.5", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/codeflask.js b/src/codeflask.js index aadb835d..9509c2e0 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -421,7 +421,7 @@ export default class CodeFlask { Pass empty string to remove highlighting from all lines */ this.elPre.setAttribute('data-line', lineSpec) - setTimeout(this.runUpdate.bind(this), 1) + this.highlight() } onUpdate (callback) { From c4b56038c7eb80fdae75098d080f42556663bf6a Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Sat, 26 Mar 2022 10:20:05 -0400 Subject: [PATCH 12/25] fix horizontal scrolling issue --- README.md | 3 ++- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/codeflask.js | 1 + src/styles/editor.js | 6 ++++-- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 408d9283..9752eba9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to... 1. Make PrismJS a peer dependency 1. Attach custom event listeners to the editor 1. Support the [Line Highlight](https://prismjs.com/plugins/line-highlight/) plugin in PrismJS +1. Fix this issue: kazzkiq/CodeFlask#69 ```javascript import CodeFlask from "codeflask" @@ -33,4 +34,4 @@ flask.highlightLines("4-7") PrismJS is highly customizable. It actually offers custom builds with more plugins that you can opt into. This is an awesome and rare feature b/c you can minimize the bundle by omitting unneeded functionality. -Therefore, it should be a peer dependency, b/c CodeFlask can't know which build with which plugins you'll need. \ No newline at end of file +Therefore, it should be a peer dependency, b/c CodeFlask can't know which build with which plugins you'll need. diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 2f2f8b1e..567f9040 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 9d31f476..6f8b3d6d 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n z-index: 2;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index 4fe89eaa..fdc6f3ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.5", + "version": "2.0.6", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/codeflask.js b/src/codeflask.js index 9509c2e0..eb2e326f 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -190,6 +190,7 @@ export default class CodeFlask { this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)` if (this.elLineNumbers) { this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)` + this.elPre.style.width = `calc(100% - 40px + ${e.target.scrollLeft}px)` } }) } diff --git a/src/styles/editor.js b/src/styles/editor.js index fb6aba2c..02df9a55 100644 --- a/src/styles/editor.js +++ b/src/styles/editor.js @@ -88,7 +88,9 @@ export const editorCss = ` height: 100%; text-align: right; color: #999; - z-index: 2; + border-right: 1px solid #f8f8f8; + background-color: #fafafa; + z-index: 5; } .codeflask__lines__line { @@ -109,4 +111,4 @@ export const editorCss = ` background: #eee; z-index: 1; } -` \ No newline at end of file +` From 783cf0143ce343d72d0a42302e69b8a414f6255f Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Sun, 27 Mar 2022 11:59:09 -0400 Subject: [PATCH 13/25] fix line number height issue --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/styles/editor.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 567f9040..497e0e47 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 6f8b3d6d..68a658ef 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index fdc6f3ec..40b09a5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.6", + "version": "2.0.7", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/styles/editor.js b/src/styles/editor.js index 02df9a55..0b44a120 100644 --- a/src/styles/editor.js +++ b/src/styles/editor.js @@ -85,7 +85,7 @@ export const editorCss = ` left: 0; top: 0; width: ${LINE_NUMBER_WIDTH}; - height: 100%; + min-height: 100%; text-align: right; color: #999; border-right: 1px solid #f8f8f8; From 5533bdb357b84164e0d988cb47c214fc34e9e15d Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 30 Mar 2022 13:47:48 -0400 Subject: [PATCH 14/25] increase default font size --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/styles/theme-default.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 497e0e47..716a9fb6 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 68a658ef..55d5b908 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="13px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="16px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; diff --git a/package.json b/package.json index 40b09a5d..f46ff7d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.7", + "version": "2.0.8", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/styles/theme-default.js b/src/styles/theme-default.js index 7b356167..72a2490b 100644 --- a/src/styles/theme-default.js +++ b/src/styles/theme-default.js @@ -1,6 +1,6 @@ export const BACKGROUND_COLOR = '#fff' export const LINE_HEIGHT = '20px' -export const FONT_SIZE = '13px' +export const FONT_SIZE = '16px' export const defaultCssTheme = ` .codeflask { From 2f465c917eb13141011c9ffbf5d491c10bc2b421 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Mon, 9 May 2022 23:04:51 -0400 Subject: [PATCH 15/25] make the self-closing characters configurable --- README.md | 4 ++- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- index.d.ts | 3 ++- package.json | 12 ++++----- rollup.config.js | 16 ++++-------- src/codeflask.js | 53 +++++++++++---------------------------- 7 files changed, 33 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 9752eba9..43dac2ec 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,15 @@ I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to... 1. Attach custom event listeners to the editor 1. Support the [Line Highlight](https://prismjs.com/plugins/line-highlight/) plugin in PrismJS 1. Fix this issue: kazzkiq/CodeFlask#69 +1. Make the self-closing characters configurable ```javascript import CodeFlask from "codeflask" import Prism from "prismjs" const flask = new CodeFlask(editor, Prism, { - language: "html", + language: "js", + selfClosingCharacters: ['(', '[', '{', "'", '"'], customEventListeners: { "keydown": e => { if (e.key == "Enter") { diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 716a9fb6..ce3c1064 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeFlask=t()}(this,function(){"use strict";var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return a[e]})}var l=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return l.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},l.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},l.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},l.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},l.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},l.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},l.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},l.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},l.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},l.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},l.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),c=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=c.length){var d=o-a.split("\n").pop().length,h=c.length,p=c.length;if(e.shiftKey)i.substr(d,c.length)===c?(h=-h,d>o?(r=r.substring(0,d)+r.substring(d+c.length),p=0):d===o?(h=0,p=0,r=r.substring(c.length)):(p=-p,a=a.substring(0,d)+a.substring(d+c.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+c.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+c+a.substring(d,o),r=r.replace(/\n/g,"\n"+c);t.value=a+r+l,t.selectionStart=o+h,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+c+l,t.selectionStart=o+c.length,t.selectionEnd=o+c.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},l.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},l.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},l.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),c=l>r?l-r:0,d=i+"\n"+" ".repeat(c)+a;t.value=d,t.selectionStart=n+c+1,t.selectionEnd=n+c+1,this.updateCode(t.value)}},l.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),c=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(c)}this.elTextarea.selectionEnd=t},l.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},l.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},l.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},l.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},l.prototype.populateDefault=function(){this.updateCode(this.code)},l.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},l.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},l.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},l.prototype.getCode=function(){return this.code},l.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},l.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},l.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},l}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";var e="#fff";var t,n,o,s='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',i="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(o=(o=t).split("-").filter((function(e){return!!e})).map((function(e){return e[0].toUpperCase()+e.substr(1)})).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+s+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+"40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+s+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: "+"20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+"40px);\n left: "+"40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+"20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+"20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+"40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+"40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+"40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function a(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var r={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return r[e]}))}var d={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'},h=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return h.prototype.startEditor=function(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},h.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},h.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},h.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},h.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},h.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},h.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},h.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},h.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},h.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",(function(t){e.code=t.target.value,e.elCode.innerHTML=l(t.target.value),e.highlight(),setTimeout((function(){e.runUpdate(),e.setLineNumber()}),1)})),this.elTextarea.addEventListener("keydown",(function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))})),this.elTextarea.addEventListener("scroll",(function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")}))},h.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),d=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=d.length){var h=o-a.split("\n").pop().length,c=d.length,p=d.length;if(e.shiftKey)i.substr(h,d.length)===d?(c=-c,h>o?(r=r.substring(0,h)+r.substring(h+d.length),p=0):h===o?(c=0,p=0,r=r.substring(d.length)):(p=-p,a=a.substring(0,h)+a.substring(h+d.length))):(c=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+d+a.substring(h,o),r=r.replace(/\n/g,"\n"+d);t.value=a+r+l,t.selectionStart=o+c,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+d+l,t.selectionStart=o+d.length,t.selectionEnd=o+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},h.prototype.handleSelfClosingCharacters=function(e){if(this.opts.selfClosingCharacters.length){var t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((function(e){return d[e]}));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}},h.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},h.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,h=i+"\n"+" ".repeat(d)+a;t.value=h,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},h.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},h.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},h.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},h.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},h.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},h.prototype.populateDefault=function(){this.updateCode(this.code)},h.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},h.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},h.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},h.prototype.getCode=function(){return this.code},h.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},h.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},h.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},h})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 55d5b908..4b6023c4 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var BACKGROUND_COLOR="#fff",LINE_HEIGHT="20px",FONT_SIZE="16px",defaultCssTheme="\n.codeflask {\n background: "+BACKGROUND_COLOR+";\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n";function cssSupports(e,t){return"undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&toCamelCase(e)in document.body.style}function toCamelCase(e){return(e=e.split("-").filter(function(e){return!!e}).map(function(e){return e[0].toUpperCase()+e.substr(1)}).join(""))[0].toLowerCase()+e.substr(1)}var FONT_FAMILY='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',COLOR=cssSupports("caret-color","#000")?BACKGROUND_COLOR:"#ccc",LINE_NUMBER_WIDTH="40px",editorCss="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+COLOR+";\n z-index: 1;\n resize: none;\n font-family: "+FONT_FAMILY+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n }\n\n .codeflask__code {\n display: block;\n font-family: "+FONT_FAMILY+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: "+FONT_SIZE+";\n line-height: "+LINE_HEIGHT+";\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+LINE_NUMBER_WIDTH+");\n left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+LINE_HEIGHT+";\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+LINE_HEIGHT+";\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+LINE_NUMBER_WIDTH+";\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+LINE_NUMBER_WIDTH+";\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function injectCss(e,t,n){var s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;var a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(e){return String(e).replace(/[&<>"'`=/]/g,function(e){return entityMap[e]})}var CodeFlask=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var s=document.querySelector(e);s&&(this.editorRoot=s)}this.Prism=t,this.opts=n,this.startEditor()};CodeFlask.prototype.startEditor=function(){if(!injectCss(editorCss,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},CodeFlask.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},CodeFlask.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},CodeFlask.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},CodeFlask.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},CodeFlask.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},CodeFlask.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},CodeFlask.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleSelfClosingCharacters&&(this.opts.handleSelfClosingCharacters=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&injectCss(defaultCssTheme,"theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},CodeFlask.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},CodeFlask.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",function(t){e.code=t.target.value,e.elCode.innerHTML=escapeHtml(t.target.value),e.highlight(),setTimeout(function(){e.runUpdate(),e.setLineNumber()},1)}),this.elTextarea.addEventListener("keydown",function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))}),this.elTextarea.addEventListener("scroll",function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")})},CodeFlask.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,o=t.selectionEnd,a=t.value,i=a.substr(0,s),r=a.substring(s,o),l=a.substring(o),d=" ".repeat(this.opts.tabSize);if(s!==o&&r.length>=d.length){var c=s-i.split("\n").pop().length,h=d.length,p=d.length;if(e.shiftKey)a.substr(c,d.length)===d?(h=-h,c>s?(r=r.substring(0,c)+r.substring(c+d.length),p=0):c===s?(h=0,p=0,r=r.substring(d.length)):(p=-p,i=i.substring(0,c)+i.substring(c+d.length))):(h=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else i=i.substr(0,c)+d+i.substring(c,s),r=r.replace(/\n/g,"\n"+d);t.value=i+r+l,t.selectionStart=s+h,t.selectionEnd=s+r.length+p,t.selectionDirection=n}else t.value=i+d+l,t.selectionStart=s+d.length,t.selectionEnd=s+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=o+this.opts.tabSize}},CodeFlask.prototype.handleSelfClosingCharacters=function(e){if(this.opts.handleSelfClosingCharacters){var t=e.key;if(["(","[","{","<","'",'"'].includes(t)||[")","]","}",">","'",'"'].includes(t))switch(t){case"(":case")":this.closeCharacter(t);break;case"[":case"]":this.closeCharacter(t);break;case"{":case"}":this.closeCharacter(t);break;case"<":case">":case"'":case'"':this.closeCharacter(t)}}},CodeFlask.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},CodeFlask.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,o=t.value,a=o.substr(0,n),i=o.substring(s),r=o.lastIndexOf("\n",n-1),l=r+o.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,c=a+"\n"+" ".repeat(d)+i;t.value=c,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},CodeFlask.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=""+this.code.substring(0,t)+a+this.code.substring(o);this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},CodeFlask.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s},CodeFlask.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=escapeHtml(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},CodeFlask.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},CodeFlask.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},CodeFlask.prototype.populateDefault=function(){this.updateCode(this.code)},CodeFlask.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},CodeFlask.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},CodeFlask.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},CodeFlask.prototype.getCode=function(){return this.code},CodeFlask.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},CodeFlask.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},CodeFlask.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export default CodeFlask; +var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter((function(e){return!!e})).map((function(e){return e[0].toUpperCase()+e.substr(1)})).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return a[e]}))}var l={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'},h=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};h.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},h.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},h.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},h.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},h.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},h.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},h.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},h.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},h.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},h.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",(function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout((function(){e.runUpdate(),e.setLineNumber()}),1)})),this.elTextarea.addEventListener("keydown",(function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))})),this.elTextarea.addEventListener("scroll",(function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")}))},h.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),h=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=h.length){var d=o-a.split("\n").pop().length,c=h.length,p=h.length;if(e.shiftKey)i.substr(d,h.length)===h?(c=-c,d>o?(r=r.substring(0,d)+r.substring(d+h.length),p=0):d===o?(c=0,p=0,r=r.substring(h.length)):(p=-p,a=a.substring(0,d)+a.substring(d+h.length))):(c=0,p=0),r=r.replace(new RegExp("\n"+h.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+h+a.substring(d,o),r=r.replace(/\n/g,"\n"+h);t.value=a+r+l,t.selectionStart=o+c,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+h+l,t.selectionStart=o+h.length,t.selectionEnd=o+h.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},h.prototype.handleSelfClosingCharacters=function(e){if(this.opts.selfClosingCharacters.length){var t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((function(e){return l[e]}));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}},h.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},h.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),h=l>r?l-r:0,d=i+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}},h.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),h=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(h)}this.elTextarea.selectionEnd=t},h.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},h.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},h.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},h.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},h.prototype.populateDefault=function(){this.updateCode(this.code)},h.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},h.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},h.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},h.prototype.getCode=function(){return this.code},h.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},h.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},h.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export{h as default}; diff --git a/index.d.ts b/index.d.ts index 265cdead..b91ea184 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,13 +20,14 @@ export interface CodeFlaskOptions { areaId?: string ariaLabelledby?: string readonly?: boolean + selfClosingCharacters: string[] customEventListeners?: EventListeners } export default class CodeFlask { constructor(selectorOrElement: Element | string, opts: CodeFlaskOptions) - updateCode(newCode: string): void + updateCode(newCode: string): void updateLanguage(newLanguage: string): void addLanguage(name: string, options: LanguageDefinition): void diff --git a/package.json b/package.json index f46ff7d6..b0767675 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.8", + "version": "2.0.9", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", @@ -27,6 +27,9 @@ "prismjs": "*" }, "devDependencies": { + "@rollup/plugin-buble": "^0.21.3", + "@rollup/plugin-commonjs": "^22.0.0", + "@rollup/plugin-node-resolve": "^13.3.0", "@wdio/cli": "^6.1.15", "@wdio/local-runner": "^6.1.14", "@wdio/mocha-framework": "^6.1.14", @@ -36,11 +39,8 @@ "chromedriver": "^83.0.0", "micro": "^9.3.0", "mocha": "^5.1.1", - "rollup": "^0.58.1", - "rollup-plugin-buble": "^0.19.2", - "rollup-plugin-commonjs": "^9.1.0", - "rollup-plugin-node-resolve": "^3.0.3", - "rollup-plugin-uglify": "^3.0.0", + "rollup": "^2.72.1", + "rollup-plugin-terser": "^7.0.2", "serve": "^7.0.0", "wdio-chromedriver-service": "^6.0.3" }, diff --git a/rollup.config.js b/rollup.config.js index d96277e4..9cf8cc3e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,7 +1,7 @@ -import resolve from 'rollup-plugin-node-resolve'; -import commonjs from 'rollup-plugin-commonjs'; -import buble from 'rollup-plugin-buble'; -import uglify from 'rollup-plugin-uglify'; +import resolve from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import buble from '@rollup/plugin-buble'; +import { terser } from 'rollup-plugin-terser'; const production = !process.env.ROLLUP_WATCH; @@ -22,17 +22,11 @@ export default { }, ], plugins: [ - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration — - // consult the documentation for details: - // https://github.com/rollup/rollup-plugin-commonjs resolve(), commonjs(), - // If we're building for production (npm run build // instead of npm run dev), transpile and minify production && buble({ exclude: 'node_modules/**' }), - production && uglify() + production && terser() ] }; diff --git a/src/codeflask.js b/src/codeflask.js index eb2e326f..20e0d35b 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -3,6 +3,15 @@ import { injectCss } from './styles/injector' import { defaultCssTheme } from './styles/theme-default' import { escapeHtml } from './utils/html-escape' +const selfClosingCharMap = { + '(': ')', + '[': ']', + '{': '}', + '<': '>', + "'": "'", + '"': '"' +} + export default class CodeFlask { constructor (selectorOrElement, Prism, opts) { if (!selectorOrElement) { @@ -101,16 +110,13 @@ export default class CodeFlask { this.opts.ariaLabelledby = this.opts.ariaLabelledby || null this.opts.readonly = this.opts.readonly || null this.opts.customEventListeners = this.opts.customEventListeners || {} + this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"'] // if handleTabs is not either true or false, make it true by default if (typeof this.opts.handleTabs !== 'boolean') { this.opts.handleTabs = true } // if handleTabs is not either true or false, make it true by default - if (typeof this.opts.handleSelfClosingCharacters !== 'boolean') { - this.opts.handleSelfClosingCharacters = true - } - // if handleTabs is not either true or false, make it true by default if (typeof this.opts.handleNewLineIndentation !== 'boolean') { this.opts.handleNewLineIndentation = true } @@ -270,44 +276,15 @@ export default class CodeFlask { } handleSelfClosingCharacters (e) { - if (!this.opts.handleSelfClosingCharacters) return - const openChars = ['(', '[', '{', '<', '\'', '"'] - const closeChars = [')', ']', '}', '>', '\'', '"'] - const key = e.key + if (!this.opts.selfClosingCharacters.length) return + const openChars = this.opts.selfClosingCharacters + const closeChars = this.opts.selfClosingCharacters.map(c => selfClosingCharMap[c]) - if (!openChars.includes(key) && !closeChars.includes(key)) { + if (!openChars.includes(e.key) && !closeChars.includes(e.key)) { return } - switch (key) { - case '(': - case ')': - this.closeCharacter(key) - break - - case '[': - case ']': - this.closeCharacter(key) - break - - case '{': - case '}': - this.closeCharacter(key) - break - - case '<': - case '>': - this.closeCharacter(key) - break - - case '\'': - this.closeCharacter(key) - break - - case '"': - this.closeCharacter(key) - break - } + this.closeCharacter(e.key) } setLineNumber () { From 274659c410a2c266d7ef98b81a4cd166be591cdc Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Sun, 17 Jul 2022 09:35:52 -0400 Subject: [PATCH 16/25] =?UTF-8?q?remove=20Bubl=C3=A9=20transpilation,=20ad?= =?UTF-8?q?d=20method=20to=20remove=20event=20listeners,=20and=20fix=20bug?= =?UTF-8?q?s=20with=20tab=20key=20indentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 3 +-- rollup.config.js | 4 --- src/codeflask.js | 51 +++++++++++++++++++++++++++++---------- 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index ce3c1064..cc4a0af1 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";var e="#fff";var t,n,o,s='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',i="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(o=(o=t).split("-").filter((function(e){return!!e})).map((function(e){return e[0].toUpperCase()+e.substr(1)})).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+s+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - "+"40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+s+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: "+"20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - "+"40px);\n left: "+"40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: "+"20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: "+"20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: "+"40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: "+"40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: "+"40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function a(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var r={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return r[e]}))}var d={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'},h=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};return h.prototype.startEditor=function(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},h.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},h.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},h.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},h.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},h.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},h.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},h.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},h.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},h.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",(function(t){e.code=t.target.value,e.elCode.innerHTML=l(t.target.value),e.highlight(),setTimeout((function(){e.runUpdate(),e.setLineNumber()}),1)})),this.elTextarea.addEventListener("keydown",(function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))})),this.elTextarea.addEventListener("scroll",(function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")}))},h.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),d=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=d.length){var h=o-a.split("\n").pop().length,c=d.length,p=d.length;if(e.shiftKey)i.substr(h,d.length)===d?(c=-c,h>o?(r=r.substring(0,h)+r.substring(h+d.length),p=0):h===o?(c=0,p=0,r=r.substring(d.length)):(p=-p,a=a.substring(0,h)+a.substring(h+d.length))):(c=0,p=0),r=r.replace(new RegExp("\n"+d.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+d+a.substring(h,o),r=r.replace(/\n/g,"\n"+d);t.value=a+r+l,t.selectionStart=o+c,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+d+l,t.selectionStart=o+d.length,t.selectionEnd=o+d.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},h.prototype.handleSelfClosingCharacters=function(e){if(this.opts.selfClosingCharacters.length){var t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((function(e){return d[e]}));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}},h.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},h.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),d=l>r?l-r:0,h=i+"\n"+" ".repeat(d)+a;t.value=h,t.selectionStart=n+d+1,t.selectionEnd=n+d+1,this.updateCode(t.value)}},h.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),d=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(d)}this.elTextarea.selectionEnd=t},h.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},h.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},h.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},h.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},h.prototype.populateDefault=function(){this.updateCode(this.code)},h.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},h.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},h.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},h.prototype.getCode=function(){return this.code},h.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},h.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},h.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")},h})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,i;const o=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(i=(i=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+i.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",i=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const o=document.createElement("style");return o.innerHTML=e,o.id=s,i.appendChild(o),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(o,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}handleTabs(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,i=t.selectionEnd,o=t.value,a=o.substr(0,s),l=o.substring(s,i),r=o.substring(i);const u=" ".repeat(this.opts.tabSize);if(s!==i&&l.length>=u.length){var h=s-a.split("\n").pop().length,d=u.length,c=u.length;if(e.shiftKey)o.substr(h,u.length)===u?(d=-d,h>s?(l=l.substring(0,h)+l.substring(h+u.length),c=0):h===s?(d=0,c=0,l=l.substring(u.length)):(c=-c,a=a.substring(0,h)+a.substring(h+u.length))):(d=0,c=0),l=l.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+u+a.substring(h,s),l=l.replace(/\n/g,"\n"+u);t.value=a+l+r,t.selectionStart=s+d,t.selectionEnd=s+l.length+c,t.selectionDirection=n}else{const n=new RegExp(`(\\n?)((?:${u})*)([^\\n]*)$`);if(e.shiftKey){const e=a.replace(n,((e,t,n,s)=>t+n.slice(0,-1*u.length)+s));e!==a&&(t.value=e+r,t.setSelectionRange(s-u.length,s-u.length))}else{const e=a.replace(n,((e,t,n,s)=>t+n+u+s));t.value=e+r,t.setSelectionRange(s+u.length,s+u.length)}}var p=t.value;this.updateCode(p)}}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,i=t.value,o=i.substr(0,n),a=i.substring(s),l=i.lastIndexOf("\n",n-1),r=l+i.slice(l+1).search(/[^ ]|$/),h=r>l?r-l:0,d=o+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,i=s?n+1:n,o=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${o}${this.code.substring(i)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const i=this.code.substring(t,n),o=`${this.code.substring(0,t)}${i}${s}${this.code.substring(n)}`;this.updateCode(o)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 4b6023c4..5a9f5f19 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -var e,t,n,o='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',s="\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: "+(e="caret-color",t="#000",("undefined"!=typeof CSS?CSS.supports(e,t):"undefined"!=typeof document&&(n=(n=e).split("-").filter((function(e){return!!e})).map((function(e){return e[0].toUpperCase()+e.substr(1)})).join(""))[0].toLowerCase()+n.substr(1)in document.body.style)?"#fff":"#ccc")+";\n z-index: 1;\n resize: none;\n font-family: "+o+";\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: "+o+";\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n";function i(e,t,n){var o=t||"codeflask-style",s=n||document.head;if(!e)return!1;if(document.getElementById(o))return!0;var i=document.createElement("style");return i.innerHTML=e,i.id=o,s.appendChild(i),!0}var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return a[e]}))}var l={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'},h=function(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{var o=document.querySelector(e);o&&(this.editorRoot=o)}this.Prism=t,this.opts=n,this.startEditor()};h.prototype.startEditor=function(){if(!i(s,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)},h.prototype.createWrapper=function(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")},h.prototype.createTextarea=function(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")},h.prototype.createPre=function(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")},h.prototype.createCode=function(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code","language-"+(this.opts.language||"html"))},h.prototype.createLineNumbers=function(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()},h.prototype.createElement=function(e,t){var n=document.createElement(e);return t.appendChild(n),n},h.prototype.runOptions=function(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||null,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()},h.prototype.updateLineNumbersCount=function(){for(var e="",t=1;t<=this.lineNumber;t++)e=e+''+t+"";this.elLineNumbers.innerHTML=e},h.prototype.listenTextarea=function(){var e=this,t=this.opts.customEventListeners;for(var n in t)t.hasOwnProperty(n)&&this.elTextarea.addEventListener(n,t[n]);this.elTextarea.addEventListener("input",(function(t){e.code=t.target.value,e.elCode.innerHTML=r(t.target.value),e.highlight(),setTimeout((function(){e.runUpdate(),e.setLineNumber()}),1)})),this.elTextarea.addEventListener("keydown",(function(t){e.opts.readonly||(e.handleTabs(t),e.handleSelfClosingCharacters(t),e.handleNewLineIndentation(t))})),this.elTextarea.addEventListener("scroll",(function(t){e.elPre.style.transform="translate3d(-"+t.target.scrollLeft+"px, -"+t.target.scrollTop+"px, 0)",e.elLineNumbers&&(e.elLineNumbers.style.transform="translate3d(0, -"+t.target.scrollTop+"px, 0)",e.elPre.style.width="calc(100% - 40px + "+t.target.scrollLeft+"px)")}))},h.prototype.handleTabs=function(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,o=t.selectionStart,s=t.selectionEnd,i=t.value,a=i.substr(0,o),r=i.substring(o,s),l=i.substring(s),h=" ".repeat(this.opts.tabSize);if(o!==s&&r.length>=h.length){var d=o-a.split("\n").pop().length,c=h.length,p=h.length;if(e.shiftKey)i.substr(d,h.length)===h?(c=-c,d>o?(r=r.substring(0,d)+r.substring(d+h.length),p=0):d===o?(c=0,p=0,r=r.substring(h.length)):(p=-p,a=a.substring(0,d)+a.substring(d+h.length))):(c=0,p=0),r=r.replace(new RegExp("\n"+h.split("").join("\\"),"g"),"\n");else a=a.substr(0,d)+h+a.substring(d,o),r=r.replace(/\n/g,"\n"+h);t.value=a+r+l,t.selectionStart=o+c,t.selectionEnd=o+r.length+p,t.selectionDirection=n}else t.value=a+h+l,t.selectionStart=o+h.length,t.selectionEnd=o+h.length;var u=t.value;this.updateCode(u),this.elTextarea.selectionEnd=s+this.opts.tabSize}},h.prototype.handleSelfClosingCharacters=function(e){if(this.opts.selfClosingCharacters.length){var t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((function(e){return l[e]}));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}},h.prototype.setLineNumber=function(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()},h.prototype.handleNewLineIndentation=function(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,o=t.selectionEnd,s=t.value,i=s.substr(0,n),a=s.substring(o),r=s.lastIndexOf("\n",n-1),l=r+s.slice(r+1).search(/[^ ]|$/),h=l>r?l-r:0,d=i+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}},h.prototype.closeCharacter=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){var o=this.code.substr(n,1)===e,s=o?n+1:n,i=!o&&["'",'"'].includes(e)?e:"",a=""+this.code.substring(0,t)+i+this.code.substring(s);this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{var r=e;switch(e){case"(":r=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":r=String.fromCharCode(e.charCodeAt()+2)}var l=this.code.substring(t,n),h=""+this.code.substring(0,t)+l+r+this.code.substring(n);this.updateCode(h)}this.elTextarea.selectionEnd=t},h.prototype.skipCloseChar=function(e){var t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,o=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!o},h.prototype.updateCode=function(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)},h.prototype.updateLanguage=function(e){var t=this.opts.language;this.elCode.classList.remove("language-"+t),this.elCode.classList.add("language-"+e),this.opts.language=e,this.highlight()},h.prototype.addLanguage=function(e,t){this.Prism.languages[e]=t},h.prototype.populateDefault=function(){this.updateCode(this.code)},h.prototype.highlight=function(){this.Prism.highlightElement(this.elCode,!1)},h.prototype.highlightLines=function(e){this.elPre.setAttribute("data-line",e),this.highlight()},h.prototype.onUpdate=function(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e},h.prototype.getCode=function(){return this.code},h.prototype.runUpdate=function(){this.updateCallBack&&this.updateCallBack(this.code)},h.prototype.enableReadonlyMode=function(){this.elTextarea.setAttribute("readonly",!0)},h.prototype.disableReadonlyMode=function(){this.elTextarea.removeAttribute("readonly")};export{h as default}; +const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function o(e,t,n){const s=t||"codeflask-style",i=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const o=document.createElement("style");return o.innerHTML=e,o.id=s,i.appendChild(o),!0}const a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return a[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!o(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&o("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}handleTabs(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,i=t.selectionEnd,o=t.value,a=o.substr(0,s),l=o.substring(s,i),r=o.substring(i);const u=" ".repeat(this.opts.tabSize);if(s!==i&&l.length>=u.length){var h=s-a.split("\n").pop().length,d=u.length,c=u.length;if(e.shiftKey)o.substr(h,u.length)===u?(d=-d,h>s?(l=l.substring(0,h)+l.substring(h+u.length),c=0):h===s?(d=0,c=0,l=l.substring(u.length)):(c=-c,a=a.substring(0,h)+a.substring(h+u.length))):(d=0,c=0),l=l.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+u+a.substring(h,s),l=l.replace(/\n/g,"\n"+u);t.value=a+l+r,t.selectionStart=s+d,t.selectionEnd=s+l.length+c,t.selectionDirection=n}else{const n=new RegExp(`(\\n?)((?:${u})*)([^\\n]*)$`);if(e.shiftKey){const e=a.replace(n,((e,t,n,s)=>t+n.slice(0,-1*u.length)+s));e!==a&&(t.value=e+r,t.setSelectionRange(s-u.length,s-u.length))}else{const e=a.replace(n,((e,t,n,s)=>t+n+u+s));t.value=e+r,t.setSelectionRange(s+u.length,s+u.length)}}var p=t.value;this.updateCode(p)}}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,i=t.value,o=i.substr(0,n),a=i.substring(s),l=i.lastIndexOf("\n",n-1),r=l+i.slice(l+1).search(/[^ ]|$/),h=r>l?r-l:0,d=o+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,i=s?n+1:n,o=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${o}${this.code.substring(i)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const i=this.code.substring(t,n),o=`${this.code.substring(0,t)}${i}${s}${this.code.substring(n)}`;this.updateCode(o)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; diff --git a/package.json b/package.json index b0767675..8b9aa36e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.0.9", + "version": "2.1.0", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", @@ -27,7 +27,6 @@ "prismjs": "*" }, "devDependencies": { - "@rollup/plugin-buble": "^0.21.3", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-node-resolve": "^13.3.0", "@wdio/cli": "^6.1.15", diff --git a/rollup.config.js b/rollup.config.js index 9cf8cc3e..be0601c0 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,6 +1,5 @@ import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; -import buble from '@rollup/plugin-buble'; import { terser } from 'rollup-plugin-terser'; const production = !process.env.ROLLUP_WATCH; @@ -24,9 +23,6 @@ export default { plugins: [ resolve(), commonjs(), - // If we're building for production (npm run build - // instead of npm run dev), transpile and minify - production && buble({ exclude: 'node_modules/**' }), production && terser() ] }; diff --git a/src/codeflask.js b/src/codeflask.js index 20e0d35b..53ebd6ee 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -42,6 +42,7 @@ export default class CodeFlask { this.Prism = Prism this.opts = opts + this.events = {} this.startEditor() } @@ -108,7 +109,7 @@ export default class CodeFlask { this.opts.defaultTheme = this.opts.defaultTheme !== false this.opts.areaId = this.opts.areaId || null this.opts.ariaLabelledby = this.opts.ariaLabelledby || null - this.opts.readonly = this.opts.readonly || null + this.opts.readonly = this.opts.readonly || false this.opts.customEventListeners = this.opts.customEventListeners || {} this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"'] @@ -167,13 +168,14 @@ export default class CodeFlask { listenTextarea () { const customEventListeners = this.opts.customEventListeners - for (const eventName in customEventListeners) { - if (customEventListeners.hasOwnProperty(eventName)) { - this.elTextarea.addEventListener(eventName, customEventListeners[eventName]) - } + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.addEventListener(eventName, func) } - this.elTextarea.addEventListener('input', (e) => { + this.elTextarea.addEventListener('input', this.events.input = (e) => { + if (this.opts.readonly) { + return; + } this.code = e.target.value this.elCode.innerHTML = escapeHtml(e.target.value) this.highlight() @@ -183,7 +185,7 @@ export default class CodeFlask { }, 1) }) - this.elTextarea.addEventListener('keydown', (e) => { + this.elTextarea.addEventListener('keydown', this.events.keydown = (e) => { if (this.opts.readonly) { return; } @@ -192,7 +194,7 @@ export default class CodeFlask { this.handleNewLineIndentation(e) }) - this.elTextarea.addEventListener('scroll', (e) => { + this.elTextarea.addEventListener('scroll', this.events.scroll = (e) => { this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)` if (this.elLineNumbers) { this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)` @@ -201,6 +203,15 @@ export default class CodeFlask { }) } + removeEventListeners () { + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.removeEventListener(eventName, func) + } + for (const [eventName, func] of Object.entries(this.events)) { + this.elTextarea.removeEventListener(eventName, func) + } + } + handleTabs (e) { if (this.opts.handleTabs) { if (e.keyCode !== 9) { @@ -264,14 +275,28 @@ export default class CodeFlask { input.selectionEnd = selStartPos + selectionVal.length + endIndentLen input.selectionDirection = selectionDir } else { - input.value = beforeSelection + indent + afterSelection - input.selectionStart = selStartPos + indent.length - input.selectionEnd = selStartPos + indent.length + const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`) + if (e.shiftKey) { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content + ) + if (newBeforeSelection !== beforeSelection) { + input.value = newBeforeSelection + afterSelection + input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length) + } + } else { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content + ) + input.value = newBeforeSelection + afterSelection + input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length) + } } var newCode = input.value this.updateCode(newCode) - this.elTextarea.selectionEnd = selEndPos + this.opts.tabSize } } @@ -389,7 +414,7 @@ export default class CodeFlask { this.Prism.highlightElement(this.elCode, false) } - highlightLines(lineSpec) { + highlightLines (lineSpec) { /* This requires the "line-highlight" plugin in PrismJS Examples 5: The 5th line From 4210981180dbb6dcc9499525c0ccf6adf29e836a Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Sun, 17 Jul 2022 09:36:43 -0400 Subject: [PATCH 17/25] update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 43dac2ec..4e1eee87 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,10 @@ npm i '@acarl005/codeflask' I modified [CodeFlask](https://github.com/kazzkiq/CodeFlask) to be able to... 1. Make PrismJS a peer dependency -1. Attach custom event listeners to the editor +1. Attach (and remove) custom event listeners to the editor 1. Support the [Line Highlight](https://prismjs.com/plugins/line-highlight/) plugin in PrismJS 1. Fix this issue: kazzkiq/CodeFlask#69 +1. Fix bugs with tab hotkey for indentation 1. Make the self-closing characters configurable ```javascript From b10a3c7acd712a1087eeb6a432ac4192c76028b2 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Mon, 25 Jul 2022 00:01:34 -0400 Subject: [PATCH 18/25] make backspace unindent --- build/codeflask.min.js | 708 +++++++++++++++++++++++++++++++++++++- build/codeflask.module.js | 700 ++++++++++++++++++++++++++++++++++++- src/codeflask.js | 176 +++++----- 3 files changed, 1502 insertions(+), 82 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index cc4a0af1..ac150bdb 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1,707 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,i;const o=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(i=(i=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+i.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",i=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const o=document.createElement("style");return o.innerHTML=e,o.id=s,i.appendChild(o),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(o,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}handleTabs(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,i=t.selectionEnd,o=t.value,a=o.substr(0,s),l=o.substring(s,i),r=o.substring(i);const u=" ".repeat(this.opts.tabSize);if(s!==i&&l.length>=u.length){var h=s-a.split("\n").pop().length,d=u.length,c=u.length;if(e.shiftKey)o.substr(h,u.length)===u?(d=-d,h>s?(l=l.substring(0,h)+l.substring(h+u.length),c=0):h===s?(d=0,c=0,l=l.substring(u.length)):(c=-c,a=a.substring(0,h)+a.substring(h+u.length))):(d=0,c=0),l=l.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+u+a.substring(h,s),l=l.replace(/\n/g,"\n"+u);t.value=a+l+r,t.selectionStart=s+d,t.selectionEnd=s+l.length+c,t.selectionDirection=n}else{const n=new RegExp(`(\\n?)((?:${u})*)([^\\n]*)$`);if(e.shiftKey){const e=a.replace(n,((e,t,n,s)=>t+n.slice(0,-1*u.length)+s));e!==a&&(t.value=e+r,t.setSelectionRange(s-u.length,s-u.length))}else{const e=a.replace(n,((e,t,n,s)=>t+n+u+s));t.value=e+r,t.setSelectionRange(s+u.length,s+u.length)}}var p=t.value;this.updateCode(p)}}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,i=t.value,o=i.substr(0,n),a=i.substring(s),l=i.lastIndexOf("\n",n-1),r=l+i.slice(l+1).search(/[^ ]|$/),h=r>l?r-l:0,d=o+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,i=s?n+1:n,o=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${o}${this.code.substring(i)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const i=this.code.substring(t,n),o=`${this.code.substring(0,t)}${i}${s}${this.code.substring(n)}`;this.updateCode(o)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.CodeFlask = factory()); +})(this, (function () { 'use strict'; + + const BACKGROUND_COLOR = '#fff'; + const LINE_HEIGHT = '20px'; + const FONT_SIZE = '16px'; + + const defaultCssTheme = ` +.codeflask { + background: ${BACKGROUND_COLOR}; + color: #4f559c; +} + +.codeflask .token.punctuation { + color: #4a4a4a; +} + +.codeflask .token.keyword { + color: #8500ff; +} + +.codeflask .token.operator { + color: #ff5598; +} + +.codeflask .token.string { + color: #41ad8f; +} + +.codeflask .token.comment { + color: #9badb7; +} + +.codeflask .token.function { + color: #8500ff; +} + +.codeflask .token.boolean { + color: #8500ff; +} + +.codeflask .token.number { + color: #8500ff; +} + +.codeflask .token.selector { + color: #8500ff; +} + +.codeflask .token.property { + color: #8500ff; +} + +.codeflask .token.tag { + color: #8500ff; +} + +.codeflask .token.attr-value { + color: #8500ff; +} +`; + + function cssSupports (property, value) { + if (typeof CSS !== 'undefined') { + return CSS.supports(property, value) + } + + if (typeof document === 'undefined') { + return false; + } + + return toCamelCase(property) in document.body.style + } + + function toCamelCase (cssProperty) { + cssProperty = cssProperty + .split('-') + .filter(word => !!word) + .map(word => word[0].toUpperCase() + word.substr(1)) + .join(''); + + return cssProperty[0].toLowerCase() + cssProperty.substr(1) + } + + const FONT_FAMILY = `"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace`; + const COLOR = (cssSupports('caret-color', '#000')) ? BACKGROUND_COLOR : '#ccc'; + const LINE_NUMBER_WIDTH = '40px'; + + const editorCss = ` + .codeflask { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + } + + .codeflask, .codeflask * { + box-sizing: border-box; + } + + .codeflask__pre { + pointer-events: none; + z-index: 3; + overflow: hidden; + } + + .codeflask__textarea { + background: none; + border: none; + color: ${COLOR}; + z-index: 1; + resize: none; + font-family: ${FONT_FAMILY}; + -webkit-appearance: pre; + caret-color: #111; + z-index: 2; + width: 100%; + height: 100%; + } + + .codeflask--has-line-numbers .codeflask__textarea { + width: calc(100% - ${LINE_NUMBER_WIDTH}); + } + + .codeflask__code { + display: block; + font-family: ${FONT_FAMILY}; + overflow: hidden; + } + + .codeflask__flatten { + padding: 10px; + font-size: ${FONT_SIZE}; + line-height: ${LINE_HEIGHT}; + white-space: pre; + position: absolute; + top: 0; + left: 0; + overflow: auto; + margin: 0 !important; + outline: none; + text-align: left; + } + + .codeflask--has-line-numbers .codeflask__flatten { + width: calc(100% - ${LINE_NUMBER_WIDTH}); + left: ${LINE_NUMBER_WIDTH}; + } + + .codeflask__line-highlight { + position: absolute; + top: 10px; + left: 0; + width: 100%; + height: ${LINE_HEIGHT}; + background: rgba(0,0,0,0.1); + z-index: 1; + } + + .codeflask__lines { + padding: 10px 4px; + font-size: 12px; + line-height: ${LINE_HEIGHT}; + font-family: 'Cousine', monospace; + position: absolute; + left: 0; + top: 0; + width: ${LINE_NUMBER_WIDTH}; + min-height: 100%; + text-align: right; + color: #999; + border-right: 1px solid #f8f8f8; + background-color: #fafafa; + z-index: 5; + } + + .codeflask__lines__line { + display: block; + } + + .codeflask.codeflask--has-line-numbers { + padding-left: ${LINE_NUMBER_WIDTH}; + } + + .codeflask.codeflask--has-line-numbers:before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: ${LINE_NUMBER_WIDTH}; + height: 100%; + background: #eee; + z-index: 1; + } +`; + + function injectCss (css, styleName, parent) { + const CSS_ID = styleName || 'codeflask-style'; + const PARENT = parent || document.head; + + if (!css) { + return false + } + + if (document.getElementById(CSS_ID)) { + return true + } + + const style = document.createElement('style'); + + style.innerHTML = css; + style.id = CSS_ID; + PARENT.appendChild(style); + + return true + } + + const entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' + }; + + function escapeHtml (string) { + return String(string).replace(/[&<>"'`=/]/g, function (s) { + return entityMap[s] + }) + } + + const selfClosingCharMap = { + '(': ')', + '[': ']', + '{': '}', + '<': '>', + "'": "'", + '"': '"' + }; + + class CodeFlask { + constructor (selectorOrElement, Prism, opts) { + if (!selectorOrElement) { + throw Error('CodeFlask expects 1st parameter to be an Element or a String selector') + } + + if (!Prism) { + throw Error('CodeFlask expects 2nd parameter to be the Prism peer dependency') + } + + if (!opts) { + throw Error('CodeFlask expects 3rd parameter to be an object containing options') + } + + if (selectorOrElement.nodeType) { + // If it is an element, assign it directly + this.editorRoot = selectorOrElement; + } else { + // If it is a selector, tries to find element + const editorRoot = document.querySelector(selectorOrElement); + + // If an element is found using this selector, + // assign this element as the root element + if (editorRoot) { + this.editorRoot = editorRoot; + } + } + + this.Prism = Prism; + this.opts = opts; + this.events = {}; + this.startEditor(); + } + + startEditor () { + const isCSSInjected = injectCss(editorCss, null, this.opts.styleParent); + + if (!isCSSInjected) { + throw Error('Failed to inject CodeFlask CSS.') + } + + // The order matters (pre > code). Don't change it + // or things are going to break. + this.createWrapper(); + this.createTextarea(); + this.createPre(); + this.createCode(); + + this.runOptions(); + this.listenTextarea(); + this.populateDefault(); + this.updateCode(this.code); + } + + createWrapper () { + this.code = this.editorRoot.innerHTML; + this.editorRoot.innerHTML = ''; + this.elWrapper = this.createElement('div', this.editorRoot); + this.elWrapper.classList.add('codeflask'); + } + + createTextarea () { + this.elTextarea = this.createElement('textarea', this.elWrapper); + this.elTextarea.classList.add('codeflask__textarea', 'codeflask__flatten'); + } + + createPre () { + this.elPre = this.createElement('pre', this.elWrapper); + this.elPre.classList.add('codeflask__pre', 'codeflask__flatten'); + } + + createCode () { + this.elCode = this.createElement('code', this.elPre); + this.elCode.classList.add('codeflask__code', `language-${this.opts.language || 'html'}`); + } + + createLineNumbers () { + this.elLineNumbers = this.createElement('div', this.elWrapper); + this.elLineNumbers.classList.add('codeflask__lines'); + this.setLineNumber(); + } + + createElement (elementTag, whereToAppend) { + const element = document.createElement(elementTag); + whereToAppend.appendChild(element); + + return element + } + + runOptions () { + this.opts.rtl = this.opts.rtl || false; + this.opts.tabSize = this.opts.tabSize || 2; + this.opts.enableAutocorrect = this.opts.enableAutocorrect || false; + this.opts.lineNumbers = this.opts.lineNumbers || false; + this.opts.defaultTheme = this.opts.defaultTheme !== false; + this.opts.areaId = this.opts.areaId || null; + this.opts.ariaLabelledby = this.opts.ariaLabelledby || null; + this.opts.readonly = this.opts.readonly || false; + this.opts.customEventListeners = this.opts.customEventListeners || {}; + this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"']; + + // if handleTabs is not either true or false, make it true by default + if (typeof this.opts.handleTabs !== 'boolean') { + this.opts.handleTabs = true; + } + // if handleTabs is not either true or false, make it true by default + if (typeof this.opts.handleNewLineIndentation !== 'boolean') { + this.opts.handleNewLineIndentation = true; + } + + if (this.opts.rtl === true) { + this.elTextarea.setAttribute('dir', 'rtl'); + this.elPre.setAttribute('dir', 'rtl'); + } + + if (this.opts.enableAutocorrect === false) { + this.elTextarea.setAttribute('spellcheck', 'false'); + this.elTextarea.setAttribute('autocapitalize', 'off'); + this.elTextarea.setAttribute('autocomplete', 'off'); + this.elTextarea.setAttribute('autocorrect', 'off'); + } + + if (this.opts.lineNumbers) { + this.elWrapper.classList.add('codeflask--has-line-numbers'); + this.createLineNumbers(); + } + + if (this.opts.defaultTheme) { + injectCss(defaultCssTheme, 'theme-default', this.opts.styleParent); + } + + if (this.opts.areaId) { + this.elTextarea.setAttribute('id', this.opts.areaId); + } + + if (this.opts.ariaLabelledby) { + this.elTextarea.setAttribute('aria-labelledby', this.opts.ariaLabelledby); + } + + if (this.opts.readonly) { + this.enableReadonlyMode(); + } + } + + updateLineNumbersCount () { + let numberList = ''; + + for (let i = 1; i <= this.lineNumber; i++) { + numberList = numberList + `${i}`; + } + + this.elLineNumbers.innerHTML = numberList; + } + + listenTextarea () { + const customEventListeners = this.opts.customEventListeners; + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.addEventListener(eventName, func); + } + + this.elTextarea.addEventListener('input', this.events.input = (e) => { + if (this.opts.readonly) { + return; + } + this.code = e.target.value; + this.elCode.innerHTML = escapeHtml(e.target.value); + this.highlight(); + setTimeout(() => { + this.runUpdate(); + this.setLineNumber(); + }, 1); + }); + + this.elTextarea.addEventListener('keydown', this.events.keydown = (e) => { + if (this.opts.readonly) { + return; + } + this.handleTabs(e); + this.handleBackspace(e); + this.handleSelfClosingCharacters(e); + this.handleNewLineIndentation(e); + }); + + this.elTextarea.addEventListener('scroll', this.events.scroll = (e) => { + this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`; + if (this.elLineNumbers) { + this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)`; + this.elPre.style.width = `calc(100% - 40px + ${e.target.scrollLeft}px)`; + } + }); + } + + removeEventListeners () { + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.removeEventListener(eventName, func); + } + for (const [eventName, func] of Object.entries(this.events)) { + this.elTextarea.removeEventListener(eventName, func); + } + } + + getSelectInfo () { + var input = this.elTextarea; + var selStartPos = input.selectionStart; + var selEndPos = input.selectionEnd; + var beforeSelection = input.value.substr(0, selStartPos); + var selectionVal = input.value.substring(selStartPos, selEndPos); + var afterSelection = input.value.substring(selEndPos); + return { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } + } + + handleTabs (e) { + if (!this.opts.handleTabs || e.key !== "Tab") { + return + } + e.preventDefault(); + + var input = this.elTextarea; + var inputVal = input.value; + var { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); + const indent = ' '.repeat(this.opts.tabSize); + + if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { + var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length; + var startIndentLen = indent.length; + var endIndentLen = indent.length; + + // Unindent + if (e.shiftKey) { + var currentLineStartStr = inputVal.substr(currentLineStart, indent.length); + // Line start whit indent + if (currentLineStartStr === indent) { + startIndentLen = -startIndentLen; + + if (currentLineStart > selStartPos) { + // Indent is in selection + selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length); + endIndentLen = 0; + } else if (currentLineStart === selStartPos) { + // Indent is in start of selection + startIndentLen = 0; + endIndentLen = 0; + selectionVal = selectionVal.substring(indent.length); + } else { + // Indent is before selection + endIndentLen = -endIndentLen; + beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length); + } + } else { + startIndentLen = 0; + endIndentLen = 0; + } + + selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n'); + } else { + // Indent + beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos); + selectionVal = selectionVal.replace(/\n/g, '\n' + indent); + } + + // Set new indented value + input.value = beforeSelection + selectionVal + afterSelection; + input.setSelectionRange(selStartPos + startIndentLen, selStartPos + selectionVal.length + endIndentLen); + } else { + const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`); + if (e.shiftKey) { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content + ); + if (newBeforeSelection !== beforeSelection) { + input.value = newBeforeSelection + afterSelection; + input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length); + } + } else { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content + ); + input.value = newBeforeSelection + afterSelection; + input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length); + } + } + + this.updateCode(input.value); + } + + handleBackspace (e) { + if (e.key !== "Backspace") { + return + } + + var { selStartPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); + if (selectionVal !== '') { + return + } + + if (!beforeSelection.match(/\n( ){1,}$/)) { + return + } + + e.preventDefault(); + const newBeforeSelection = beforeSelection.replace(/ $/, ''); + const input = this.elTextarea; + input.value = newBeforeSelection + afterSelection; + this.updateCode(input.value); + input.setSelectionRange(selStartPos - 2, selStartPos - 2); + } + + handleSelfClosingCharacters (e) { + if (!this.opts.selfClosingCharacters.length) return + const openChars = this.opts.selfClosingCharacters; + const closeChars = this.opts.selfClosingCharacters.map(c => selfClosingCharMap[c]); + + if (!openChars.includes(e.key) && !closeChars.includes(e.key)) { + return + } + + this.closeCharacter(e.key); + } + + setLineNumber () { + this.lineNumber = this.code.split('\n').length; + + if (this.opts.lineNumbers) { + this.updateLineNumbersCount(); + } + } + + handleNewLineIndentation (e) { + if (!this.opts.handleNewLineIndentation || e.keyCode !== 13) { + return + } + + e.preventDefault(); + var input = this.elTextarea; + var inputVal = input.value; + var { selStartPos, beforeSelection, afterSelection } = this.getSelectInfo(); + + var lineStart = inputVal.lastIndexOf('\n', selStartPos - 1); + var spaceLast = lineStart + inputVal.slice(lineStart + 1).search(/[^ ]|$/); + var indent = (spaceLast > lineStart) ? (spaceLast - lineStart) : 0; + var newCode = beforeSelection + '\n' + ' '.repeat(indent) + afterSelection; + + input.value = newCode; + input.selectionStart = selStartPos + indent + 1; + input.selectionEnd = selStartPos + indent + 1; + + this.updateCode(input.value); + } + + closeCharacter (char) { + const selectionStart = this.elTextarea.selectionStart; + const selectionEnd = this.elTextarea.selectionEnd; + + if (!this.skipCloseChar(char)) { + let closeChar = char; + switch (char) { + case '(': + closeChar = String.fromCharCode(char.charCodeAt() + 1); + break + case '<': + case '{': + case '[': + closeChar = String.fromCharCode(char.charCodeAt() + 2); + break + } + const selectionText = this.code.substring(selectionStart, selectionEnd); + const newCode = `${this.code.substring(0, selectionStart)}${selectionText}${closeChar}${this.code.substring(selectionEnd)}`; + this.updateCode(newCode); + } else { + const skipChar = this.code.substr(selectionEnd, 1) === char; + const newSelectionEnd = skipChar ? selectionEnd + 1 : selectionEnd; + const closeChar = !skipChar && ['\'', '"'].includes(char) ? char : ''; + const newCode = `${this.code.substring(0, selectionStart)}${closeChar}${this.code.substring(newSelectionEnd)}`; + this.updateCode(newCode); + this.elTextarea.selectionEnd = ++this.elTextarea.selectionStart; + } + + this.elTextarea.selectionEnd = selectionStart; + } + + skipCloseChar (char) { + const selectionStart = this.elTextarea.selectionStart; + const selectionEnd = this.elTextarea.selectionEnd; + const hasSelection = Math.abs(selectionEnd - selectionStart) > 0; + return [')', '}', ']', '>'].includes(char) || (['\'', '"'].includes(char) && !hasSelection) + } + + updateCode (newCode) { + this.code = newCode; + this.elTextarea.value = newCode; + this.elCode.innerHTML = escapeHtml(newCode); + this.highlight(); + this.setLineNumber(); + setTimeout(this.runUpdate.bind(this), 1); + } + + updateLanguage (newLanguage) { + const oldLanguage = this.opts.language; + this.elCode.classList.remove(`language-${oldLanguage}`); + this.elCode.classList.add(`language-${newLanguage}`); + this.opts.language = newLanguage; + this.highlight(); + } + + addLanguage (name, options) { + this.Prism.languages[name] = options; + } + + populateDefault () { + this.updateCode(this.code); + } + + highlight () { + this.Prism.highlightElement(this.elCode, false); + } + + highlightLines (lineSpec) { + /* This requires the "line-highlight" plugin in PrismJS + Examples + 5: The 5th line + 1-5: Lines 1 through 5 + 1,4: Line 1 and line 4 + 1-2, 5, 9-20: Lines 1 through 2, line 5, lines 9 through 20 + Pass empty string to remove highlighting from all lines + */ + this.elPre.setAttribute('data-line', lineSpec); + this.highlight(); + } + + onUpdate (callback) { + if (callback && {}.toString.call(callback) !== '[object Function]') { + throw Error('CodeFlask expects callback of type Function') + } + + this.updateCallBack = callback; + } + + getCode () { + return this.code + } + + runUpdate () { + if (this.updateCallBack) { + this.updateCallBack(this.code); + } + } + + enableReadonlyMode () { + this.elTextarea.setAttribute('readonly', true); + } + + disableReadonlyMode () { + this.elTextarea.removeAttribute('readonly'); + } + } + + return CodeFlask; + +})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 5a9f5f19..d46061ac 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1,699 @@ -const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function o(e,t,n){const s=t||"codeflask-style",i=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const o=document.createElement("style");return o.innerHTML=e,o.id=s,i.appendChild(o),!0}const a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return a[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!o(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&o("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}handleTabs(e){if(this.opts.handleTabs){if(9!==e.keyCode)return;e.preventDefault();var t=this.elTextarea,n=t.selectionDirection,s=t.selectionStart,i=t.selectionEnd,o=t.value,a=o.substr(0,s),l=o.substring(s,i),r=o.substring(i);const u=" ".repeat(this.opts.tabSize);if(s!==i&&l.length>=u.length){var h=s-a.split("\n").pop().length,d=u.length,c=u.length;if(e.shiftKey)o.substr(h,u.length)===u?(d=-d,h>s?(l=l.substring(0,h)+l.substring(h+u.length),c=0):h===s?(d=0,c=0,l=l.substring(u.length)):(c=-c,a=a.substring(0,h)+a.substring(h+u.length))):(d=0,c=0),l=l.replace(new RegExp("\n"+u.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+u+a.substring(h,s),l=l.replace(/\n/g,"\n"+u);t.value=a+l+r,t.selectionStart=s+d,t.selectionEnd=s+l.length+c,t.selectionDirection=n}else{const n=new RegExp(`(\\n?)((?:${u})*)([^\\n]*)$`);if(e.shiftKey){const e=a.replace(n,((e,t,n,s)=>t+n.slice(0,-1*u.length)+s));e!==a&&(t.value=e+r,t.setSelectionRange(s-u.length,s-u.length))}else{const e=a.replace(n,((e,t,n,s)=>t+n+u+s));t.value=e+r,t.setSelectionRange(s+u.length,s+u.length)}}var p=t.value;this.updateCode(p)}}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.selectionStart,s=t.selectionEnd,i=t.value,o=i.substr(0,n),a=i.substring(s),l=i.lastIndexOf("\n",n-1),r=l+i.slice(l+1).search(/[^ ]|$/),h=r>l?r-l:0,d=o+"\n"+" ".repeat(h)+a;t.value=d,t.selectionStart=n+h+1,t.selectionEnd=n+h+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,i=s?n+1:n,o=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${o}${this.code.substring(i)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const i=this.code.substring(t,n),o=`${this.code.substring(0,t)}${i}${s}${this.code.substring(n)}`;this.updateCode(o)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; +const BACKGROUND_COLOR = '#fff'; +const LINE_HEIGHT = '20px'; +const FONT_SIZE = '16px'; + +const defaultCssTheme = ` +.codeflask { + background: ${BACKGROUND_COLOR}; + color: #4f559c; +} + +.codeflask .token.punctuation { + color: #4a4a4a; +} + +.codeflask .token.keyword { + color: #8500ff; +} + +.codeflask .token.operator { + color: #ff5598; +} + +.codeflask .token.string { + color: #41ad8f; +} + +.codeflask .token.comment { + color: #9badb7; +} + +.codeflask .token.function { + color: #8500ff; +} + +.codeflask .token.boolean { + color: #8500ff; +} + +.codeflask .token.number { + color: #8500ff; +} + +.codeflask .token.selector { + color: #8500ff; +} + +.codeflask .token.property { + color: #8500ff; +} + +.codeflask .token.tag { + color: #8500ff; +} + +.codeflask .token.attr-value { + color: #8500ff; +} +`; + +function cssSupports (property, value) { + if (typeof CSS !== 'undefined') { + return CSS.supports(property, value) + } + + if (typeof document === 'undefined') { + return false; + } + + return toCamelCase(property) in document.body.style +} + +function toCamelCase (cssProperty) { + cssProperty = cssProperty + .split('-') + .filter(word => !!word) + .map(word => word[0].toUpperCase() + word.substr(1)) + .join(''); + + return cssProperty[0].toLowerCase() + cssProperty.substr(1) +} + +const FONT_FAMILY = `"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace`; +const COLOR = (cssSupports('caret-color', '#000')) ? BACKGROUND_COLOR : '#ccc'; +const LINE_NUMBER_WIDTH = '40px'; + +const editorCss = ` + .codeflask { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + } + + .codeflask, .codeflask * { + box-sizing: border-box; + } + + .codeflask__pre { + pointer-events: none; + z-index: 3; + overflow: hidden; + } + + .codeflask__textarea { + background: none; + border: none; + color: ${COLOR}; + z-index: 1; + resize: none; + font-family: ${FONT_FAMILY}; + -webkit-appearance: pre; + caret-color: #111; + z-index: 2; + width: 100%; + height: 100%; + } + + .codeflask--has-line-numbers .codeflask__textarea { + width: calc(100% - ${LINE_NUMBER_WIDTH}); + } + + .codeflask__code { + display: block; + font-family: ${FONT_FAMILY}; + overflow: hidden; + } + + .codeflask__flatten { + padding: 10px; + font-size: ${FONT_SIZE}; + line-height: ${LINE_HEIGHT}; + white-space: pre; + position: absolute; + top: 0; + left: 0; + overflow: auto; + margin: 0 !important; + outline: none; + text-align: left; + } + + .codeflask--has-line-numbers .codeflask__flatten { + width: calc(100% - ${LINE_NUMBER_WIDTH}); + left: ${LINE_NUMBER_WIDTH}; + } + + .codeflask__line-highlight { + position: absolute; + top: 10px; + left: 0; + width: 100%; + height: ${LINE_HEIGHT}; + background: rgba(0,0,0,0.1); + z-index: 1; + } + + .codeflask__lines { + padding: 10px 4px; + font-size: 12px; + line-height: ${LINE_HEIGHT}; + font-family: 'Cousine', monospace; + position: absolute; + left: 0; + top: 0; + width: ${LINE_NUMBER_WIDTH}; + min-height: 100%; + text-align: right; + color: #999; + border-right: 1px solid #f8f8f8; + background-color: #fafafa; + z-index: 5; + } + + .codeflask__lines__line { + display: block; + } + + .codeflask.codeflask--has-line-numbers { + padding-left: ${LINE_NUMBER_WIDTH}; + } + + .codeflask.codeflask--has-line-numbers:before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: ${LINE_NUMBER_WIDTH}; + height: 100%; + background: #eee; + z-index: 1; + } +`; + +function injectCss (css, styleName, parent) { + const CSS_ID = styleName || 'codeflask-style'; + const PARENT = parent || document.head; + + if (!css) { + return false + } + + if (document.getElementById(CSS_ID)) { + return true + } + + const style = document.createElement('style'); + + style.innerHTML = css; + style.id = CSS_ID; + PARENT.appendChild(style); + + return true +} + +const entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' +}; + +function escapeHtml (string) { + return String(string).replace(/[&<>"'`=/]/g, function (s) { + return entityMap[s] + }) +} + +const selfClosingCharMap = { + '(': ')', + '[': ']', + '{': '}', + '<': '>', + "'": "'", + '"': '"' +}; + +class CodeFlask { + constructor (selectorOrElement, Prism, opts) { + if (!selectorOrElement) { + throw Error('CodeFlask expects 1st parameter to be an Element or a String selector') + } + + if (!Prism) { + throw Error('CodeFlask expects 2nd parameter to be the Prism peer dependency') + } + + if (!opts) { + throw Error('CodeFlask expects 3rd parameter to be an object containing options') + } + + if (selectorOrElement.nodeType) { + // If it is an element, assign it directly + this.editorRoot = selectorOrElement; + } else { + // If it is a selector, tries to find element + const editorRoot = document.querySelector(selectorOrElement); + + // If an element is found using this selector, + // assign this element as the root element + if (editorRoot) { + this.editorRoot = editorRoot; + } + } + + this.Prism = Prism; + this.opts = opts; + this.events = {}; + this.startEditor(); + } + + startEditor () { + const isCSSInjected = injectCss(editorCss, null, this.opts.styleParent); + + if (!isCSSInjected) { + throw Error('Failed to inject CodeFlask CSS.') + } + + // The order matters (pre > code). Don't change it + // or things are going to break. + this.createWrapper(); + this.createTextarea(); + this.createPre(); + this.createCode(); + + this.runOptions(); + this.listenTextarea(); + this.populateDefault(); + this.updateCode(this.code); + } + + createWrapper () { + this.code = this.editorRoot.innerHTML; + this.editorRoot.innerHTML = ''; + this.elWrapper = this.createElement('div', this.editorRoot); + this.elWrapper.classList.add('codeflask'); + } + + createTextarea () { + this.elTextarea = this.createElement('textarea', this.elWrapper); + this.elTextarea.classList.add('codeflask__textarea', 'codeflask__flatten'); + } + + createPre () { + this.elPre = this.createElement('pre', this.elWrapper); + this.elPre.classList.add('codeflask__pre', 'codeflask__flatten'); + } + + createCode () { + this.elCode = this.createElement('code', this.elPre); + this.elCode.classList.add('codeflask__code', `language-${this.opts.language || 'html'}`); + } + + createLineNumbers () { + this.elLineNumbers = this.createElement('div', this.elWrapper); + this.elLineNumbers.classList.add('codeflask__lines'); + this.setLineNumber(); + } + + createElement (elementTag, whereToAppend) { + const element = document.createElement(elementTag); + whereToAppend.appendChild(element); + + return element + } + + runOptions () { + this.opts.rtl = this.opts.rtl || false; + this.opts.tabSize = this.opts.tabSize || 2; + this.opts.enableAutocorrect = this.opts.enableAutocorrect || false; + this.opts.lineNumbers = this.opts.lineNumbers || false; + this.opts.defaultTheme = this.opts.defaultTheme !== false; + this.opts.areaId = this.opts.areaId || null; + this.opts.ariaLabelledby = this.opts.ariaLabelledby || null; + this.opts.readonly = this.opts.readonly || false; + this.opts.customEventListeners = this.opts.customEventListeners || {}; + this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"']; + + // if handleTabs is not either true or false, make it true by default + if (typeof this.opts.handleTabs !== 'boolean') { + this.opts.handleTabs = true; + } + // if handleTabs is not either true or false, make it true by default + if (typeof this.opts.handleNewLineIndentation !== 'boolean') { + this.opts.handleNewLineIndentation = true; + } + + if (this.opts.rtl === true) { + this.elTextarea.setAttribute('dir', 'rtl'); + this.elPre.setAttribute('dir', 'rtl'); + } + + if (this.opts.enableAutocorrect === false) { + this.elTextarea.setAttribute('spellcheck', 'false'); + this.elTextarea.setAttribute('autocapitalize', 'off'); + this.elTextarea.setAttribute('autocomplete', 'off'); + this.elTextarea.setAttribute('autocorrect', 'off'); + } + + if (this.opts.lineNumbers) { + this.elWrapper.classList.add('codeflask--has-line-numbers'); + this.createLineNumbers(); + } + + if (this.opts.defaultTheme) { + injectCss(defaultCssTheme, 'theme-default', this.opts.styleParent); + } + + if (this.opts.areaId) { + this.elTextarea.setAttribute('id', this.opts.areaId); + } + + if (this.opts.ariaLabelledby) { + this.elTextarea.setAttribute('aria-labelledby', this.opts.ariaLabelledby); + } + + if (this.opts.readonly) { + this.enableReadonlyMode(); + } + } + + updateLineNumbersCount () { + let numberList = ''; + + for (let i = 1; i <= this.lineNumber; i++) { + numberList = numberList + `${i}`; + } + + this.elLineNumbers.innerHTML = numberList; + } + + listenTextarea () { + const customEventListeners = this.opts.customEventListeners; + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.addEventListener(eventName, func); + } + + this.elTextarea.addEventListener('input', this.events.input = (e) => { + if (this.opts.readonly) { + return; + } + this.code = e.target.value; + this.elCode.innerHTML = escapeHtml(e.target.value); + this.highlight(); + setTimeout(() => { + this.runUpdate(); + this.setLineNumber(); + }, 1); + }); + + this.elTextarea.addEventListener('keydown', this.events.keydown = (e) => { + if (this.opts.readonly) { + return; + } + this.handleTabs(e); + this.handleBackspace(e); + this.handleSelfClosingCharacters(e); + this.handleNewLineIndentation(e); + }); + + this.elTextarea.addEventListener('scroll', this.events.scroll = (e) => { + this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`; + if (this.elLineNumbers) { + this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)`; + this.elPre.style.width = `calc(100% - 40px + ${e.target.scrollLeft}px)`; + } + }); + } + + removeEventListeners () { + for (const [eventName, func] of Object.entries(customEventListeners)) { + this.elTextarea.removeEventListener(eventName, func); + } + for (const [eventName, func] of Object.entries(this.events)) { + this.elTextarea.removeEventListener(eventName, func); + } + } + + getSelectInfo () { + var input = this.elTextarea; + var selStartPos = input.selectionStart; + var selEndPos = input.selectionEnd; + var beforeSelection = input.value.substr(0, selStartPos); + var selectionVal = input.value.substring(selStartPos, selEndPos); + var afterSelection = input.value.substring(selEndPos); + return { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } + } + + handleTabs (e) { + if (!this.opts.handleTabs || e.key !== "Tab") { + return + } + e.preventDefault(); + + var input = this.elTextarea; + var inputVal = input.value; + var { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); + const indent = ' '.repeat(this.opts.tabSize); + + if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { + var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length; + var startIndentLen = indent.length; + var endIndentLen = indent.length; + + // Unindent + if (e.shiftKey) { + var currentLineStartStr = inputVal.substr(currentLineStart, indent.length); + // Line start whit indent + if (currentLineStartStr === indent) { + startIndentLen = -startIndentLen; + + if (currentLineStart > selStartPos) { + // Indent is in selection + selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length); + endIndentLen = 0; + } else if (currentLineStart === selStartPos) { + // Indent is in start of selection + startIndentLen = 0; + endIndentLen = 0; + selectionVal = selectionVal.substring(indent.length); + } else { + // Indent is before selection + endIndentLen = -endIndentLen; + beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length); + } + } else { + startIndentLen = 0; + endIndentLen = 0; + } + + selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n'); + } else { + // Indent + beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos); + selectionVal = selectionVal.replace(/\n/g, '\n' + indent); + } + + // Set new indented value + input.value = beforeSelection + selectionVal + afterSelection; + input.setSelectionRange(selStartPos + startIndentLen, selStartPos + selectionVal.length + endIndentLen); + } else { + const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`); + if (e.shiftKey) { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content + ); + if (newBeforeSelection !== beforeSelection) { + input.value = newBeforeSelection + afterSelection; + input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length); + } + } else { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content + ); + input.value = newBeforeSelection + afterSelection; + input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length); + } + } + + this.updateCode(input.value); + } + + handleBackspace (e) { + if (e.key !== "Backspace") { + return + } + + var { selStartPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); + if (selectionVal !== '') { + return + } + + if (!beforeSelection.match(/\n( ){1,}$/)) { + return + } + + e.preventDefault(); + const newBeforeSelection = beforeSelection.replace(/ $/, ''); + const input = this.elTextarea; + input.value = newBeforeSelection + afterSelection; + this.updateCode(input.value); + input.setSelectionRange(selStartPos - 2, selStartPos - 2); + } + + handleSelfClosingCharacters (e) { + if (!this.opts.selfClosingCharacters.length) return + const openChars = this.opts.selfClosingCharacters; + const closeChars = this.opts.selfClosingCharacters.map(c => selfClosingCharMap[c]); + + if (!openChars.includes(e.key) && !closeChars.includes(e.key)) { + return + } + + this.closeCharacter(e.key); + } + + setLineNumber () { + this.lineNumber = this.code.split('\n').length; + + if (this.opts.lineNumbers) { + this.updateLineNumbersCount(); + } + } + + handleNewLineIndentation (e) { + if (!this.opts.handleNewLineIndentation || e.keyCode !== 13) { + return + } + + e.preventDefault(); + var input = this.elTextarea; + var inputVal = input.value; + var { selStartPos, beforeSelection, afterSelection } = this.getSelectInfo(); + + var lineStart = inputVal.lastIndexOf('\n', selStartPos - 1); + var spaceLast = lineStart + inputVal.slice(lineStart + 1).search(/[^ ]|$/); + var indent = (spaceLast > lineStart) ? (spaceLast - lineStart) : 0; + var newCode = beforeSelection + '\n' + ' '.repeat(indent) + afterSelection; + + input.value = newCode; + input.selectionStart = selStartPos + indent + 1; + input.selectionEnd = selStartPos + indent + 1; + + this.updateCode(input.value); + } + + closeCharacter (char) { + const selectionStart = this.elTextarea.selectionStart; + const selectionEnd = this.elTextarea.selectionEnd; + + if (!this.skipCloseChar(char)) { + let closeChar = char; + switch (char) { + case '(': + closeChar = String.fromCharCode(char.charCodeAt() + 1); + break + case '<': + case '{': + case '[': + closeChar = String.fromCharCode(char.charCodeAt() + 2); + break + } + const selectionText = this.code.substring(selectionStart, selectionEnd); + const newCode = `${this.code.substring(0, selectionStart)}${selectionText}${closeChar}${this.code.substring(selectionEnd)}`; + this.updateCode(newCode); + } else { + const skipChar = this.code.substr(selectionEnd, 1) === char; + const newSelectionEnd = skipChar ? selectionEnd + 1 : selectionEnd; + const closeChar = !skipChar && ['\'', '"'].includes(char) ? char : ''; + const newCode = `${this.code.substring(0, selectionStart)}${closeChar}${this.code.substring(newSelectionEnd)}`; + this.updateCode(newCode); + this.elTextarea.selectionEnd = ++this.elTextarea.selectionStart; + } + + this.elTextarea.selectionEnd = selectionStart; + } + + skipCloseChar (char) { + const selectionStart = this.elTextarea.selectionStart; + const selectionEnd = this.elTextarea.selectionEnd; + const hasSelection = Math.abs(selectionEnd - selectionStart) > 0; + return [')', '}', ']', '>'].includes(char) || (['\'', '"'].includes(char) && !hasSelection) + } + + updateCode (newCode) { + this.code = newCode; + this.elTextarea.value = newCode; + this.elCode.innerHTML = escapeHtml(newCode); + this.highlight(); + this.setLineNumber(); + setTimeout(this.runUpdate.bind(this), 1); + } + + updateLanguage (newLanguage) { + const oldLanguage = this.opts.language; + this.elCode.classList.remove(`language-${oldLanguage}`); + this.elCode.classList.add(`language-${newLanguage}`); + this.opts.language = newLanguage; + this.highlight(); + } + + addLanguage (name, options) { + this.Prism.languages[name] = options; + } + + populateDefault () { + this.updateCode(this.code); + } + + highlight () { + this.Prism.highlightElement(this.elCode, false); + } + + highlightLines (lineSpec) { + /* This requires the "line-highlight" plugin in PrismJS + Examples + 5: The 5th line + 1-5: Lines 1 through 5 + 1,4: Line 1 and line 4 + 1-2, 5, 9-20: Lines 1 through 2, line 5, lines 9 through 20 + Pass empty string to remove highlighting from all lines + */ + this.elPre.setAttribute('data-line', lineSpec); + this.highlight(); + } + + onUpdate (callback) { + if (callback && {}.toString.call(callback) !== '[object Function]') { + throw Error('CodeFlask expects callback of type Function') + } + + this.updateCallBack = callback; + } + + getCode () { + return this.code + } + + runUpdate () { + if (this.updateCallBack) { + this.updateCallBack(this.code); + } + } + + enableReadonlyMode () { + this.elTextarea.setAttribute('readonly', true); + } + + disableReadonlyMode () { + this.elTextarea.removeAttribute('readonly'); + } +} + +export { CodeFlask as default }; diff --git a/src/codeflask.js b/src/codeflask.js index 53ebd6ee..5a279221 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -190,6 +190,7 @@ export default class CodeFlask { return; } this.handleTabs(e) + this.handleBackspace(e) this.handleSelfClosingCharacters(e) this.handleNewLineIndentation(e) }) @@ -212,92 +213,112 @@ export default class CodeFlask { } } + getSelectInfo () { + var input = this.elTextarea + var selStartPos = input.selectionStart + var selEndPos = input.selectionEnd + var beforeSelection = input.value.substr(0, selStartPos) + var selectionVal = input.value.substring(selStartPos, selEndPos) + var afterSelection = input.value.substring(selEndPos) + return { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } + } + handleTabs (e) { - if (this.opts.handleTabs) { - if (e.keyCode !== 9) { - return - } - e.preventDefault() - - var input = this.elTextarea - var selectionDir = input.selectionDirection - var selStartPos = input.selectionStart - var selEndPos = input.selectionEnd - var inputVal = input.value - - var beforeSelection = inputVal.substr(0, selStartPos) - var selectionVal = inputVal.substring(selStartPos, selEndPos) - var afterSelection = inputVal.substring(selEndPos) - const indent = ' '.repeat(this.opts.tabSize) - - if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { - var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length - var startIndentLen = indent.length - var endIndentLen = indent.length - - // Unindent - if (e.shiftKey) { - var currentLineStartStr = inputVal.substr(currentLineStart, indent.length) - // Line start whit indent - if (currentLineStartStr === indent) { - startIndentLen = -startIndentLen - - if (currentLineStart > selStartPos) { - // Indent is in selection - selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length) - endIndentLen = 0 - } else if (currentLineStart === selStartPos) { - // Indent is in start of selection - startIndentLen = 0 - endIndentLen = 0 - selectionVal = selectionVal.substring(indent.length) - } else { - // Indent is before selection - endIndentLen = -endIndentLen - beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length) - } - } else { + if (!this.opts.handleTabs || e.key !== "Tab") { + return + } + e.preventDefault() + + var input = this.elTextarea + var inputVal = input.value + var { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo() + const indent = ' '.repeat(this.opts.tabSize) + + if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { + var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length + var startIndentLen = indent.length + var endIndentLen = indent.length + + // Unindent + if (e.shiftKey) { + var currentLineStartStr = inputVal.substr(currentLineStart, indent.length) + // Line start whit indent + if (currentLineStartStr === indent) { + startIndentLen = -startIndentLen + + if (currentLineStart > selStartPos) { + // Indent is in selection + selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length) + endIndentLen = 0 + } else if (currentLineStart === selStartPos) { + // Indent is in start of selection startIndentLen = 0 endIndentLen = 0 + selectionVal = selectionVal.substring(indent.length) + } else { + // Indent is before selection + endIndentLen = -endIndentLen + beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length) } - - selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n') } else { - // Indent - beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos) - selectionVal = selectionVal.replace(/\n/g, '\n' + indent) + startIndentLen = 0 + endIndentLen = 0 } - // Set new indented value - input.value = beforeSelection + selectionVal + afterSelection - - input.selectionStart = selStartPos + startIndentLen - input.selectionEnd = selStartPos + selectionVal.length + endIndentLen - input.selectionDirection = selectionDir + selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n') } else { - const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`) - if (e.shiftKey) { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content - ) - if (newBeforeSelection !== beforeSelection) { - input.value = newBeforeSelection + afterSelection - input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length) - } - } else { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content - ) + // Indent + beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos) + selectionVal = selectionVal.replace(/\n/g, '\n' + indent) + } + + // Set new indented value + input.value = beforeSelection + selectionVal + afterSelection + input.setSelectionRange(selStartPos + startIndentLen, selStartPos + selectionVal.length + endIndentLen) + } else { + const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`) + if (e.shiftKey) { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content + ) + if (newBeforeSelection !== beforeSelection) { input.value = newBeforeSelection + afterSelection - input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length) + input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length) } + } else { + const newBeforeSelection = beforeSelection.replace( + activeLineRegexp, + (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content + ) + input.value = newBeforeSelection + afterSelection + input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length) } + } - var newCode = input.value - this.updateCode(newCode) + this.updateCode(input.value) + } + + handleBackspace (e) { + if (e.key !== "Backspace") { + return + } + + var { selStartPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo() + if (selectionVal !== '') { + return } + + if (!beforeSelection.match(/\n( ){1,}$/)) { + return + } + + e.preventDefault() + const newBeforeSelection = beforeSelection.replace(/ $/, '') + const input = this.elTextarea + input.value = newBeforeSelection + afterSelection + this.updateCode(input.value) + input.setSelectionRange(selStartPos - 2, selStartPos - 2) } handleSelfClosingCharacters (e) { @@ -321,19 +342,14 @@ export default class CodeFlask { } handleNewLineIndentation (e) { - if (!this.opts.handleNewLineIndentation) return - if (e.keyCode !== 13) { + if (!this.opts.handleNewLineIndentation || e.keyCode !== 13) { return } e.preventDefault() var input = this.elTextarea - var selStartPos = input.selectionStart - var selEndPos = input.selectionEnd var inputVal = input.value - - var beforeSelection = inputVal.substr(0, selStartPos) - var afterSelection = inputVal.substring(selEndPos) + var { selStartPos, beforeSelection, afterSelection } = this.getSelectInfo() var lineStart = inputVal.lastIndexOf('\n', selStartPos - 1) var spaceLast = lineStart + inputVal.slice(lineStart + 1).search(/[^ ]|$/) From ab760e7a2ba57084a833f0251f72c0be0e11f4bd Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Mon, 25 Jul 2022 00:02:12 -0400 Subject: [PATCH 19/25] bump version --- build/codeflask.min.js | 708 +------------------------------------- build/codeflask.module.js | 700 +------------------------------------ package.json | 2 +- 3 files changed, 3 insertions(+), 1407 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index ac150bdb..15d1b07d 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1,707 +1 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.CodeFlask = factory()); -})(this, (function () { 'use strict'; - - const BACKGROUND_COLOR = '#fff'; - const LINE_HEIGHT = '20px'; - const FONT_SIZE = '16px'; - - const defaultCssTheme = ` -.codeflask { - background: ${BACKGROUND_COLOR}; - color: #4f559c; -} - -.codeflask .token.punctuation { - color: #4a4a4a; -} - -.codeflask .token.keyword { - color: #8500ff; -} - -.codeflask .token.operator { - color: #ff5598; -} - -.codeflask .token.string { - color: #41ad8f; -} - -.codeflask .token.comment { - color: #9badb7; -} - -.codeflask .token.function { - color: #8500ff; -} - -.codeflask .token.boolean { - color: #8500ff; -} - -.codeflask .token.number { - color: #8500ff; -} - -.codeflask .token.selector { - color: #8500ff; -} - -.codeflask .token.property { - color: #8500ff; -} - -.codeflask .token.tag { - color: #8500ff; -} - -.codeflask .token.attr-value { - color: #8500ff; -} -`; - - function cssSupports (property, value) { - if (typeof CSS !== 'undefined') { - return CSS.supports(property, value) - } - - if (typeof document === 'undefined') { - return false; - } - - return toCamelCase(property) in document.body.style - } - - function toCamelCase (cssProperty) { - cssProperty = cssProperty - .split('-') - .filter(word => !!word) - .map(word => word[0].toUpperCase() + word.substr(1)) - .join(''); - - return cssProperty[0].toLowerCase() + cssProperty.substr(1) - } - - const FONT_FAMILY = `"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace`; - const COLOR = (cssSupports('caret-color', '#000')) ? BACKGROUND_COLOR : '#ccc'; - const LINE_NUMBER_WIDTH = '40px'; - - const editorCss = ` - .codeflask { - position: absolute; - width: 100%; - height: 100%; - overflow: hidden; - } - - .codeflask, .codeflask * { - box-sizing: border-box; - } - - .codeflask__pre { - pointer-events: none; - z-index: 3; - overflow: hidden; - } - - .codeflask__textarea { - background: none; - border: none; - color: ${COLOR}; - z-index: 1; - resize: none; - font-family: ${FONT_FAMILY}; - -webkit-appearance: pre; - caret-color: #111; - z-index: 2; - width: 100%; - height: 100%; - } - - .codeflask--has-line-numbers .codeflask__textarea { - width: calc(100% - ${LINE_NUMBER_WIDTH}); - } - - .codeflask__code { - display: block; - font-family: ${FONT_FAMILY}; - overflow: hidden; - } - - .codeflask__flatten { - padding: 10px; - font-size: ${FONT_SIZE}; - line-height: ${LINE_HEIGHT}; - white-space: pre; - position: absolute; - top: 0; - left: 0; - overflow: auto; - margin: 0 !important; - outline: none; - text-align: left; - } - - .codeflask--has-line-numbers .codeflask__flatten { - width: calc(100% - ${LINE_NUMBER_WIDTH}); - left: ${LINE_NUMBER_WIDTH}; - } - - .codeflask__line-highlight { - position: absolute; - top: 10px; - left: 0; - width: 100%; - height: ${LINE_HEIGHT}; - background: rgba(0,0,0,0.1); - z-index: 1; - } - - .codeflask__lines { - padding: 10px 4px; - font-size: 12px; - line-height: ${LINE_HEIGHT}; - font-family: 'Cousine', monospace; - position: absolute; - left: 0; - top: 0; - width: ${LINE_NUMBER_WIDTH}; - min-height: 100%; - text-align: right; - color: #999; - border-right: 1px solid #f8f8f8; - background-color: #fafafa; - z-index: 5; - } - - .codeflask__lines__line { - display: block; - } - - .codeflask.codeflask--has-line-numbers { - padding-left: ${LINE_NUMBER_WIDTH}; - } - - .codeflask.codeflask--has-line-numbers:before { - content: ''; - position: absolute; - left: 0; - top: 0; - width: ${LINE_NUMBER_WIDTH}; - height: 100%; - background: #eee; - z-index: 1; - } -`; - - function injectCss (css, styleName, parent) { - const CSS_ID = styleName || 'codeflask-style'; - const PARENT = parent || document.head; - - if (!css) { - return false - } - - if (document.getElementById(CSS_ID)) { - return true - } - - const style = document.createElement('style'); - - style.innerHTML = css; - style.id = CSS_ID; - PARENT.appendChild(style); - - return true - } - - const entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - '`': '`', - '=': '=' - }; - - function escapeHtml (string) { - return String(string).replace(/[&<>"'`=/]/g, function (s) { - return entityMap[s] - }) - } - - const selfClosingCharMap = { - '(': ')', - '[': ']', - '{': '}', - '<': '>', - "'": "'", - '"': '"' - }; - - class CodeFlask { - constructor (selectorOrElement, Prism, opts) { - if (!selectorOrElement) { - throw Error('CodeFlask expects 1st parameter to be an Element or a String selector') - } - - if (!Prism) { - throw Error('CodeFlask expects 2nd parameter to be the Prism peer dependency') - } - - if (!opts) { - throw Error('CodeFlask expects 3rd parameter to be an object containing options') - } - - if (selectorOrElement.nodeType) { - // If it is an element, assign it directly - this.editorRoot = selectorOrElement; - } else { - // If it is a selector, tries to find element - const editorRoot = document.querySelector(selectorOrElement); - - // If an element is found using this selector, - // assign this element as the root element - if (editorRoot) { - this.editorRoot = editorRoot; - } - } - - this.Prism = Prism; - this.opts = opts; - this.events = {}; - this.startEditor(); - } - - startEditor () { - const isCSSInjected = injectCss(editorCss, null, this.opts.styleParent); - - if (!isCSSInjected) { - throw Error('Failed to inject CodeFlask CSS.') - } - - // The order matters (pre > code). Don't change it - // or things are going to break. - this.createWrapper(); - this.createTextarea(); - this.createPre(); - this.createCode(); - - this.runOptions(); - this.listenTextarea(); - this.populateDefault(); - this.updateCode(this.code); - } - - createWrapper () { - this.code = this.editorRoot.innerHTML; - this.editorRoot.innerHTML = ''; - this.elWrapper = this.createElement('div', this.editorRoot); - this.elWrapper.classList.add('codeflask'); - } - - createTextarea () { - this.elTextarea = this.createElement('textarea', this.elWrapper); - this.elTextarea.classList.add('codeflask__textarea', 'codeflask__flatten'); - } - - createPre () { - this.elPre = this.createElement('pre', this.elWrapper); - this.elPre.classList.add('codeflask__pre', 'codeflask__flatten'); - } - - createCode () { - this.elCode = this.createElement('code', this.elPre); - this.elCode.classList.add('codeflask__code', `language-${this.opts.language || 'html'}`); - } - - createLineNumbers () { - this.elLineNumbers = this.createElement('div', this.elWrapper); - this.elLineNumbers.classList.add('codeflask__lines'); - this.setLineNumber(); - } - - createElement (elementTag, whereToAppend) { - const element = document.createElement(elementTag); - whereToAppend.appendChild(element); - - return element - } - - runOptions () { - this.opts.rtl = this.opts.rtl || false; - this.opts.tabSize = this.opts.tabSize || 2; - this.opts.enableAutocorrect = this.opts.enableAutocorrect || false; - this.opts.lineNumbers = this.opts.lineNumbers || false; - this.opts.defaultTheme = this.opts.defaultTheme !== false; - this.opts.areaId = this.opts.areaId || null; - this.opts.ariaLabelledby = this.opts.ariaLabelledby || null; - this.opts.readonly = this.opts.readonly || false; - this.opts.customEventListeners = this.opts.customEventListeners || {}; - this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"']; - - // if handleTabs is not either true or false, make it true by default - if (typeof this.opts.handleTabs !== 'boolean') { - this.opts.handleTabs = true; - } - // if handleTabs is not either true or false, make it true by default - if (typeof this.opts.handleNewLineIndentation !== 'boolean') { - this.opts.handleNewLineIndentation = true; - } - - if (this.opts.rtl === true) { - this.elTextarea.setAttribute('dir', 'rtl'); - this.elPre.setAttribute('dir', 'rtl'); - } - - if (this.opts.enableAutocorrect === false) { - this.elTextarea.setAttribute('spellcheck', 'false'); - this.elTextarea.setAttribute('autocapitalize', 'off'); - this.elTextarea.setAttribute('autocomplete', 'off'); - this.elTextarea.setAttribute('autocorrect', 'off'); - } - - if (this.opts.lineNumbers) { - this.elWrapper.classList.add('codeflask--has-line-numbers'); - this.createLineNumbers(); - } - - if (this.opts.defaultTheme) { - injectCss(defaultCssTheme, 'theme-default', this.opts.styleParent); - } - - if (this.opts.areaId) { - this.elTextarea.setAttribute('id', this.opts.areaId); - } - - if (this.opts.ariaLabelledby) { - this.elTextarea.setAttribute('aria-labelledby', this.opts.ariaLabelledby); - } - - if (this.opts.readonly) { - this.enableReadonlyMode(); - } - } - - updateLineNumbersCount () { - let numberList = ''; - - for (let i = 1; i <= this.lineNumber; i++) { - numberList = numberList + `${i}`; - } - - this.elLineNumbers.innerHTML = numberList; - } - - listenTextarea () { - const customEventListeners = this.opts.customEventListeners; - for (const [eventName, func] of Object.entries(customEventListeners)) { - this.elTextarea.addEventListener(eventName, func); - } - - this.elTextarea.addEventListener('input', this.events.input = (e) => { - if (this.opts.readonly) { - return; - } - this.code = e.target.value; - this.elCode.innerHTML = escapeHtml(e.target.value); - this.highlight(); - setTimeout(() => { - this.runUpdate(); - this.setLineNumber(); - }, 1); - }); - - this.elTextarea.addEventListener('keydown', this.events.keydown = (e) => { - if (this.opts.readonly) { - return; - } - this.handleTabs(e); - this.handleBackspace(e); - this.handleSelfClosingCharacters(e); - this.handleNewLineIndentation(e); - }); - - this.elTextarea.addEventListener('scroll', this.events.scroll = (e) => { - this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`; - if (this.elLineNumbers) { - this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)`; - this.elPre.style.width = `calc(100% - 40px + ${e.target.scrollLeft}px)`; - } - }); - } - - removeEventListeners () { - for (const [eventName, func] of Object.entries(customEventListeners)) { - this.elTextarea.removeEventListener(eventName, func); - } - for (const [eventName, func] of Object.entries(this.events)) { - this.elTextarea.removeEventListener(eventName, func); - } - } - - getSelectInfo () { - var input = this.elTextarea; - var selStartPos = input.selectionStart; - var selEndPos = input.selectionEnd; - var beforeSelection = input.value.substr(0, selStartPos); - var selectionVal = input.value.substring(selStartPos, selEndPos); - var afterSelection = input.value.substring(selEndPos); - return { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } - } - - handleTabs (e) { - if (!this.opts.handleTabs || e.key !== "Tab") { - return - } - e.preventDefault(); - - var input = this.elTextarea; - var inputVal = input.value; - var { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); - const indent = ' '.repeat(this.opts.tabSize); - - if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { - var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length; - var startIndentLen = indent.length; - var endIndentLen = indent.length; - - // Unindent - if (e.shiftKey) { - var currentLineStartStr = inputVal.substr(currentLineStart, indent.length); - // Line start whit indent - if (currentLineStartStr === indent) { - startIndentLen = -startIndentLen; - - if (currentLineStart > selStartPos) { - // Indent is in selection - selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length); - endIndentLen = 0; - } else if (currentLineStart === selStartPos) { - // Indent is in start of selection - startIndentLen = 0; - endIndentLen = 0; - selectionVal = selectionVal.substring(indent.length); - } else { - // Indent is before selection - endIndentLen = -endIndentLen; - beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length); - } - } else { - startIndentLen = 0; - endIndentLen = 0; - } - - selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n'); - } else { - // Indent - beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos); - selectionVal = selectionVal.replace(/\n/g, '\n' + indent); - } - - // Set new indented value - input.value = beforeSelection + selectionVal + afterSelection; - input.setSelectionRange(selStartPos + startIndentLen, selStartPos + selectionVal.length + endIndentLen); - } else { - const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`); - if (e.shiftKey) { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content - ); - if (newBeforeSelection !== beforeSelection) { - input.value = newBeforeSelection + afterSelection; - input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length); - } - } else { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content - ); - input.value = newBeforeSelection + afterSelection; - input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length); - } - } - - this.updateCode(input.value); - } - - handleBackspace (e) { - if (e.key !== "Backspace") { - return - } - - var { selStartPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); - if (selectionVal !== '') { - return - } - - if (!beforeSelection.match(/\n( ){1,}$/)) { - return - } - - e.preventDefault(); - const newBeforeSelection = beforeSelection.replace(/ $/, ''); - const input = this.elTextarea; - input.value = newBeforeSelection + afterSelection; - this.updateCode(input.value); - input.setSelectionRange(selStartPos - 2, selStartPos - 2); - } - - handleSelfClosingCharacters (e) { - if (!this.opts.selfClosingCharacters.length) return - const openChars = this.opts.selfClosingCharacters; - const closeChars = this.opts.selfClosingCharacters.map(c => selfClosingCharMap[c]); - - if (!openChars.includes(e.key) && !closeChars.includes(e.key)) { - return - } - - this.closeCharacter(e.key); - } - - setLineNumber () { - this.lineNumber = this.code.split('\n').length; - - if (this.opts.lineNumbers) { - this.updateLineNumbersCount(); - } - } - - handleNewLineIndentation (e) { - if (!this.opts.handleNewLineIndentation || e.keyCode !== 13) { - return - } - - e.preventDefault(); - var input = this.elTextarea; - var inputVal = input.value; - var { selStartPos, beforeSelection, afterSelection } = this.getSelectInfo(); - - var lineStart = inputVal.lastIndexOf('\n', selStartPos - 1); - var spaceLast = lineStart + inputVal.slice(lineStart + 1).search(/[^ ]|$/); - var indent = (spaceLast > lineStart) ? (spaceLast - lineStart) : 0; - var newCode = beforeSelection + '\n' + ' '.repeat(indent) + afterSelection; - - input.value = newCode; - input.selectionStart = selStartPos + indent + 1; - input.selectionEnd = selStartPos + indent + 1; - - this.updateCode(input.value); - } - - closeCharacter (char) { - const selectionStart = this.elTextarea.selectionStart; - const selectionEnd = this.elTextarea.selectionEnd; - - if (!this.skipCloseChar(char)) { - let closeChar = char; - switch (char) { - case '(': - closeChar = String.fromCharCode(char.charCodeAt() + 1); - break - case '<': - case '{': - case '[': - closeChar = String.fromCharCode(char.charCodeAt() + 2); - break - } - const selectionText = this.code.substring(selectionStart, selectionEnd); - const newCode = `${this.code.substring(0, selectionStart)}${selectionText}${closeChar}${this.code.substring(selectionEnd)}`; - this.updateCode(newCode); - } else { - const skipChar = this.code.substr(selectionEnd, 1) === char; - const newSelectionEnd = skipChar ? selectionEnd + 1 : selectionEnd; - const closeChar = !skipChar && ['\'', '"'].includes(char) ? char : ''; - const newCode = `${this.code.substring(0, selectionStart)}${closeChar}${this.code.substring(newSelectionEnd)}`; - this.updateCode(newCode); - this.elTextarea.selectionEnd = ++this.elTextarea.selectionStart; - } - - this.elTextarea.selectionEnd = selectionStart; - } - - skipCloseChar (char) { - const selectionStart = this.elTextarea.selectionStart; - const selectionEnd = this.elTextarea.selectionEnd; - const hasSelection = Math.abs(selectionEnd - selectionStart) > 0; - return [')', '}', ']', '>'].includes(char) || (['\'', '"'].includes(char) && !hasSelection) - } - - updateCode (newCode) { - this.code = newCode; - this.elTextarea.value = newCode; - this.elCode.innerHTML = escapeHtml(newCode); - this.highlight(); - this.setLineNumber(); - setTimeout(this.runUpdate.bind(this), 1); - } - - updateLanguage (newLanguage) { - const oldLanguage = this.opts.language; - this.elCode.classList.remove(`language-${oldLanguage}`); - this.elCode.classList.add(`language-${newLanguage}`); - this.opts.language = newLanguage; - this.highlight(); - } - - addLanguage (name, options) { - this.Prism.languages[name] = options; - } - - populateDefault () { - this.updateCode(this.code); - } - - highlight () { - this.Prism.highlightElement(this.elCode, false); - } - - highlightLines (lineSpec) { - /* This requires the "line-highlight" plugin in PrismJS - Examples - 5: The 5th line - 1-5: Lines 1 through 5 - 1,4: Line 1 and line 4 - 1-2, 5, 9-20: Lines 1 through 2, line 5, lines 9 through 20 - Pass empty string to remove highlighting from all lines - */ - this.elPre.setAttribute('data-line', lineSpec); - this.highlight(); - } - - onUpdate (callback) { - if (callback && {}.toString.call(callback) !== '[object Function]') { - throw Error('CodeFlask expects callback of type Function') - } - - this.updateCallBack = callback; - } - - getCode () { - return this.code - } - - runUpdate () { - if (this.updateCallBack) { - this.updateCallBack(this.code); - } - } - - enableReadonlyMode () { - this.elTextarea.setAttribute('readonly', true); - } - - disableReadonlyMode () { - this.elTextarea.removeAttribute('readonly'); - } - } - - return CodeFlask; - -})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,o;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(o=(o=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:o,beforeSelection:i,selectionVal:a,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==o&&a.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(a=a.substring(0,h)+a.substring(h+r.length),d=0):h===s?(c=0,d=0,a=a.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),a=a.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),a=a.replace(/\n/g,"\n"+r);t.value=i+a+l,t.setSelectionRange(s+c,s+a.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:o}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),a=this.elTextarea;a.value=i+o,this.updateCode(a.value),a.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:o,afterSelection:i}=this.getSelectInfo(),a=n.lastIndexOf("\n",s-1),l=a+n.slice(a+1).search(/[^ ]|$/),r=l>a?l-a:0,h=o+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${i}${this.code.substring(o)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const o=this.code.substring(t,n),i=`${this.code.substring(0,t)}${o}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index d46061ac..372a30dd 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1,699 +1 @@ -const BACKGROUND_COLOR = '#fff'; -const LINE_HEIGHT = '20px'; -const FONT_SIZE = '16px'; - -const defaultCssTheme = ` -.codeflask { - background: ${BACKGROUND_COLOR}; - color: #4f559c; -} - -.codeflask .token.punctuation { - color: #4a4a4a; -} - -.codeflask .token.keyword { - color: #8500ff; -} - -.codeflask .token.operator { - color: #ff5598; -} - -.codeflask .token.string { - color: #41ad8f; -} - -.codeflask .token.comment { - color: #9badb7; -} - -.codeflask .token.function { - color: #8500ff; -} - -.codeflask .token.boolean { - color: #8500ff; -} - -.codeflask .token.number { - color: #8500ff; -} - -.codeflask .token.selector { - color: #8500ff; -} - -.codeflask .token.property { - color: #8500ff; -} - -.codeflask .token.tag { - color: #8500ff; -} - -.codeflask .token.attr-value { - color: #8500ff; -} -`; - -function cssSupports (property, value) { - if (typeof CSS !== 'undefined') { - return CSS.supports(property, value) - } - - if (typeof document === 'undefined') { - return false; - } - - return toCamelCase(property) in document.body.style -} - -function toCamelCase (cssProperty) { - cssProperty = cssProperty - .split('-') - .filter(word => !!word) - .map(word => word[0].toUpperCase() + word.substr(1)) - .join(''); - - return cssProperty[0].toLowerCase() + cssProperty.substr(1) -} - -const FONT_FAMILY = `"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace`; -const COLOR = (cssSupports('caret-color', '#000')) ? BACKGROUND_COLOR : '#ccc'; -const LINE_NUMBER_WIDTH = '40px'; - -const editorCss = ` - .codeflask { - position: absolute; - width: 100%; - height: 100%; - overflow: hidden; - } - - .codeflask, .codeflask * { - box-sizing: border-box; - } - - .codeflask__pre { - pointer-events: none; - z-index: 3; - overflow: hidden; - } - - .codeflask__textarea { - background: none; - border: none; - color: ${COLOR}; - z-index: 1; - resize: none; - font-family: ${FONT_FAMILY}; - -webkit-appearance: pre; - caret-color: #111; - z-index: 2; - width: 100%; - height: 100%; - } - - .codeflask--has-line-numbers .codeflask__textarea { - width: calc(100% - ${LINE_NUMBER_WIDTH}); - } - - .codeflask__code { - display: block; - font-family: ${FONT_FAMILY}; - overflow: hidden; - } - - .codeflask__flatten { - padding: 10px; - font-size: ${FONT_SIZE}; - line-height: ${LINE_HEIGHT}; - white-space: pre; - position: absolute; - top: 0; - left: 0; - overflow: auto; - margin: 0 !important; - outline: none; - text-align: left; - } - - .codeflask--has-line-numbers .codeflask__flatten { - width: calc(100% - ${LINE_NUMBER_WIDTH}); - left: ${LINE_NUMBER_WIDTH}; - } - - .codeflask__line-highlight { - position: absolute; - top: 10px; - left: 0; - width: 100%; - height: ${LINE_HEIGHT}; - background: rgba(0,0,0,0.1); - z-index: 1; - } - - .codeflask__lines { - padding: 10px 4px; - font-size: 12px; - line-height: ${LINE_HEIGHT}; - font-family: 'Cousine', monospace; - position: absolute; - left: 0; - top: 0; - width: ${LINE_NUMBER_WIDTH}; - min-height: 100%; - text-align: right; - color: #999; - border-right: 1px solid #f8f8f8; - background-color: #fafafa; - z-index: 5; - } - - .codeflask__lines__line { - display: block; - } - - .codeflask.codeflask--has-line-numbers { - padding-left: ${LINE_NUMBER_WIDTH}; - } - - .codeflask.codeflask--has-line-numbers:before { - content: ''; - position: absolute; - left: 0; - top: 0; - width: ${LINE_NUMBER_WIDTH}; - height: 100%; - background: #eee; - z-index: 1; - } -`; - -function injectCss (css, styleName, parent) { - const CSS_ID = styleName || 'codeflask-style'; - const PARENT = parent || document.head; - - if (!css) { - return false - } - - if (document.getElementById(CSS_ID)) { - return true - } - - const style = document.createElement('style'); - - style.innerHTML = css; - style.id = CSS_ID; - PARENT.appendChild(style); - - return true -} - -const entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - '`': '`', - '=': '=' -}; - -function escapeHtml (string) { - return String(string).replace(/[&<>"'`=/]/g, function (s) { - return entityMap[s] - }) -} - -const selfClosingCharMap = { - '(': ')', - '[': ']', - '{': '}', - '<': '>', - "'": "'", - '"': '"' -}; - -class CodeFlask { - constructor (selectorOrElement, Prism, opts) { - if (!selectorOrElement) { - throw Error('CodeFlask expects 1st parameter to be an Element or a String selector') - } - - if (!Prism) { - throw Error('CodeFlask expects 2nd parameter to be the Prism peer dependency') - } - - if (!opts) { - throw Error('CodeFlask expects 3rd parameter to be an object containing options') - } - - if (selectorOrElement.nodeType) { - // If it is an element, assign it directly - this.editorRoot = selectorOrElement; - } else { - // If it is a selector, tries to find element - const editorRoot = document.querySelector(selectorOrElement); - - // If an element is found using this selector, - // assign this element as the root element - if (editorRoot) { - this.editorRoot = editorRoot; - } - } - - this.Prism = Prism; - this.opts = opts; - this.events = {}; - this.startEditor(); - } - - startEditor () { - const isCSSInjected = injectCss(editorCss, null, this.opts.styleParent); - - if (!isCSSInjected) { - throw Error('Failed to inject CodeFlask CSS.') - } - - // The order matters (pre > code). Don't change it - // or things are going to break. - this.createWrapper(); - this.createTextarea(); - this.createPre(); - this.createCode(); - - this.runOptions(); - this.listenTextarea(); - this.populateDefault(); - this.updateCode(this.code); - } - - createWrapper () { - this.code = this.editorRoot.innerHTML; - this.editorRoot.innerHTML = ''; - this.elWrapper = this.createElement('div', this.editorRoot); - this.elWrapper.classList.add('codeflask'); - } - - createTextarea () { - this.elTextarea = this.createElement('textarea', this.elWrapper); - this.elTextarea.classList.add('codeflask__textarea', 'codeflask__flatten'); - } - - createPre () { - this.elPre = this.createElement('pre', this.elWrapper); - this.elPre.classList.add('codeflask__pre', 'codeflask__flatten'); - } - - createCode () { - this.elCode = this.createElement('code', this.elPre); - this.elCode.classList.add('codeflask__code', `language-${this.opts.language || 'html'}`); - } - - createLineNumbers () { - this.elLineNumbers = this.createElement('div', this.elWrapper); - this.elLineNumbers.classList.add('codeflask__lines'); - this.setLineNumber(); - } - - createElement (elementTag, whereToAppend) { - const element = document.createElement(elementTag); - whereToAppend.appendChild(element); - - return element - } - - runOptions () { - this.opts.rtl = this.opts.rtl || false; - this.opts.tabSize = this.opts.tabSize || 2; - this.opts.enableAutocorrect = this.opts.enableAutocorrect || false; - this.opts.lineNumbers = this.opts.lineNumbers || false; - this.opts.defaultTheme = this.opts.defaultTheme !== false; - this.opts.areaId = this.opts.areaId || null; - this.opts.ariaLabelledby = this.opts.ariaLabelledby || null; - this.opts.readonly = this.opts.readonly || false; - this.opts.customEventListeners = this.opts.customEventListeners || {}; - this.opts.selfClosingCharacters = this.opts.selfClosingCharacters || ['(', '[', '{', '<', "'", '"']; - - // if handleTabs is not either true or false, make it true by default - if (typeof this.opts.handleTabs !== 'boolean') { - this.opts.handleTabs = true; - } - // if handleTabs is not either true or false, make it true by default - if (typeof this.opts.handleNewLineIndentation !== 'boolean') { - this.opts.handleNewLineIndentation = true; - } - - if (this.opts.rtl === true) { - this.elTextarea.setAttribute('dir', 'rtl'); - this.elPre.setAttribute('dir', 'rtl'); - } - - if (this.opts.enableAutocorrect === false) { - this.elTextarea.setAttribute('spellcheck', 'false'); - this.elTextarea.setAttribute('autocapitalize', 'off'); - this.elTextarea.setAttribute('autocomplete', 'off'); - this.elTextarea.setAttribute('autocorrect', 'off'); - } - - if (this.opts.lineNumbers) { - this.elWrapper.classList.add('codeflask--has-line-numbers'); - this.createLineNumbers(); - } - - if (this.opts.defaultTheme) { - injectCss(defaultCssTheme, 'theme-default', this.opts.styleParent); - } - - if (this.opts.areaId) { - this.elTextarea.setAttribute('id', this.opts.areaId); - } - - if (this.opts.ariaLabelledby) { - this.elTextarea.setAttribute('aria-labelledby', this.opts.ariaLabelledby); - } - - if (this.opts.readonly) { - this.enableReadonlyMode(); - } - } - - updateLineNumbersCount () { - let numberList = ''; - - for (let i = 1; i <= this.lineNumber; i++) { - numberList = numberList + `${i}`; - } - - this.elLineNumbers.innerHTML = numberList; - } - - listenTextarea () { - const customEventListeners = this.opts.customEventListeners; - for (const [eventName, func] of Object.entries(customEventListeners)) { - this.elTextarea.addEventListener(eventName, func); - } - - this.elTextarea.addEventListener('input', this.events.input = (e) => { - if (this.opts.readonly) { - return; - } - this.code = e.target.value; - this.elCode.innerHTML = escapeHtml(e.target.value); - this.highlight(); - setTimeout(() => { - this.runUpdate(); - this.setLineNumber(); - }, 1); - }); - - this.elTextarea.addEventListener('keydown', this.events.keydown = (e) => { - if (this.opts.readonly) { - return; - } - this.handleTabs(e); - this.handleBackspace(e); - this.handleSelfClosingCharacters(e); - this.handleNewLineIndentation(e); - }); - - this.elTextarea.addEventListener('scroll', this.events.scroll = (e) => { - this.elPre.style.transform = `translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`; - if (this.elLineNumbers) { - this.elLineNumbers.style.transform = `translate3d(0, -${e.target.scrollTop}px, 0)`; - this.elPre.style.width = `calc(100% - 40px + ${e.target.scrollLeft}px)`; - } - }); - } - - removeEventListeners () { - for (const [eventName, func] of Object.entries(customEventListeners)) { - this.elTextarea.removeEventListener(eventName, func); - } - for (const [eventName, func] of Object.entries(this.events)) { - this.elTextarea.removeEventListener(eventName, func); - } - } - - getSelectInfo () { - var input = this.elTextarea; - var selStartPos = input.selectionStart; - var selEndPos = input.selectionEnd; - var beforeSelection = input.value.substr(0, selStartPos); - var selectionVal = input.value.substring(selStartPos, selEndPos); - var afterSelection = input.value.substring(selEndPos); - return { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } - } - - handleTabs (e) { - if (!this.opts.handleTabs || e.key !== "Tab") { - return - } - e.preventDefault(); - - var input = this.elTextarea; - var inputVal = input.value; - var { selStartPos, selEndPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); - const indent = ' '.repeat(this.opts.tabSize); - - if (selStartPos !== selEndPos && selectionVal.length >= indent.length) { - var currentLineStart = selStartPos - beforeSelection.split('\n').pop().length; - var startIndentLen = indent.length; - var endIndentLen = indent.length; - - // Unindent - if (e.shiftKey) { - var currentLineStartStr = inputVal.substr(currentLineStart, indent.length); - // Line start whit indent - if (currentLineStartStr === indent) { - startIndentLen = -startIndentLen; - - if (currentLineStart > selStartPos) { - // Indent is in selection - selectionVal = selectionVal.substring(0, currentLineStart) + selectionVal.substring(currentLineStart + indent.length); - endIndentLen = 0; - } else if (currentLineStart === selStartPos) { - // Indent is in start of selection - startIndentLen = 0; - endIndentLen = 0; - selectionVal = selectionVal.substring(indent.length); - } else { - // Indent is before selection - endIndentLen = -endIndentLen; - beforeSelection = beforeSelection.substring(0, currentLineStart) + beforeSelection.substring(currentLineStart + indent.length); - } - } else { - startIndentLen = 0; - endIndentLen = 0; - } - - selectionVal = selectionVal.replace(new RegExp('\n' + indent.split('').join('\\'), 'g'), '\n'); - } else { - // Indent - beforeSelection = beforeSelection.substr(0, currentLineStart) + indent + beforeSelection.substring(currentLineStart, selStartPos); - selectionVal = selectionVal.replace(/\n/g, '\n' + indent); - } - - // Set new indented value - input.value = beforeSelection + selectionVal + afterSelection; - input.setSelectionRange(selStartPos + startIndentLen, selStartPos + selectionVal.length + endIndentLen); - } else { - const activeLineRegexp = new RegExp(`(\\n?)((?:${indent})*)([^\\n]*)$`); - if (e.shiftKey) { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent.slice(0, -1 * indent.length) + content - ); - if (newBeforeSelection !== beforeSelection) { - input.value = newBeforeSelection + afterSelection; - input.setSelectionRange(selStartPos - indent.length, selStartPos - indent.length); - } - } else { - const newBeforeSelection = beforeSelection.replace( - activeLineRegexp, - (_, maybeNewline, leadingIndent, content) => maybeNewline + leadingIndent + indent + content - ); - input.value = newBeforeSelection + afterSelection; - input.setSelectionRange(selStartPos + indent.length, selStartPos + indent.length); - } - } - - this.updateCode(input.value); - } - - handleBackspace (e) { - if (e.key !== "Backspace") { - return - } - - var { selStartPos, beforeSelection, selectionVal, afterSelection } = this.getSelectInfo(); - if (selectionVal !== '') { - return - } - - if (!beforeSelection.match(/\n( ){1,}$/)) { - return - } - - e.preventDefault(); - const newBeforeSelection = beforeSelection.replace(/ $/, ''); - const input = this.elTextarea; - input.value = newBeforeSelection + afterSelection; - this.updateCode(input.value); - input.setSelectionRange(selStartPos - 2, selStartPos - 2); - } - - handleSelfClosingCharacters (e) { - if (!this.opts.selfClosingCharacters.length) return - const openChars = this.opts.selfClosingCharacters; - const closeChars = this.opts.selfClosingCharacters.map(c => selfClosingCharMap[c]); - - if (!openChars.includes(e.key) && !closeChars.includes(e.key)) { - return - } - - this.closeCharacter(e.key); - } - - setLineNumber () { - this.lineNumber = this.code.split('\n').length; - - if (this.opts.lineNumbers) { - this.updateLineNumbersCount(); - } - } - - handleNewLineIndentation (e) { - if (!this.opts.handleNewLineIndentation || e.keyCode !== 13) { - return - } - - e.preventDefault(); - var input = this.elTextarea; - var inputVal = input.value; - var { selStartPos, beforeSelection, afterSelection } = this.getSelectInfo(); - - var lineStart = inputVal.lastIndexOf('\n', selStartPos - 1); - var spaceLast = lineStart + inputVal.slice(lineStart + 1).search(/[^ ]|$/); - var indent = (spaceLast > lineStart) ? (spaceLast - lineStart) : 0; - var newCode = beforeSelection + '\n' + ' '.repeat(indent) + afterSelection; - - input.value = newCode; - input.selectionStart = selStartPos + indent + 1; - input.selectionEnd = selStartPos + indent + 1; - - this.updateCode(input.value); - } - - closeCharacter (char) { - const selectionStart = this.elTextarea.selectionStart; - const selectionEnd = this.elTextarea.selectionEnd; - - if (!this.skipCloseChar(char)) { - let closeChar = char; - switch (char) { - case '(': - closeChar = String.fromCharCode(char.charCodeAt() + 1); - break - case '<': - case '{': - case '[': - closeChar = String.fromCharCode(char.charCodeAt() + 2); - break - } - const selectionText = this.code.substring(selectionStart, selectionEnd); - const newCode = `${this.code.substring(0, selectionStart)}${selectionText}${closeChar}${this.code.substring(selectionEnd)}`; - this.updateCode(newCode); - } else { - const skipChar = this.code.substr(selectionEnd, 1) === char; - const newSelectionEnd = skipChar ? selectionEnd + 1 : selectionEnd; - const closeChar = !skipChar && ['\'', '"'].includes(char) ? char : ''; - const newCode = `${this.code.substring(0, selectionStart)}${closeChar}${this.code.substring(newSelectionEnd)}`; - this.updateCode(newCode); - this.elTextarea.selectionEnd = ++this.elTextarea.selectionStart; - } - - this.elTextarea.selectionEnd = selectionStart; - } - - skipCloseChar (char) { - const selectionStart = this.elTextarea.selectionStart; - const selectionEnd = this.elTextarea.selectionEnd; - const hasSelection = Math.abs(selectionEnd - selectionStart) > 0; - return [')', '}', ']', '>'].includes(char) || (['\'', '"'].includes(char) && !hasSelection) - } - - updateCode (newCode) { - this.code = newCode; - this.elTextarea.value = newCode; - this.elCode.innerHTML = escapeHtml(newCode); - this.highlight(); - this.setLineNumber(); - setTimeout(this.runUpdate.bind(this), 1); - } - - updateLanguage (newLanguage) { - const oldLanguage = this.opts.language; - this.elCode.classList.remove(`language-${oldLanguage}`); - this.elCode.classList.add(`language-${newLanguage}`); - this.opts.language = newLanguage; - this.highlight(); - } - - addLanguage (name, options) { - this.Prism.languages[name] = options; - } - - populateDefault () { - this.updateCode(this.code); - } - - highlight () { - this.Prism.highlightElement(this.elCode, false); - } - - highlightLines (lineSpec) { - /* This requires the "line-highlight" plugin in PrismJS - Examples - 5: The 5th line - 1-5: Lines 1 through 5 - 1,4: Line 1 and line 4 - 1-2, 5, 9-20: Lines 1 through 2, line 5, lines 9 through 20 - Pass empty string to remove highlighting from all lines - */ - this.elPre.setAttribute('data-line', lineSpec); - this.highlight(); - } - - onUpdate (callback) { - if (callback && {}.toString.call(callback) !== '[object Function]') { - throw Error('CodeFlask expects callback of type Function') - } - - this.updateCallBack = callback; - } - - getCode () { - return this.code - } - - runUpdate () { - if (this.updateCallBack) { - this.updateCallBack(this.code); - } - } - - enableReadonlyMode () { - this.elTextarea.setAttribute('readonly', true); - } - - disableReadonlyMode () { - this.elTextarea.removeAttribute('readonly'); - } -} - -export { CodeFlask as default }; +const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",a=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,a.appendChild(i),!0}const o={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return o[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:a,beforeSelection:i,selectionVal:o,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==a&&o.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(o=o.substring(0,h)+o.substring(h+r.length),d=0):h===s?(c=0,d=0,o=o.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),o=o.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),o=o.replace(/\n/g,"\n"+r);t.value=i+o+l,t.setSelectionRange(s+c,s+o.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:a}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),o=this.elTextarea;o.value=i+a,this.updateCode(o.value),o.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:a,afterSelection:i}=this.getSelectInfo(),o=n.lastIndexOf("\n",s-1),l=o+n.slice(o+1).search(/[^ ]|$/),r=l>o?l-o:0,h=a+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,a=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",o=`${this.code.substring(0,t)}${i}${this.code.substring(a)}`;this.updateCode(o),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const a=this.code.substring(t,n),i=`${this.code.substring(0,t)}${a}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; diff --git a/package.json b/package.json index 8b9aa36e..7c445434 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.0", + "version": "2.1.1", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From 825c90b924f10a338cbf886ee5ccfa92de3bb12b Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 31 Aug 2022 17:35:44 -0400 Subject: [PATCH 20/25] add methods i added to the type definitino --- index.d.ts | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index b91ea184..e79f1adf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -36,4 +36,8 @@ export default class CodeFlask { disableReadonlyMode(): void enableReadonlyMode(): void + + removeEventListeners(): void + highlight(): void + highlightLines(lineSpec: string): void } diff --git a/package.json b/package.json index 7c445434..989296b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.1", + "version": "2.1.2", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From a6739438e64b0b7c47bd98ca7125bf438213198a Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 31 Aug 2022 17:55:10 -0400 Subject: [PATCH 21/25] fix type signatures again --- index.d.ts | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index e79f1adf..d6ba337c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -7,7 +7,7 @@ export type LanguageDefinition = { } export type EventListeners = { - [index: string]: (UIEvent) => void + [index: string]: (e: UIEvent) => void } export interface CodeFlaskOptions { @@ -25,7 +25,7 @@ export interface CodeFlaskOptions { } export default class CodeFlask { - constructor(selectorOrElement: Element | string, opts: CodeFlaskOptions) + constructor(selectorOrElement: Element | string, Prism: any, opts: CodeFlaskOptions) updateCode(newCode: string): void updateLanguage(newLanguage: string): void diff --git a/package.json b/package.json index 989296b8..46b69fe9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.2", + "version": "2.1.3", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From dfc163a44c1c966cd02f89d15cd9ad2b020b5170 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 1 Sep 2022 15:38:30 -0400 Subject: [PATCH 22/25] fix type signatures again --- index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index d6ba337c..80c5d683 100644 --- a/index.d.ts +++ b/index.d.ts @@ -6,9 +6,9 @@ export type LanguageDefinition = { [token: string]: prism.LanguageDefinition | RegExp } -export type EventListeners = { - [index: string]: (e: UIEvent) => void -} +export type EventListeners = Partial<{ + [K in keyof WindowEventMap]: (e: WindowEventMap[K]) => void +}> export interface CodeFlaskOptions { language?: string From 923ffb16b02e2447cd45b9513bf11d55840e9fa7 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Thu, 1 Sep 2022 15:38:42 -0400 Subject: [PATCH 23/25] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46b69fe9..51b3f2a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.3", + "version": "2.1.4", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", From 633935f319a94decb16863892a095786594b448e Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Wed, 14 Sep 2022 19:22:23 -0400 Subject: [PATCH 24/25] fix bug with cmd+] --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- package.json | 2 +- src/codeflask.js | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index 15d1b07d..d75990ba 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,o;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(o=(o=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:o,beforeSelection:i,selectionVal:a,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==o&&a.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(a=a.substring(0,h)+a.substring(h+r.length),d=0):h===s?(c=0,d=0,a=a.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),a=a.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),a=a.replace(/\n/g,"\n"+r);t.value=i+a+l,t.setSelectionRange(s+c,s+a.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:o}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),a=this.elTextarea;a.value=i+o,this.updateCode(a.value),a.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:o,afterSelection:i}=this.getSelectInfo(),a=n.lastIndexOf("\n",s-1),l=a+n.slice(a+1).search(/[^ ]|$/),r=l>a?l-a:0,h=o+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${i}${this.code.substring(o)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const o=this.code.substring(t,n),i=`${this.code.substring(0,t)}${o}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,o;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(o=(o=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:o,beforeSelection:i,selectionVal:a,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==o&&a.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(a=a.substring(0,h)+a.substring(h+r.length),d=0):h===s?(c=0,d=0,a=a.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),a=a.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),a=a.replace(/\n/g,"\n"+r);t.value=i+a+l,t.setSelectionRange(s+c,s+a.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:o}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),a=this.elTextarea;a.value=i+o,this.updateCode(a.value),a.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:o,afterSelection:i}=this.getSelectInfo(),a=n.lastIndexOf("\n",s-1),l=a+n.slice(a+1).search(/[^ ]|$/),r=l>a?l-a:0,h=o+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${i}${this.code.substring(o)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const o=this.code.substring(t,n),i=`${this.code.substring(0,t)}${o}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index 372a30dd..ea4e10e7 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",a=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,a.appendChild(i),!0}const o={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return o[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:a,beforeSelection:i,selectionVal:o,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==a&&o.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(o=o.substring(0,h)+o.substring(h+r.length),d=0):h===s?(c=0,d=0,o=o.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),o=o.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),o=o.replace(/\n/g,"\n"+r);t.value=i+o+l,t.setSelectionRange(s+c,s+o.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:a}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),o=this.elTextarea;o.value=i+a,this.updateCode(o.value),o.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&this.closeCharacter(e.key)}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:a,afterSelection:i}=this.getSelectInfo(),o=n.lastIndexOf("\n",s-1),l=o+n.slice(o+1).search(/[^ ]|$/),r=l>o?l-o:0,h=a+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,a=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",o=`${this.code.substring(0,t)}${i}${this.code.substring(a)}`;this.updateCode(o),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const a=this.code.substring(t,n),i=`${this.code.substring(0,t)}${a}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; +const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",a=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,a.appendChild(i),!0}const o={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return o[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:a,beforeSelection:i,selectionVal:o,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==a&&o.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(o=o.substring(0,h)+o.substring(h+r.length),d=0):h===s?(c=0,d=0,o=o.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),o=o.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),o=o.replace(/\n/g,"\n"+r);t.value=i+o+l,t.setSelectionRange(s+c,s+o.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:a}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),o=this.elTextarea;o.value=i+a,this.updateCode(o.value),o.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:a,afterSelection:i}=this.getSelectInfo(),o=n.lastIndexOf("\n",s-1),l=o+n.slice(o+1).search(/[^ ]|$/),r=l>o?l-o:0,h=a+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,a=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",o=`${this.code.substring(0,t)}${i}${this.code.substring(a)}`;this.updateCode(o),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const a=this.code.substring(t,n),i=`${this.code.substring(0,t)}${a}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; diff --git a/package.json b/package.json index 51b3f2a6..bbc1d094 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.4", + "version": "2.1.5", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/codeflask.js b/src/codeflask.js index 5a279221..26c5ec41 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -330,6 +330,10 @@ export default class CodeFlask { return } + if (e.metaKey || e.ctrlKey) { + return + } + this.closeCharacter(e.key) } From 4a898842c39cfafc343a5c59828db41dcf2f1efb Mon Sep 17 00:00:00 2001 From: Andrew Carlson <2yinyang2@gmail.com> Date: Fri, 16 Sep 2022 17:37:44 -0400 Subject: [PATCH 25/25] expose blur method to unfocus the editor --- build/codeflask.min.js | 2 +- build/codeflask.module.js | 2 +- index.d.ts | 1 + package.json | 2 +- src/codeflask.js | 4 ++++ 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/build/codeflask.min.js b/build/codeflask.min.js index d75990ba..b8715681 100644 --- a/build/codeflask.min.js +++ b/build/codeflask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,o;const i=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(o=(o=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function a(e,t,n){const s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,o.appendChild(i),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!a(i,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&a("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:o,beforeSelection:i,selectionVal:a,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==o&&a.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(a=a.substring(0,h)+a.substring(h+r.length),d=0):h===s?(c=0,d=0,a=a.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),a=a.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),a=a.replace(/\n/g,"\n"+r);t.value=i+a+l,t.setSelectionRange(s+c,s+a.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:o}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),a=this.elTextarea;a.value=i+o,this.updateCode(a.value),a.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:o,afterSelection:i}=this.getSelectInfo(),a=n.lastIndexOf("\n",s-1),l=a+n.slice(a+1).search(/[^ ]|$/),r=l>a?l-a:0,h=o+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,o=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",a=`${this.code.substring(0,t)}${i}${this.code.substring(o)}`;this.updateCode(a),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const o=this.code.substring(t,n),i=`${this.code.substring(0,t)}${o}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CodeFlask=t()}(this,(function(){"use strict";const e="#fff";const t='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var n,s,o;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${n="caret-color",s="#000",("undefined"!=typeof CSS?CSS.supports(n,s):"undefined"!=typeof document&&(o=(o=n).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+o.substr(1)in document.body.style)?e:"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${t};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${t};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",o=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const a=document.createElement("style");return a.innerHTML=e,a.id=s,o.appendChild(a),!0}const l={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function r(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return l[e]}))}const h={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};return class{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=r(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:o,beforeSelection:a,selectionVal:i,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==o&&i.length>=r.length){var h=s-a.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(i=i.substring(0,h)+i.substring(h+r.length),d=0):h===s?(c=0,d=0,i=i.substring(r.length)):(d=-d,a=a.substring(0,h)+a.substring(h+r.length))):(c=0,d=0),i=i.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else a=a.substr(0,h)+r+a.substring(h,s),i=i.replace(/\n/g,"\n"+r);t.value=a+i+l,t.setSelectionRange(s+c,s+i.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=a.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==a&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=a.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:o}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const a=n.replace(/ $/,""),i=this.elTextarea;i.value=a+o,this.updateCode(i.value),i.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>h[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:o,afterSelection:a}=this.getSelectInfo(),i=n.lastIndexOf("\n",s-1),l=i+n.slice(i+1).search(/[^ ]|$/),r=l>i?l-i:0,h=o+"\n"+" ".repeat(r)+a;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,o=s?n+1:n,a=!s&&["'",'"'].includes(e)?e:"",i=`${this.code.substring(0,t)}${a}${this.code.substring(o)}`;this.updateCode(i),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const o=this.code.substring(t,n),a=`${this.code.substring(0,t)}${o}${s}${this.code.substring(n)}`;this.updateCode(a)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=r(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}blur(){this.elTextarea.blur()}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}})); diff --git a/build/codeflask.module.js b/build/codeflask.module.js index ea4e10e7..ca4b7c46 100644 --- a/build/codeflask.module.js +++ b/build/codeflask.module.js @@ -1 +1 @@ -const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",a=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,a.appendChild(i),!0}const o={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return o[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:a,beforeSelection:i,selectionVal:o,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==a&&o.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(o=o.substring(0,h)+o.substring(h+r.length),d=0):h===s?(c=0,d=0,o=o.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),o=o.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),o=o.replace(/\n/g,"\n"+r);t.value=i+o+l,t.setSelectionRange(s+c,s+o.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:a}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),o=this.elTextarea;o.value=i+a,this.updateCode(o.value),o.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:a,afterSelection:i}=this.getSelectInfo(),o=n.lastIndexOf("\n",s-1),l=o+n.slice(o+1).search(/[^ ]|$/),r=l>o?l-o:0,h=a+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,a=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",o=`${this.code.substring(0,t)}${i}${this.code.substring(a)}`;this.updateCode(o),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const a=this.code.substring(t,n),i=`${this.code.substring(0,t)}${a}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; +const e='"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace';var t,n,s;const a=`\n .codeflask {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .codeflask, .codeflask * {\n box-sizing: border-box;\n }\n\n .codeflask__pre {\n pointer-events: none;\n z-index: 3;\n overflow: hidden;\n }\n\n .codeflask__textarea {\n background: none;\n border: none;\n color: ${t="caret-color",n="#000",("undefined"!=typeof CSS?CSS.supports(t,n):"undefined"!=typeof document&&(s=(s=t).split("-").filter((e=>!!e)).map((e=>e[0].toUpperCase()+e.substr(1))).join(""))[0].toLowerCase()+s.substr(1)in document.body.style)?"#fff":"#ccc"};\n z-index: 1;\n resize: none;\n font-family: ${e};\n -webkit-appearance: pre;\n caret-color: #111;\n z-index: 2;\n width: 100%;\n height: 100%;\n }\n\n .codeflask--has-line-numbers .codeflask__textarea {\n width: calc(100% - 40px);\n }\n\n .codeflask__code {\n display: block;\n font-family: ${e};\n overflow: hidden;\n }\n\n .codeflask__flatten {\n padding: 10px;\n font-size: 16px;\n line-height: 20px;\n white-space: pre;\n position: absolute;\n top: 0;\n left: 0;\n overflow: auto;\n margin: 0 !important;\n outline: none;\n text-align: left;\n }\n\n .codeflask--has-line-numbers .codeflask__flatten {\n width: calc(100% - 40px);\n left: 40px;\n }\n\n .codeflask__line-highlight {\n position: absolute;\n top: 10px;\n left: 0;\n width: 100%;\n height: 20px;\n background: rgba(0,0,0,0.1);\n z-index: 1;\n }\n\n .codeflask__lines {\n padding: 10px 4px;\n font-size: 12px;\n line-height: 20px;\n font-family: 'Cousine', monospace;\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n min-height: 100%;\n text-align: right;\n color: #999;\n border-right: 1px solid #f8f8f8;\n background-color: #fafafa;\n z-index: 5;\n }\n\n .codeflask__lines__line {\n display: block;\n }\n\n .codeflask.codeflask--has-line-numbers {\n padding-left: 40px;\n }\n\n .codeflask.codeflask--has-line-numbers:before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 40px;\n height: 100%;\n background: #eee;\n z-index: 1;\n }\n`;function i(e,t,n){const s=t||"codeflask-style",a=n||document.head;if(!e)return!1;if(document.getElementById(s))return!0;const i=document.createElement("style");return i.innerHTML=e,i.id=s,a.appendChild(i),!0}const o={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function l(e){return String(e).replace(/[&<>"'`=/]/g,(function(e){return o[e]}))}const r={"(":")","[":"]","{":"}","<":">","'":"'",'"':'"'};class h{constructor(e,t,n){if(!e)throw Error("CodeFlask expects 1st parameter to be an Element or a String selector");if(!t)throw Error("CodeFlask expects 2nd parameter to be the Prism peer dependency");if(!n)throw Error("CodeFlask expects 3rd parameter to be an object containing options");if(e.nodeType)this.editorRoot=e;else{const t=document.querySelector(e);t&&(this.editorRoot=t)}this.Prism=t,this.opts=n,this.events={},this.startEditor()}startEditor(){if(!i(a,null,this.opts.styleParent))throw Error("Failed to inject CodeFlask CSS.");this.createWrapper(),this.createTextarea(),this.createPre(),this.createCode(),this.runOptions(),this.listenTextarea(),this.populateDefault(),this.updateCode(this.code)}createWrapper(){this.code=this.editorRoot.innerHTML,this.editorRoot.innerHTML="",this.elWrapper=this.createElement("div",this.editorRoot),this.elWrapper.classList.add("codeflask")}createTextarea(){this.elTextarea=this.createElement("textarea",this.elWrapper),this.elTextarea.classList.add("codeflask__textarea","codeflask__flatten")}createPre(){this.elPre=this.createElement("pre",this.elWrapper),this.elPre.classList.add("codeflask__pre","codeflask__flatten")}createCode(){this.elCode=this.createElement("code",this.elPre),this.elCode.classList.add("codeflask__code",`language-${this.opts.language||"html"}`)}createLineNumbers(){this.elLineNumbers=this.createElement("div",this.elWrapper),this.elLineNumbers.classList.add("codeflask__lines"),this.setLineNumber()}createElement(e,t){const n=document.createElement(e);return t.appendChild(n),n}runOptions(){this.opts.rtl=this.opts.rtl||!1,this.opts.tabSize=this.opts.tabSize||2,this.opts.enableAutocorrect=this.opts.enableAutocorrect||!1,this.opts.lineNumbers=this.opts.lineNumbers||!1,this.opts.defaultTheme=!1!==this.opts.defaultTheme,this.opts.areaId=this.opts.areaId||null,this.opts.ariaLabelledby=this.opts.ariaLabelledby||null,this.opts.readonly=this.opts.readonly||!1,this.opts.customEventListeners=this.opts.customEventListeners||{},this.opts.selfClosingCharacters=this.opts.selfClosingCharacters||["(","[","{","<","'",'"'],"boolean"!=typeof this.opts.handleTabs&&(this.opts.handleTabs=!0),"boolean"!=typeof this.opts.handleNewLineIndentation&&(this.opts.handleNewLineIndentation=!0),!0===this.opts.rtl&&(this.elTextarea.setAttribute("dir","rtl"),this.elPre.setAttribute("dir","rtl")),!1===this.opts.enableAutocorrect&&(this.elTextarea.setAttribute("spellcheck","false"),this.elTextarea.setAttribute("autocapitalize","off"),this.elTextarea.setAttribute("autocomplete","off"),this.elTextarea.setAttribute("autocorrect","off")),this.opts.lineNumbers&&(this.elWrapper.classList.add("codeflask--has-line-numbers"),this.createLineNumbers()),this.opts.defaultTheme&&i("\n.codeflask {\n background: #fff;\n color: #4f559c;\n}\n\n.codeflask .token.punctuation {\n color: #4a4a4a;\n}\n\n.codeflask .token.keyword {\n color: #8500ff;\n}\n\n.codeflask .token.operator {\n color: #ff5598;\n}\n\n.codeflask .token.string {\n color: #41ad8f;\n}\n\n.codeflask .token.comment {\n color: #9badb7;\n}\n\n.codeflask .token.function {\n color: #8500ff;\n}\n\n.codeflask .token.boolean {\n color: #8500ff;\n}\n\n.codeflask .token.number {\n color: #8500ff;\n}\n\n.codeflask .token.selector {\n color: #8500ff;\n}\n\n.codeflask .token.property {\n color: #8500ff;\n}\n\n.codeflask .token.tag {\n color: #8500ff;\n}\n\n.codeflask .token.attr-value {\n color: #8500ff;\n}\n","theme-default",this.opts.styleParent),this.opts.areaId&&this.elTextarea.setAttribute("id",this.opts.areaId),this.opts.ariaLabelledby&&this.elTextarea.setAttribute("aria-labelledby",this.opts.ariaLabelledby),this.opts.readonly&&this.enableReadonlyMode()}updateLineNumbersCount(){let e="";for(let t=1;t<=this.lineNumber;t++)e+=`${t}`;this.elLineNumbers.innerHTML=e}listenTextarea(){const e=this.opts.customEventListeners;for(const[t,n]of Object.entries(e))this.elTextarea.addEventListener(t,n);this.elTextarea.addEventListener("input",this.events.input=e=>{this.opts.readonly||(this.code=e.target.value,this.elCode.innerHTML=l(e.target.value),this.highlight(),setTimeout((()=>{this.runUpdate(),this.setLineNumber()}),1))}),this.elTextarea.addEventListener("keydown",this.events.keydown=e=>{this.opts.readonly||(this.handleTabs(e),this.handleBackspace(e),this.handleSelfClosingCharacters(e),this.handleNewLineIndentation(e))}),this.elTextarea.addEventListener("scroll",this.events.scroll=e=>{this.elPre.style.transform=`translate3d(-${e.target.scrollLeft}px, -${e.target.scrollTop}px, 0)`,this.elLineNumbers&&(this.elLineNumbers.style.transform=`translate3d(0, -${e.target.scrollTop}px, 0)`,this.elPre.style.width=`calc(100% - 40px + ${e.target.scrollLeft}px)`)})}removeEventListeners(){for(const[e,t]of Object.entries(customEventListeners))this.elTextarea.removeEventListener(e,t);for(const[e,t]of Object.entries(this.events))this.elTextarea.removeEventListener(e,t)}getSelectInfo(){var e=this.elTextarea,t=e.selectionStart,n=e.selectionEnd;return{selStartPos:t,selEndPos:n,beforeSelection:e.value.substr(0,t),selectionVal:e.value.substring(t,n),afterSelection:e.value.substring(n)}}handleTabs(e){if(!this.opts.handleTabs||"Tab"!==e.key)return;e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,selEndPos:a,beforeSelection:i,selectionVal:o,afterSelection:l}=this.getSelectInfo();const r=" ".repeat(this.opts.tabSize);if(s!==a&&o.length>=r.length){var h=s-i.split("\n").pop().length,c=r.length,d=r.length;if(e.shiftKey)n.substr(h,r.length)===r?(c=-c,h>s?(o=o.substring(0,h)+o.substring(h+r.length),d=0):h===s?(c=0,d=0,o=o.substring(r.length)):(d=-d,i=i.substring(0,h)+i.substring(h+r.length))):(c=0,d=0),o=o.replace(new RegExp("\n"+r.split("").join("\\"),"g"),"\n");else i=i.substr(0,h)+r+i.substring(h,s),o=o.replace(/\n/g,"\n"+r);t.value=i+o+l,t.setSelectionRange(s+c,s+o.length+d)}else{const n=new RegExp(`(\\n?)((?:${r})*)([^\\n]*)$`);if(e.shiftKey){const e=i.replace(n,((e,t,n,s)=>t+n.slice(0,-1*r.length)+s));e!==i&&(t.value=e+l,t.setSelectionRange(s-r.length,s-r.length))}else{const e=i.replace(n,((e,t,n,s)=>t+n+r+s));t.value=e+l,t.setSelectionRange(s+r.length,s+r.length)}}this.updateCode(t.value)}handleBackspace(e){if("Backspace"!==e.key)return;var{selStartPos:t,beforeSelection:n,selectionVal:s,afterSelection:a}=this.getSelectInfo();if(""!==s)return;if(!n.match(/\n( ){1,}$/))return;e.preventDefault();const i=n.replace(/ $/,""),o=this.elTextarea;o.value=i+a,this.updateCode(o.value),o.setSelectionRange(t-2,t-2)}handleSelfClosingCharacters(e){if(!this.opts.selfClosingCharacters.length)return;const t=this.opts.selfClosingCharacters,n=this.opts.selfClosingCharacters.map((e=>r[e]));(t.includes(e.key)||n.includes(e.key))&&(e.metaKey||e.ctrlKey||this.closeCharacter(e.key))}setLineNumber(){this.lineNumber=this.code.split("\n").length,this.opts.lineNumbers&&this.updateLineNumbersCount()}handleNewLineIndentation(e){if(this.opts.handleNewLineIndentation&&13===e.keyCode){e.preventDefault();var t=this.elTextarea,n=t.value,{selStartPos:s,beforeSelection:a,afterSelection:i}=this.getSelectInfo(),o=n.lastIndexOf("\n",s-1),l=o+n.slice(o+1).search(/[^ ]|$/),r=l>o?l-o:0,h=a+"\n"+" ".repeat(r)+i;t.value=h,t.selectionStart=s+r+1,t.selectionEnd=s+r+1,this.updateCode(t.value)}}closeCharacter(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd;if(this.skipCloseChar(e)){const s=this.code.substr(n,1)===e,a=s?n+1:n,i=!s&&["'",'"'].includes(e)?e:"",o=`${this.code.substring(0,t)}${i}${this.code.substring(a)}`;this.updateCode(o),this.elTextarea.selectionEnd=++this.elTextarea.selectionStart}else{let s=e;switch(e){case"(":s=String.fromCharCode(e.charCodeAt()+1);break;case"<":case"{":case"[":s=String.fromCharCode(e.charCodeAt()+2)}const a=this.code.substring(t,n),i=`${this.code.substring(0,t)}${a}${s}${this.code.substring(n)}`;this.updateCode(i)}this.elTextarea.selectionEnd=t}skipCloseChar(e){const t=this.elTextarea.selectionStart,n=this.elTextarea.selectionEnd,s=Math.abs(n-t)>0;return[")","}","]",">"].includes(e)||["'",'"'].includes(e)&&!s}updateCode(e){this.code=e,this.elTextarea.value=e,this.elCode.innerHTML=l(e),this.highlight(),this.setLineNumber(),setTimeout(this.runUpdate.bind(this),1)}updateLanguage(e){const t=this.opts.language;this.elCode.classList.remove(`language-${t}`),this.elCode.classList.add(`language-${e}`),this.opts.language=e,this.highlight()}addLanguage(e,t){this.Prism.languages[e]=t}populateDefault(){this.updateCode(this.code)}blur(){this.elTextarea.blur()}highlight(){this.Prism.highlightElement(this.elCode,!1)}highlightLines(e){this.elPre.setAttribute("data-line",e),this.highlight()}onUpdate(e){if(e&&"[object Function]"!=={}.toString.call(e))throw Error("CodeFlask expects callback of type Function");this.updateCallBack=e}getCode(){return this.code}runUpdate(){this.updateCallBack&&this.updateCallBack(this.code)}enableReadonlyMode(){this.elTextarea.setAttribute("readonly",!0)}disableReadonlyMode(){this.elTextarea.removeAttribute("readonly")}}export{h as default}; diff --git a/index.d.ts b/index.d.ts index 80c5d683..4dd1f0cb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -38,6 +38,7 @@ export default class CodeFlask { enableReadonlyMode(): void removeEventListeners(): void + blur(): void highlight(): void highlightLines(lineSpec: string): void } diff --git a/package.json b/package.json index bbc1d094..bee7609f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@acarl005/codeflask", - "version": "2.1.5", + "version": "2.1.6", "description": "A micro code-editor for awesome web pages", "main": "build/codeflask.min.js", "module": "build/codeflask.module.js", diff --git a/src/codeflask.js b/src/codeflask.js index 26c5ec41..59c9d819 100644 --- a/src/codeflask.js +++ b/src/codeflask.js @@ -430,6 +430,10 @@ export default class CodeFlask { this.updateCode(this.code) } + blur () { + this.elTextarea.blur() + } + highlight () { this.Prism.highlightElement(this.elCode, false) }