@webcoder49/code-input 1.5.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -8
- package/code-input.css +19 -4
- package/code-input.d.ts +242 -0
- package/code-input.js +366 -81
- package/code-input.min.css +1 -1
- package/code-input.min.js +1 -1
- package/package.json +1 -1
- package/plugins/autocomplete.js +2 -3
- package/plugins/autocomplete.min.js +1 -1
- package/plugins/autodetect.js +2 -3
- package/plugins/autodetect.min.js +1 -1
- package/plugins/debounce-update.js +1 -1
- package/plugins/debounce-update.min.js +1 -1
- package/plugins/indent.js +1 -1
- package/plugins/indent.min.js +1 -1
- package/plugins/special-chars.js +4 -5
- package/plugins/special-chars.min.js +1 -1
- package/plugins/test.js +5 -6
- package/plugins/test.min.js +1 -1
package/code-input.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
code-input{position:relative;top:0;left:0;display:block;overflow:hidden;
|
|
1
|
+
code-input{position:relative;top:0;left:0;display:block;overflow:hidden;margin:8px;--padding:16px;height:250px;font-size:normal;font-family:monospace;line-height:1.5;tab-size:2;caret-color:#a9a9a9;white-space:pre;padding:0!important}code-input textarea,code-input.code-input_pre-element-styled pre,code-input:not(.code-input_pre-element-styled) pre code{margin:0!important;padding:var(--padding,16px)!important;border:0;width:calc(100% - var(--padding,16px) * 2);height:calc(100% - var(--padding,16px) * 2)}code-input:not(.code-input_loaded){margin:0!important;margin-bottom:calc(-1 * var(--padding,16px))!important;padding:var(--padding,16px)!important;border:0}code-input.code-input_pre-element-styled pre code,code-input:not(.code-input_pre-element-styled) pre{margin:0!important;padding:0!important;width:100%;height:100%}code-input pre,code-input pre *,code-input textarea{font-size:inherit!important;font-family:inherit!important;line-height:inherit!important;tab-size:inherit!important}code-input pre,code-input textarea{position:absolute;top:0;left:0}code-input textarea{z-index:1}code-input pre{z-index:0}code-input:not(.code-input_loaded) pre,code-input:not(.code-input_loaded) textarea{opacity:0}code-input:not(.code-input_loaded)::after{color:#ccc}code-input textarea{color:transparent;background:0 0;caret-color:inherit!important}code-input pre,code-input textarea{overflow:auto!important;white-space:inherit;word-spacing:normal;word-break:normal;word-wrap:normal}code-input textarea{resize:none;outline:0!important}code-input:not(.code-input_registered)::after{content:"Use codeInput.registerTemplate to set up.";display:block;color:grey}
|
package/code-input.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var codeInput={observedAttributes:["value","placeholder","lang","template"],textareaSyncAttributes:["value","name","required","minlength","maxlength","min","max","type","pattern"],textareaSyncEvents:["change","selectionchange","invalid","input"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`Template for "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue){for(let c in codeInput.templateNotYetRegisteredQueue[a])elem=codeInput.templateNotYetRegisteredQueue[a][c],elem.template=b,elem.setup();console.log(`code-input: template: Added existing elements with template ${a}`)}if(null==codeInput.defaultTemplate){if(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue)for(let a in codeInput.templateNotYetRegisteredQueue[void 0])elem=codeInput.templateNotYetRegisteredQueue[void 0][a],elem.template=b,elem.setup();console.log(`code-input: template: Set template ${a} as default`)}console.log(`code-input: template: Created template ${a}`)},templates:{custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}},prism(a,b=[]){return{includeCodeInputInHighlightFunc:!1,highlight:a.highlightElement,preElementStyled:!0,isCode:!0,plugins:b}},hljs(a,b=[]){return{includeCodeInputInHighlightFunc:!1,highlight:a.highlightElement,preElementStyled:!1,isCode:!0,plugins:b}},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)}},plugins:{},Plugin:class{constructor(){console.log("code-input: plugin: Created plugin"),codeInput.observedAttributes=codeInput.observedAttributes.concat(self.observedAttributes)}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}observedAttributes=[]},CodeInput:class extends HTMLElement{constructor(){super()}boundEventCallbacks={};pluginEvt(a,b){for(let c in this.template.plugins){let d=this.template.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}update(a){if(!this.ignoreValueUpdate){this.ignoreValueUpdate=!0,this.value=a,this.ignoreValueUpdate=!1,this.querySelector("textarea").value!=a&&(this.querySelector("textarea").value=a);let b=this.querySelector("pre code");"\n"==a[a.length-1]&&(a+=" "),b.innerHTML=this.escapeHtml(a),this.pluginEvt("beforeHighlight"),this.template.includeCodeInputInHighlightFunc?this.template.highlight(b,this):this.template.highlight(b),this.pluginEvt("afterHighlight")}}syncScroll(){let a=this.querySelector("textarea"),b=this.template.preElementStyled?this.querySelector("pre"):this.querySelector("pre code");b.scrollTop=a.scrollTop,b.scrollLeft=a.scrollLeft}escapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){this.classList.add("code-input_registered"),this.template.preElementStyled&&this.classList.add("code-input_pre-element-styled"),this.pluginEvt("beforeElementsAdded");let a=this.getAttribute("lang"),b=this.getAttribute("placeholder")||this.getAttribute("lang")||"",c=this.value||this.innerHTML||"";this.innerHTML="";let d=document.createElement("textarea");d.placeholder=b,d.value=c,d.setAttribute("spellcheck","false"),codeInput.textareaSyncAttributes.forEach(a=>{this.hasAttribute(a)&&d.setAttribute(a,this.getAttribute(a))}),d.addEventListener("input",()=>{d.parentElement.update(d.value),d.parentElement.sync_scroll()}),d.addEventListener("scroll",()=>d.parentElement.sync_scroll()),this.append(d);let e=document.createElement("code"),f=document.createElement("pre");f.setAttribute("aria-hidden","true"),f.append(e),this.append(f),this.template.isCode&&a!=null&&""!=a&&e.classList.add("language-"+a),this.pluginEvt("afterElementsAdded"),this.update(c)}sync_scroll(){this.syncScroll()}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}connectedCallback(){this.template=this.getTemplate(),this.template!=null&&this.setup()}static get observedAttributes(){return codeInput.observedAttributes.concat(codeInput.textareaSyncAttributes)}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.update(c);break;case"placeholder":this.querySelector("textarea").placeholder=c;break;case"template":this.template=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.template.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.update(this.value);break;case"lang":let d=this.querySelector("pre code"),e=this.querySelector("textarea");if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;b=b.toLowerCase(),console.log("code-input: Language: REMOVE","language-"+b),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&(d.classList.add("language-"+c),console.log("code-input: Language:ADD","language-"+c)),e.placeholder==b&&(e.placeholder=c),this.update(this.value);break;default:codeInput.textareaSyncAttributes.includes(a)&&this.querySelector("textarea").setAttribute(a,c)}}addEventListener(a,b,c=void 0){let d=b.bind(this);this.boundEventCallbacks[b]=d,codeInput.textareaSyncEvents.includes(a)?c===void 0?this.querySelector("textarea").addEventListener(a,d):this.querySelector("textarea").addEventListener(a,d,c):c===void 0?super.addEventListener(a,d):super.addEventListener(a,d,c)}removeEventListener(a,b,c=null){let d=this.boundEventCallbacks[b];"change"==a?null===c?this.querySelector("textarea").removeEventListener("change",d):this.querySelector("textarea").removeEventListener("change",d,c):"selectionchange"==a?null===c?this.querySelector("textarea").removeEventListener("selectionchange",d):this.querySelector("textarea").removeEventListener("selectionchange",d,c):super.removeEventListener(a,b,c)}get value(){return this.getAttribute("value")}set value(a){return this.setAttribute("value",a)}get placeholder(){return this.getAttribute("placeholder")}set placeholder(a){return this.setAttribute("placeholder",a)}get validity(){return this.querySelector("textarea").validity}get validationMessage(){return this.querySelector("textarea").validationMessage}setCustomValidity(a){return this.querySelector("textarea").setCustomValidity(a)}checkValidity(){return this.querySelector("textarea").checkValidity()}reportValidity(){return this.querySelector("textarea").reportValidity()}setAttribute(a,b){super.setAttribute(a,b),this.querySelector("textarea").setAttribute(a,b)}getAttribute(a){return null==this.querySelector("textarea")?super.getAttribute(a):this.querySelector("textarea").getAttribute(a)}pluginData={}}};customElements.define("code-input",codeInput.CodeInput);
|
|
1
|
+
var codeInput={observedAttributes:["value","placeholder","lang","template"],textareaSyncAttributes:["aria-*","value","name","required","minlength","maxlength","min","max","type","pattern"],textareaSyncEvents:["change","selectionchange","invalid","input"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`code-input: Template for "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`code-input: Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue){for(let c in codeInput.templateNotYetRegisteredQueue[a])elem=codeInput.templateNotYetRegisteredQueue[a][c],elem.template=b,codeInput.runOnceWindowLoaded(function(a){a.connectedCallback()}.bind(null,elem),elem);console.log(`code-input: template: Added existing elements with template ${a}`)}if(null==codeInput.defaultTemplate){if(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue)for(let a in codeInput.templateNotYetRegisteredQueue[void 0])elem=codeInput.templateNotYetRegisteredQueue[void 0][a],elem.template=b,codeInput.runOnceWindowLoaded(function(a){a.connectedCallback()}.bind(null,elem),elem);console.log(`code-input: template: Set template ${a} as default`)}console.log(`code-input: template: Created template ${a}`)},Template:class{constructor(a=function(){},b=!0,c=!0,d=!1,e=[]){this.highlight=a,this.preElementStyled=b,this.isCode=c,this.includeCodeInputInHighlightFunc=d,this.plugins=e}highlight=function(){};preElementStyled=!0;isCode=!0;includeCodeInputInHighlightFunc=!1;plugins=[]},templates:{prism(a,b=[]){return{includeCodeInputInHighlightFunc:!1,highlight:a.highlightElement,preElementStyled:!0,isCode:!0,plugins:b}},hljs(a,b=[]){return{includeCodeInputInHighlightFunc:!1,highlight:a.highlightElement,preElementStyled:!1,isCode:!0,plugins:b}},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)},custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}}},plugins:new Proxy({},{get(a,b){if(a[b]==null)throw ReferenceError(`code-input: Plugin '${b}' is not defined. Please ensure you import the necessary files from the plugins folder in the WebCoder49/code-input repository, in the <head> of your HTML, before the plugin is instatiated.`);return a[b]}}),Plugin:class{constructor(a){console.log("code-input: plugin: Created plugin"),a.forEach(a=>{let b=codeInput.wildcard2regex(a);null==b?codeInput.observedAttributes.push(a):codeInput.observedAttributes.regexp.push(b)})}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}},CodeInput:class extends HTMLElement{constructor(){super()}_value="";textareaElement=null;preElement=null;codeElement=null;static formAssociated=!0;boundEventCallbacks={};pluginEvt(a,b){for(let c in this.template.plugins){let d=this.template.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}update(a){if(!this.ignoreValueUpdate){if(null==this.textareaElement)return void this.addEventListener("code-input_load",()=>{this.update(a)});this.ignoreValueUpdate=!0,this.value=a,this.ignoreValueUpdate=!1,this.textareaElement.value!=a&&(this.textareaElement.value=a);let b=this.codeElement;"\n"==a[a.length-1]&&(a+=" "),b.innerHTML=this.escapeHtml(a),this.pluginEvt("beforeHighlight"),this.template.includeCodeInputInHighlightFunc?this.template.highlight(b,this):this.template.highlight(b),this.pluginEvt("afterHighlight")}}syncScroll(){let a=this.textareaElement,b=this.template.preElementStyled?this.preElement:this.codeElement;b.scrollTop=a.scrollTop,b.scrollLeft=a.scrollLeft}escapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<")}unescapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){if(null!=this.textareaElement)return;this.classList.add("code-input_registered"),this.template.preElementStyled&&this.classList.add("code-input_pre-element-styled"),this.pluginEvt("beforeElementsAdded");let a=this.getAttribute("lang"),b=this.getAttribute("placeholder")||this.getAttribute("lang")||"",c=this.unescapeHtml(this.innerHTML)||this.getAttribute("value")||"";this.initialValue=c;let d=document.createElement("textarea");d.placeholder=b,""!=c&&(d.value=c),d.innerHTML=this.innerHTML,d.setAttribute("spellcheck","false"),this.innerHTML="",codeInput.textareaSyncAttributes.forEach(a=>{this.hasAttribute(a)&&d.setAttribute(a,this.getAttribute(a))}),codeInput.textareaSyncAttributes.regexp.forEach(a=>{for(const b of this.attributes)b.nodeName.match(a)&&d.setAttribute(b.nodeName,b.nodeValue)}),d.addEventListener("input",()=>{d.parentElement.update(d.value),d.parentElement.sync_scroll()}),d.addEventListener("scroll",()=>d.parentElement.sync_scroll()),this.textareaElement=d,this.append(d);let e=document.createElement("code"),f=document.createElement("pre");f.setAttribute("aria-hidden","true"),this.preElement=f,this.codeElement=e,f.append(e),this.append(f),this.template.isCode&&a!=null&&""!=a&&e.classList.add("language-"+a),this.pluginEvt("afterElementsAdded"),this.update(c),this.dispatchEvent(new CustomEvent("code-input_load"))}sync_scroll(){this.syncScroll()}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}connectedCallback(){this.template=this.getTemplate(),this.template!=null&&(this.classList.add("code-input_registered"),codeInput.runOnceWindowLoaded(()=>{this.setup(),this.classList.add("code-input_loaded")},this)),this.mutationObserver=new MutationObserver(this.mutationObserverCallback.bind(this)),this.mutationObserver.observe(this,{attributes:!0,attributeOldValue:!0})}mutationObserverCallback(a){for(const b of a)if("attributes"===b.type){for(let a=0;a<codeInput.observedAttributes.length;a++)if(b.attributeName==codeInput.observedAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));for(let a=0;a<codeInput.observedAttributes.regexp.length;a++){const c=codeInput.observedAttributes.regexp[a];if(b.attributeName.match(c))return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName))}}}disconnectedCallback(){this.mutationObserver.disconnect()}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.value=c;break;case"placeholder":this.textareaElement.placeholder=c;break;case"template":this.template=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.template.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.update(this.value);break;case"lang":let d=this.codeElement,e=this.textareaElement;if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;b=b.toLowerCase(),console.log("code-input: Language: REMOVE","language-"+b),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&(d.classList.add("language-"+c),console.log("code-input: Language: ADD","language-"+c)),e.placeholder==b&&(e.placeholder=c),this.update(this.value);break;default:codeInput.textareaSyncAttributes.includes(a)?null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c):codeInput.textareaSyncAttributes.regexp.forEach(b=>{a.match(b)&&(null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c))})}}addEventListener(a,b,c=void 0){let d=b.bind(this);this.boundEventCallbacks[b]=d,codeInput.textareaSyncEvents.includes(a)?c===void 0?null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d)}):this.textareaElement.addEventListener(a,d):null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d,c)}):this.textareaElement.addEventListener(a,d,c):c===void 0?super.addEventListener(a,d):super.addEventListener(a,d,c)}removeEventListener(a,b,c=null){let d=this.boundEventCallbacks[b];"change"==a?null===c?this.textareaElement.removeEventListener("change",d):this.textareaElement.removeEventListener("change",d,c):"selectionchange"==a?null===c?this.textareaElement.removeEventListener("selectionchange",d):this.textareaElement.removeEventListener("selectionchange",d,c):super.removeEventListener(a,b,c)}get value(){return this._value}set value(a){return(null===a||void 0===a)&&(a=""),this._value=a,this.update(a),a}get placeholder(){return this.getAttribute("placeholder")}set placeholder(a){return this.setAttribute("placeholder",a)}get validity(){return this.textareaElement.validity}get validationMessage(){return this.textareaElement.validationMessage}setCustomValidity(a){return this.textareaElement.setCustomValidity(a)}checkValidity(){return this.textareaElement.checkValidity()}reportValidity(){return this.textareaElement.reportValidity()}setAttribute(a,b){super.setAttribute(a,b),null!=this.textareaElement&&this.textareaElement.setAttribute(a,b)}getAttribute(a){return null==this.textareaElement?super.getAttribute(a):this.textareaElement.getAttribute(a)}pluginData={};formResetCallback(){this.update(this.initialValue)}},arrayWildcards2regex(a){for(let b=0;b<a.length;b++){const c=a[b];0>c.indexOf("*")||(a.regexp.push(new RegExp("^"+c.replace(/[/\-\\^$+?.()|[\]{}]/g,"\\$&").replace("*",".*")+"$","i")),a.splice(b--,1))}},wildcard2regex(a){return 0>a.indexOf("*")?null:new RegExp("^"+a.replace(/[/\-\\^$+?.()|[\]{}]/g,"\\$&").replace("*",".*")+"$","i")},runOnceWindowLoaded(a){codeInput.windowLoaded?a():window.addEventListener("load",a)},windowLoaded:!1};window.addEventListener("load",function(){codeInput.windowLoaded=!0}),Object.defineProperty(codeInput.textareaSyncAttributes,"regexp",{value:[],writable:!1,enumerable:!1,configurable:!1}),codeInput.observedAttributes=codeInput.observedAttributes.concat(codeInput.textareaSyncAttributes),Object.defineProperty(codeInput.observedAttributes,"regexp",{value:[],writable:!1,enumerable:!1,configurable:!1}),codeInput.arrayWildcards2regex(codeInput.textareaSyncAttributes),codeInput.arrayWildcards2regex(codeInput.observedAttributes),customElements.define("code-input",codeInput.CodeInput);
|
package/package.json
CHANGED
package/plugins/autocomplete.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
|
|
6
6
|
/**
|
|
7
7
|
* Pass in a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
8
|
-
* @param {function} updatePopupCallback
|
|
8
|
+
* @param {function} updatePopupCallback a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
9
9
|
*/
|
|
10
10
|
constructor(updatePopupCallback) {
|
|
11
|
-
super();
|
|
11
|
+
super([]); // No observed attributes
|
|
12
12
|
this.updatePopupCallback = updatePopupCallback;
|
|
13
13
|
}
|
|
14
14
|
/* When a key is pressed, or scrolling occurs, update the autocomplete */
|
|
@@ -75,6 +75,5 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
|
|
|
75
75
|
}
|
|
76
76
|
return {"top": afterSpan.offsetTop - textarea.scrollTop, "left": afterSpan.offsetLeft - textarea.scrollLeft};
|
|
77
77
|
}
|
|
78
|
-
observedAttributes = [];
|
|
79
78
|
updatePopupCallback = function() {};
|
|
80
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.Autocomplete=class extends codeInput.Plugin{constructor(a){super(),this.updatePopupCallback=a}updatePopup(a,b){let c=a.querySelector("textarea"),d=this.getCaretCoordinates(a,c,c.selectionEnd,b),e=a.querySelector(".code-input_autocomplete_popup");e.style.top=d.top+"px",e.style.left=d.left+"px",b||this.updatePopupCallback(e,c,c.selectionEnd)}afterElementsAdded(a){let b=document.createElement("div");b.classList.add("code-input_autocomplete_popup"),a.appendChild(b);let c=document.createElement("pre");c.classList.add("code-input_autocomplete_testpos"),a.appendChild(c);let d=a.querySelector("textarea");d.addEventListener("keyup",this.updatePopup.bind(this,a,!1)),d.addEventListener("click",this.updatePopup.bind(this,a,!1)),d.addEventListener("scroll",this.updatePopup.bind(this,a,!0))}getCaretCoordinates(a,b,c,d){let e;if(d){let d=a.querySelector(".code-input_autocomplete_testpos").querySelectorAll("span");if(2>d.length)return this.getCaretCoordinates(a,b,c,!1);e=d[1]}else{let d=a.querySelector(".code-input_autocomplete_testpos"),f=document.createElement("span");for(f.textContent=b.value.substring(0,c),e=document.createElement("span"),e.textContent=".";d.firstChild;)d.removeChild(d.firstChild);d.appendChild(f),d.appendChild(e)}return{top:e.offsetTop-b.scrollTop,left:e.offsetLeft-b.scrollLeft}}
|
|
1
|
+
codeInput.plugins.Autocomplete=class extends codeInput.Plugin{constructor(a){super([]),this.updatePopupCallback=a}updatePopup(a,b){let c=a.querySelector("textarea"),d=this.getCaretCoordinates(a,c,c.selectionEnd,b),e=a.querySelector(".code-input_autocomplete_popup");e.style.top=d.top+"px",e.style.left=d.left+"px",b||this.updatePopupCallback(e,c,c.selectionEnd)}afterElementsAdded(a){let b=document.createElement("div");b.classList.add("code-input_autocomplete_popup"),a.appendChild(b);let c=document.createElement("pre");c.classList.add("code-input_autocomplete_testpos"),a.appendChild(c);let d=a.querySelector("textarea");d.addEventListener("keyup",this.updatePopup.bind(this,a,!1)),d.addEventListener("click",this.updatePopup.bind(this,a,!1)),d.addEventListener("scroll",this.updatePopup.bind(this,a,!0))}getCaretCoordinates(a,b,c,d){let e;if(d){let d=a.querySelector(".code-input_autocomplete_testpos").querySelectorAll("span");if(2>d.length)return this.getCaretCoordinates(a,b,c,!1);e=d[1]}else{let d=a.querySelector(".code-input_autocomplete_testpos"),f=document.createElement("span");for(f.textContent=b.value.substring(0,c),e=document.createElement("span"),e.textContent=".";d.firstChild;)d.removeChild(d.firstChild);d.appendChild(f),d.appendChild(e)}return{top:e.offsetTop-b.scrollTop,left:e.offsetLeft-b.scrollLeft}}updatePopupCallback=function(){}};
|
package/plugins/autodetect.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Autodetect the language live and change the `lang` attribute using the syntax highlighter's
|
|
3
|
-
* autodetect capabilities. Works with highlight.js.
|
|
3
|
+
* autodetect capabilities. Works with highlight.js only.
|
|
4
4
|
* Files: autodetect.js
|
|
5
5
|
*/
|
|
6
6
|
codeInput.plugins.Autodetect = class extends codeInput.Plugin {
|
|
7
7
|
constructor() {
|
|
8
|
-
super();
|
|
8
|
+
super([]); // No observed attributes
|
|
9
9
|
}
|
|
10
10
|
/* Remove previous language class */
|
|
11
11
|
beforeHighlight(codeInput) {
|
|
@@ -25,5 +25,4 @@ codeInput.plugins.Autodetect = class extends codeInput.Plugin {
|
|
|
25
25
|
codeInput.setAttribute("lang", lang);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
observedAttributes = []
|
|
29
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.Autodetect=class extends codeInput.Plugin{constructor(){super()}beforeHighlight(a){let b=a.querySelector("pre code");b.className="",b.parentElement.className=""}afterHighlight(a){let b=a.querySelector("pre code"),c=b.className||b.parentElement.className,d=c.match(/lang(\w|-)*/i)[0];d=d.split("-")[1],"undefined"==d?a.removeAttribute("lang"):a.setAttribute("lang",d)}
|
|
1
|
+
codeInput.plugins.Autodetect=class extends codeInput.Plugin{constructor(){super([])}beforeHighlight(a){let b=a.querySelector("pre code");b.className="",b.parentElement.className=""}afterHighlight(a){let b=a.querySelector("pre code"),c=b.className||b.parentElement.className,d=c.match(/lang(\w|-)*/i)[0];d=d.split("-")[1],"undefined"==d?a.removeAttribute("lang"):a.setAttribute("lang",d)}};
|
|
@@ -9,7 +9,7 @@ codeInput.plugins.DebounceUpdate = class extends codeInput.Plugin {
|
|
|
9
9
|
* @param {Number} delayMs Delay, in ms, to wait until updating the syntax highlighting
|
|
10
10
|
*/
|
|
11
11
|
constructor(delayMs) {
|
|
12
|
-
super();
|
|
12
|
+
super([]); // No observed attributes
|
|
13
13
|
this.delayMs = delayMs;
|
|
14
14
|
}
|
|
15
15
|
/* Runs before elements are added into a `code-input`; Params: codeInput element) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.DebounceUpdate=class extends codeInput.Plugin{constructor(a){super(),this.delayMs=a}beforeElementsAdded(a){console.log(a,"before elements added"),this.update=a.update.bind(a),a.update=this.updateDebounced.bind(this,a)}updateDebounced(a,b){null!=this.debounceTimeout&&window.clearTimeout(this.debounceTimeout),this.debounceTimeout=window.setTimeout(()=>{this.update(b)},this.delayMs)}debounceTimeout=null;delayMs=0};
|
|
1
|
+
codeInput.plugins.DebounceUpdate=class extends codeInput.Plugin{constructor(a){super([]),this.delayMs=a}beforeElementsAdded(a){console.log(a,"before elements added"),this.update=a.update.bind(a),a.update=this.updateDebounced.bind(this,a)}updateDebounced(a,b){null!=this.debounceTimeout&&window.clearTimeout(this.debounceTimeout),this.debounceTimeout=window.setTimeout(()=>{this.update(b)},this.delayMs)}debounceTimeout=null;delayMs=0};
|
package/plugins/indent.js
CHANGED
package/plugins/indent.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.Indent=class extends codeInput.Plugin{constructor(){super()}afterElementsAdded(a){let b=a.querySelector("textarea");b.addEventListener("keydown",b=>{this.check_tab(a,b),this.check_enter(a,b)})}check_tab(a,b){if("Tab"!=b.key)return;let c=a.querySelector("textarea"),d=c.value;if(b.preventDefault(),!b.shiftKey&&c.selectionStart==c.selectionEnd)document.execCommand("insertText",!1,"\t");else{let a=c.value.split("\n"),d=0,e=c.selectionStart,f=c.selectionEnd;for(let g=0;g<a.length;g++)(e<=d+a[g].length&&f>=d+1||e==f&&e<=d+a[g].length+1&&f>=d)&&(b.shiftKey?"\t"==a[g][0]&&(c.selectionStart=d,c.selectionEnd=d+1,document.execCommand("delete",!1,""),e>d&&e--,f--,d--):(c.selectionStart=d,c.selectionEnd=d,document.execCommand("insertText",!1,"\t"),e>d&&e++,f++,d++)),d+=a[g].length+1;c.selectionStart=e,c.selectionEnd=f}a.update(c.value)}check_enter(a,b){if("Enter"!=b.key)return;b.preventDefault();let c=a.querySelector("textarea"),d=c.value.split("\n"),e=0,f=d.length-1,g="",h=0;for(let g=0;g<d.length;g++)if(e+=d[g].length+1,c.selectionEnd<=e){f=g;break}let j=d[f].length-(e-c.selectionEnd)+1;for(let c=0;c<j&&"\t"==d[f][c];c++)h++;let k="";j!=d[f].length&&(k=d[f].substring(j),d[f]=d[f].substring(0,j));for(let c=0;c<h;c++)g+="\t";let l=c.selectionStart,m=c.selectionEnd;document.execCommand("insertText",!1,"\n"+g),c.selectionStart=l+h+1,c.selectionEnd=l+h+1,a.update(c.value),c.scrollLeft=0;let n=+getComputedStyle(c).lineHeight.split(0,-2);c.scrollTop+=n==NaN&&"px"==getComputedStyle(c).lineHeight.split(-2)?n:20}};
|
|
1
|
+
codeInput.plugins.Indent=class extends codeInput.Plugin{constructor(){super([])}afterElementsAdded(a){let b=a.querySelector("textarea");b.addEventListener("keydown",b=>{this.check_tab(a,b),this.check_enter(a,b)})}check_tab(a,b){if("Tab"!=b.key)return;let c=a.querySelector("textarea"),d=c.value;if(b.preventDefault(),!b.shiftKey&&c.selectionStart==c.selectionEnd)document.execCommand("insertText",!1,"\t");else{let a=c.value.split("\n"),d=0,e=c.selectionStart,f=c.selectionEnd;for(let g=0;g<a.length;g++)(e<=d+a[g].length&&f>=d+1||e==f&&e<=d+a[g].length+1&&f>=d)&&(b.shiftKey?"\t"==a[g][0]&&(c.selectionStart=d,c.selectionEnd=d+1,document.execCommand("delete",!1,""),e>d&&e--,f--,d--):(c.selectionStart=d,c.selectionEnd=d,document.execCommand("insertText",!1,"\t"),e>d&&e++,f++,d++)),d+=a[g].length+1;c.selectionStart=e,c.selectionEnd=f}a.update(c.value)}check_enter(a,b){if("Enter"!=b.key)return;b.preventDefault();let c=a.querySelector("textarea"),d=c.value.split("\n"),e=0,f=d.length-1,g="",h=0;for(let g=0;g<d.length;g++)if(e+=d[g].length+1,c.selectionEnd<=e){f=g;break}let j=d[f].length-(e-c.selectionEnd)+1;for(let c=0;c<j&&"\t"==d[f][c];c++)h++;let k="";j!=d[f].length&&(k=d[f].substring(j),d[f]=d[f].substring(0,j));for(let c=0;c<h;c++)g+="\t";let l=c.selectionStart,m=c.selectionEnd;document.execCommand("insertText",!1,"\n"+g),c.selectionStart=l+h+1,c.selectionEnd=l+h+1,a.update(c.value),c.scrollLeft=0;let n=+getComputedStyle(c).lineHeight.split(0,-2);c.scrollTop+=n==NaN&&"px"==getComputedStyle(c).lineHeight.split(-2)?n:20}};
|
package/plugins/special-chars.js
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
* Files: special-chars.js, special-chars.css
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// INCOMPLETE: TODO Optimise regex - compile at start; Update CSS for character display; clean up + comment
|
|
7
|
-
|
|
8
6
|
codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
|
|
9
7
|
specialCharRegExp;
|
|
10
8
|
|
|
@@ -13,13 +11,14 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
|
|
|
13
11
|
canvasContext;
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
|
-
* Create a special characters plugin instance
|
|
14
|
+
* Create a special characters plugin instance.
|
|
15
|
+
* Default = covers many non-renderable ASCII characters.
|
|
17
16
|
* @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code
|
|
18
17
|
* @param {Boolean} inheritTextColor If `colorInSpecialChars` is false, forces the color of the hex code to inherit from syntax highlighting. Otherwise, the base colour of the `pre code` element is used to give contrast to the small characters.
|
|
19
18
|
* @param {RegExp} specialCharRegExp The regular expression which matches special characters
|
|
20
19
|
*/
|
|
21
20
|
constructor(colorInSpecialChars = false, inheritTextColor = false, specialCharRegExp = /(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug) { // By default, covers many non-renderable ASCII characters
|
|
22
|
-
super();
|
|
21
|
+
super([]); // No observed attributes
|
|
23
22
|
|
|
24
23
|
this.specialCharRegExp = specialCharRegExp;
|
|
25
24
|
this.colorInSpecialChars = colorInSpecialChars;
|
|
@@ -153,7 +152,7 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
|
|
|
153
152
|
}
|
|
154
153
|
}
|
|
155
154
|
|
|
156
|
-
getCharacterWidth(codeInput, char) {
|
|
155
|
+
getCharacterWidth(codeInput, char) {
|
|
157
156
|
// Force zero-width characters
|
|
158
157
|
if(new RegExp("\u00AD|\u02de|[\u0300-\u036F]|[\u0483-\u0489]|\u200b").test(char) ) { return 0 }
|
|
159
158
|
// Non-renderable ASCII characters should all be rendered at same size
|
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.SpecialChars=class extends codeInput.Plugin{specialCharRegExp;cachedColors;cachedWidths;canvasContext;constructor(a=!1,b=!1,c=/(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug){super(),this.specialCharRegExp=c,this.colorInSpecialChars=a,this.inheritTextColor=b,this.cachedColors={},this.cachedWidths={};let d=document.createElement("canvas");this.canvasContext=d.getContext("2d")}beforeElementsAdded(a){a.classList.add("code-input_special-char_container")}afterElementsAdded(a){setTimeout(()=>{a.update(a.value)},100)}afterHighlight(a){let b=a.querySelector("pre code");a.pluginData.specialChars={},a.pluginData.specialChars.textarea=a.getElementsByTagName("textarea")[0],a.pluginData.specialChars.contrastColor=window.getComputedStyle(b).color,this.recursivelyReplaceText(a,b),this.lastFont=window.getComputedStyle(a.pluginData.specialChars.textarea).font}recursivelyReplaceText(a,b){for(let c,d=0;d<b.childNodes.length;d++)if(c=b.childNodes[d],"#text"==c.nodeName&&""!=c.nodeValue){let b=c.nodeValue;this.specialCharRegExp.lastIndex=0;let d=this.specialCharRegExp.exec(b);if(null!=d){let b=d.index;if(c=c.splitText(b+1).previousSibling,0<b&&(c=c.splitText(b)),""!=c.textContent){let b=this.specialCharReplacer(a,c.textContent);c.parentNode.insertBefore(b,c),c.textContent=""}}}else 1==c.nodeType&&"code-input_special-char"!=c.className&&""!=c.nodeValue&&this.recursivelyReplaceText(a,c)}specialCharReplacer(a,b){let c,d=b.codePointAt(0);this.colorInSpecialChars&&(c=this.getCharacterColor(d)),d=d.toString(16),d=("0000"+d).substring(d.length),d=d.toUpperCase();let e=this.getCharacterWidth(a,b),f=document.createElement("span");return f.classList.add("code-input_special-char"),f.style.setProperty("--hex-0","var(--code-input_special-chars_"+d[0]+")"),f.style.setProperty("--hex-1","var(--code-input_special-chars_"+d[1]+")"),f.style.setProperty("--hex-2","var(--code-input_special-chars_"+d[2]+")"),f.style.setProperty("--hex-3","var(--code-input_special-chars_"+d[3]+")"),0==e?f.classList.add("code-input_special-char_zero-width"):f.style.width=e+"px",this.colorInSpecialChars?(f.style.backgroundColor="#"+c[0],f.style.setProperty("--code-input_special-char_color",c[1])):!this.inheritTextColor&&f.style.setProperty("--code-input_special-char_color",a.pluginData.specialChars.contrastColor),f}getCharacterColor(a){let b,c;if(!(a in this.cachedColors)){b=a^a<<3^a<<7^a<<14^a<<16,b^=2082343,b=b.toString(16),b=("000000"+b).substring(b.length);let d=0,e=[.299,.587,.114];for(let a=0;6>a;a+=2)d+=parseInt(b.substring(a,a+2),16)*e[a/2];return c=128>d?"white":"black",this.cachedColors[a]=[b,c],[b,c]}return this.cachedColors[a]}getCharacterWidth(a,b){if(/|˞|[̀-ͯ]|[҃-҉]|/.test(b))return 0;if("\x96"!=b&&/[\0-]|[-]/g.test(b)){let a=this.getCharacterWidth("\x96");return a}let c=window.getComputedStyle(a.pluginData.specialChars.textarea).font;if(null==this.cachedWidths[c]&&(this.cachedWidths[c]={}),null!=this.cachedWidths[c][b])return this.cachedWidths[c][b];this.canvasContext.font=c;let d=this.canvasContext.measureText(b).width;if(d>+c.split("px")[0])d/=2;else if(0==d&&"\x96"!=b){let a=this.getCharacterWidth("\x96");return a}return this.cachedWidths[c][b]=d,d}};
|
|
1
|
+
codeInput.plugins.SpecialChars=class extends codeInput.Plugin{specialCharRegExp;cachedColors;cachedWidths;canvasContext;constructor(a=!1,b=!1,c=/(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug){super([]),this.specialCharRegExp=c,this.colorInSpecialChars=a,this.inheritTextColor=b,this.cachedColors={},this.cachedWidths={};let d=document.createElement("canvas");this.canvasContext=d.getContext("2d")}beforeElementsAdded(a){a.classList.add("code-input_special-char_container")}afterElementsAdded(a){setTimeout(()=>{a.update(a.value)},100)}afterHighlight(a){let b=a.querySelector("pre code");a.pluginData.specialChars={},a.pluginData.specialChars.textarea=a.getElementsByTagName("textarea")[0],a.pluginData.specialChars.contrastColor=window.getComputedStyle(b).color,this.recursivelyReplaceText(a,b),this.lastFont=window.getComputedStyle(a.pluginData.specialChars.textarea).font}recursivelyReplaceText(a,b){for(let c,d=0;d<b.childNodes.length;d++)if(c=b.childNodes[d],"#text"==c.nodeName&&""!=c.nodeValue){let b=c.nodeValue;this.specialCharRegExp.lastIndex=0;let d=this.specialCharRegExp.exec(b);if(null!=d){let b=d.index;if(c=c.splitText(b+1).previousSibling,0<b&&(c=c.splitText(b)),""!=c.textContent){let b=this.specialCharReplacer(a,c.textContent);c.parentNode.insertBefore(b,c),c.textContent=""}}}else 1==c.nodeType&&"code-input_special-char"!=c.className&&""!=c.nodeValue&&this.recursivelyReplaceText(a,c)}specialCharReplacer(a,b){let c,d=b.codePointAt(0);this.colorInSpecialChars&&(c=this.getCharacterColor(d)),d=d.toString(16),d=("0000"+d).substring(d.length),d=d.toUpperCase();let e=this.getCharacterWidth(a,b),f=document.createElement("span");return f.classList.add("code-input_special-char"),f.style.setProperty("--hex-0","var(--code-input_special-chars_"+d[0]+")"),f.style.setProperty("--hex-1","var(--code-input_special-chars_"+d[1]+")"),f.style.setProperty("--hex-2","var(--code-input_special-chars_"+d[2]+")"),f.style.setProperty("--hex-3","var(--code-input_special-chars_"+d[3]+")"),0==e?f.classList.add("code-input_special-char_zero-width"):f.style.width=e+"px",this.colorInSpecialChars?(f.style.backgroundColor="#"+c[0],f.style.setProperty("--code-input_special-char_color",c[1])):!this.inheritTextColor&&f.style.setProperty("--code-input_special-char_color",a.pluginData.specialChars.contrastColor),f}getCharacterColor(a){let b,c;if(!(a in this.cachedColors)){b=a^a<<3^a<<7^a<<14^a<<16,b^=2082343,b=b.toString(16),b=("000000"+b).substring(b.length);let d=0,e=[.299,.587,.114];for(let a=0;6>a;a+=2)d+=parseInt(b.substring(a,a+2),16)*e[a/2];return c=128>d?"white":"black",this.cachedColors[a]=[b,c],[b,c]}return this.cachedColors[a]}getCharacterWidth(a,b){if(/|˞|[̀-ͯ]|[҃-҉]|/.test(b))return 0;if("\x96"!=b&&/[\0-]|[-]/g.test(b)){let a=this.getCharacterWidth("\x96");return a}let c=window.getComputedStyle(a.pluginData.specialChars.textarea).font;if(null==this.cachedWidths[c]&&(this.cachedWidths[c]={}),null!=this.cachedWidths[c][b])return this.cachedWidths[c][b];this.canvasContext.font=c;let d=this.canvasContext.measureText(b).width;if(d>+c.split("px")[0])d/=2;else if(0==d&&"\x96"!=b){let a=this.getCharacterWidth("\x96");return a}return this.cachedWidths[c][b]=d,d}};
|
package/plugins/test.js
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
codeInput.plugins.Test = class extends codeInput.Plugin {
|
|
12
12
|
constructor() {
|
|
13
|
-
super();
|
|
13
|
+
super(["testattr", "test-*"]);
|
|
14
|
+
// Array of observed attributes as parameter
|
|
15
|
+
// Wildcard "*" matches any text
|
|
14
16
|
}
|
|
15
17
|
/* Runs before code is highlighted; Params: codeInput element) */
|
|
16
18
|
beforeHighlight(codeInput) {
|
|
@@ -28,11 +30,8 @@ codeInput.plugins.Test = class extends codeInput.Plugin {
|
|
|
28
30
|
afterElementsAdded(codeInput) {
|
|
29
31
|
console.log(codeInput, "after elements added");
|
|
30
32
|
}
|
|
31
|
-
/* Runs when an attribute of a `code-input` is changed (you must add the attribute name
|
|
33
|
+
/* Runs when an observed attribute of a `code-input` is changed (you must add the attribute name in the constructor); Params: codeInput element, name attribute name, oldValue previous value of attribute, newValue changed value of attribute) */
|
|
32
34
|
attributeChanged(codeInput, name, oldValue, newValue) {
|
|
33
|
-
|
|
34
|
-
console.log(codeInput, "testattr:", oldValue, ">", newValue);
|
|
35
|
-
}
|
|
35
|
+
console.log(codeInput, name, ":", oldValue, ">", newValue);
|
|
36
36
|
}
|
|
37
|
-
observedAttributes = ["testattr"]
|
|
38
37
|
}
|
package/plugins/test.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
codeInput.plugins.Test=class extends codeInput.Plugin{constructor(){super()}beforeHighlight(a){console.log(a,"before highlight")}afterHighlight(a){console.log(a,"after highlight")}beforeElementsAdded(a){console.log(a,"before elements added")}afterElementsAdded(a){console.log(a,"after elements added")}attributeChanged(a,b,c,d){
|
|
1
|
+
codeInput.plugins.Test=class extends codeInput.Plugin{constructor(){super(["testattr","test-*"])}beforeHighlight(a){console.log(a,"before highlight")}afterHighlight(a){console.log(a,"after highlight")}beforeElementsAdded(a){console.log(a,"before elements added")}afterElementsAdded(a){console.log(a,"after elements added")}attributeChanged(a,b,c,d){console.log(a,b,":",c,">",d)}};
|