UNPKG

webserverai

Version:

WebServerAI is an advanced project using AI to revolutionize web development. It empowers users to create visually stunning websites tailored to their needs without extensive coding knowledge. This innovative tool streamlines the design process, offering

884 lines (851 loc) 52.4 kB
import Listener from './components/Learner.js'; import Extensions from './components/extenstions.js'; import { filter, credits } from './components/security.js'; import { rgbaToHex, calculateContrastRatio, keyboardFocusable, isDecimal, wait } from './components/utils.js'; import VoiceType from './components/voicetype.js'; import ai_extension from './extras/aiExtension.js'; import { cookie, session } from './components/storage.js'; import { aiVoice } from './extras/aiVoice.js'; var responce, elemRole='', codeTheme='default', bodyHistory; window.WebServerAI = class extends ai_extension{ /** * @constructor Loads up the WebServerAI module * @param {{}} [settings={}] * @param {Boolean} [isNull=false] Triggers event even if message is null */ constructor(settings={},isNull=false){ super(); session.save('wsa-aivoice-reader',false); const x = document.createElement('script'); x.innerHTML = 'window.speechSynthesis'; document.body.insertBefore(x,document.querySelectorAll('script')[1]); wait(()=>{aiVoice.getVoices()},50); this.isNull = isNull; session.save('wsa-isnull',isNull); this.request(window.location.origin+'/WebServerAI/libs/history.php?action=create'); this.request(window.location.origin+'/WebServerAI/libs/ai_credits.php?load=true'); this.request(window.location.origin+'/WebserverAI/libs/ai_saveSettings.php?action=timezone&value='+Intl.DateTimeFormat().resolvedOptions().timeZone); //Load up CSS document.head.innerHTML+='<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/tkbviet/font-awesome-6.5.2-pro-full@main/css/all.css"/>'; document.head.innerHTML+='<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/XHiddenProjects/WebAnimate@0.0.5/assets/webanimate.css"/>'; //Continue the program this.theme = settings.hasOwnProperty('theme') ? settings.theme : 'light'; document.documentElement.setAttribute('wsa-theme',this.theme); this.pos = settings.hasOwnProperty('position') ? settings.position : 'bottom right'; this.status = settings.hasOwnProperty('status') ? settings.status : 'opened'; this.enabled = (settings.hasOwnProperty('enabled') ? settings.enabled : true); this.smart = (settings.hasOwnProperty('smart') ? settings.smart : true); this.cte = (settings.hasOwnProperty('cte') ? settings.cte : true); this.preview = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('preview') ? settings.ui.preview : null); this.previewBtn = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('previewBtn') ? settings.ui.previewBtn : null); this.manualBox = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('chatbox') ? settings.ui.chatbox : null); this.submitBtn = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('submit') ? settings.ui.submit : null); this.historyStorage = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('history') ? settings.ui.history : null); this.language = (settings.hasOwnProperty('ui')&&settings.ui.hasOwnProperty('language') ? settings.ui.language : navigator.language); cookie.set('lang',this.language,(86400 * 1)); if(document.querySelector(this.manualBox)) document.querySelector(this.manualBox).setAttribute('wsa-exclude',''); if(document.querySelector(this.submitBtn)){ const btn = document.querySelector(this.submitBtn); btn.setAttribute('wsa-exclude',''); btn.classList.add('wsa-editor-send'); } codeTheme = (settings.hasOwnProperty('codeTheme') ? settings.codeTheme : 'default'); const extensions = new Extensions(); this.origin = window.location.origin; if(settings.hasOwnProperty('extensions')){ for(let e in settings.extensions){ if(settings.extensions[e].active){ extensions.activate(e, (settings.extensions[e].hasOwnProperty('config') ? settings.extensions[e].config : null)); if(settings.extensions[e].hasOwnProperty('startup')){ for(let s in settings.extensions[e].startup){ if(s==='styles'){ for(let i=0;i<settings.extensions[e].startup[s].length;i++){ const style = document.createElement('link'); style.rel = 'stylesheet'; style.setAttribute('wsa-build',e); style.href = this.origin+settings.extensions[e].startup[s][i]+'?extensionID='+extensions.lookup(e,'id',extensions.list()); document.head.appendChild(style); } }else if(s==='scripts'){ for(let i=0;i<settings.extensions[e].startup[s].length;i++){ const script = document.createElement('script'); script.type = 'module'; script.setAttribute('wsa-build',e); script.src = this.origin+settings.extensions[e].startup[s][i]+'?extensionID='+extensions.lookup(e,'id',extensions.list())+(extensions.getBuildConfig(e,extensions.list()).length>0 ? '&'+extensions.getBuildConfig(e,extensions.list()).join('&') : ''); document.body.appendChild(script); } }else if(s==='assets'){ for(let i=0;i<settings.extensions[e].startup[s].length;i++){ const item = settings.extensions[e].startup[s][i]; if(item['type']==='style'){ const style = document.createElement('link'); style.rel = 'stylesheet'; style.href = item['url']; document.head.appendChild(style); }else{ const script = document.createElement('script'); script.src = item['url']; if(item.hasOwnProperty('module')) script.type = 'module'; document.body.appendChild(script); } } } } } } } sessionStorage.setItem('wsa_extensions', JSON.stringify(extensions.list())); } this.cmdID = 0; this.botName=''; this.lang = ''; this.botInfo; this.listedHistory=[]; this.getHistory = this.request(window.location.origin+'/WebServerAI/libs/history.php?action=recieve', true); if(this.getHistory){ this.getHistory.forEach((e)=>{ this.listedHistory.push(e.history); }); } this.history=(this.listedHistory ? this.listedHistory : []); this.listen = new Listener(); this.checked=false; this.responces = ''; this.voice = new VoiceType(); } /** * Generate a unique id * * @param {string} [prefix=''] Prefix to the start of the ID * @param {boolean} [more_entropy=false] add more to the list * @returns {string} */ #uniqid(prefix='', more_entropy=false){ return prefix+(Date.now().toString(36) + Math.random().toString(36).substr(2)).substr(0,(more_entropy ? 23 : 13)); } /** * Sets a request to the file to select * * @param {*} url URL to receive information * @param {boolean} [isJSON=false] Output as a JSON format * @param {boolean} [async=false] Async the request * @param {boolean} [retReq=false] Return as a request object * @returns {*} */ request(url, isJSON=false, async=false, retReq=false){ let req = new XMLHttpRequest(); req.onreadystatechange = ()=>{ if(req.readyState==4&&req.status==200){ if(!retReq){ if(isJSON){ responce = JSON.parse(req.responseText); } else{ responce = req.responseText; } }else{ responce = req; } } } req.open("GET", url, async); req.send(); return responce; } #getSel(txtarea) // JavaScript { // Obtain the index of the first selected character let start = txtarea.selectionStart; // Obtain the index of the last selected character let finish = txtarea.selectionEnd; // Obtain the selected text let sel = txtarea.value.substring(start, finish); return sel; } #replaceSelection(textarea, replacementText) { let len = textarea.value.length, start = textarea.selectionStart, end = textarea.selectionEnd, sel = textarea.value.substring(start, end); textarea.value = textarea.value.substring(0,start) + replacementText + textarea.value.substring(end,len); } /** * Converts datetime to current users timezone * @param {String} date DateTime to format * @returns {String} Formatted datetime */ #formatDate(date){ const splitDate = date.split('/'); const d = new Date(parseInt(splitDate[2]),parseInt(splitDate[0])-1,parseInt(splitDate[1])); return d.toLocaleDateString(this.language,{ month: '2-digit', day: '2-digit', year: 'numeric' }); } #getNthChild(childNode){ const parent = childNode.parentNode, nthchild = Array.prototype.indexOf.call(parent.children, childNode)+1; return ':nth-child('+nthchild+')'; } /** * Get all parents to the branch * @param {Element} t Targetted element * @returns {String} Element Path */ #branchLoad(t){ let branch = [], currentBase = t, toPath = ''; while(currentBase.tagName.toLocaleLowerCase()!==document.documentElement.tagName.toLocaleLowerCase()){ const nthChild = this.#getNthChild(currentBase); const elem = (currentBase.tagName.toLowerCase()+(nthChild ? nthChild : '')+(currentBase.id ? '#'+currentBase.id : '')+(currentBase.classList.length > 0 ? '.'+currentBase.className.replace(' ','.') : '')); branch.push(elem); currentBase = currentBase.parentElement; } branch.push('html'); branch.reverse().forEach((i)=>{ toPath += i+' '; }); return toPath.replace(/ $/,''); } #getElemRole(){ document.querySelectorAll('*:not(.wsa, .wsa *)').forEach((e)=>{ const node = (window.hasOwnProperty('getComputedAccessibleNode') ? window.getComputedAccessibleNode(e) : null); if(node){ const role = node.then((data)=>{ return (data ? data.role : ''); }).then((r)=>{ (r!=='' ? e.role = r : ''); }); } }); } #getElemName(){ document.querySelectorAll('*:not(.wsa, .wsa *)').forEach((e)=>{ const node = (window.hasOwnProperty('getComputedAccessibleNode') ? window.getComputedAccessibleNode(e) : null); if(node){ const name = node.then((data)=>{ return (data ? data.name : ''); }).then((n)=>{ (n!=='' ? e.setAttribute('aria-name',n) : ''); }); } }); } /** * Loads up the WebServerAI module */ load(){ if(this.enabled){ this.#getElemRole(); this.#getElemName(); document.documentElement.lang = this.language.replace(/\-(.*)$/,''); this.botInfo = this.request(this.origin+'/WebServerAI/libs/usersInfo.php',true)['AI']; this.previewBox = this.request(this.origin+'/WebServerAI/libs/usersInfo.php',true)['previewBox']; this.lang = this.request(this.origin+'/WebServerAI/data/languages.json?u='+this.#uniqid(),true)['languages'][this.language]; this.botName = this.botInfo['Name']; document.querySelector('html').setAttribute('wsa-active',''); document.querySelector('head').innerHTML+='<link rel="stylesheet" wsa-exclude href="'+this.origin+'/WebServerAI/assets/AI/css/webserverai.min.css"/>'; document.querySelector('head').innerHTML+='<link rel="stylesheet" wsa-exclude href="'+this.origin+'/WebServerAI/assets/AI/css/webserverai-mobile.min.css"/>'; if(!this.manualBox){ let chatBox = document.createElement('div'); chatBox.setAttribute('wsa-theme',this.theme); chatBox.setAttribute('wsa-position',this.pos); chatBox.setAttribute('wsa-stat',this.status); chatBox.classList.add('wsa'); chatBox.setAttribute('wsa-exclude',''); chatBox.contentEditable = false; chatBox.draggable = true; chatBox.setAttribute('ondragstart', 'dragBlock(event)'); chatBox.setAttribute('ondragend', 'endDragBlock(event)'); const container = document.createElement('div'); container.classList.add('wsa-container'); container.innerHTML = `<h2 class="wsa-title"> ${this.lang['dictionary'].title} <div class="wsa-subtitle"><span class="wsa-version" title="${this.#formatDate(this.botInfo['Updated'])}">v${this.botInfo['Version']} (${this.lang.name})</span> | <span class="wsa-credits" title="${this.lang['dictionary']['ai']['creditsInfo']}">${this.lang['dictionary']['ai']['credits']}: <span class="current${credits.get() <= Math.floor(credits.max()/2) ? ' low' : ''}">${credits.get()}</span>/${credits.max()}</span></div> </h2> <div class="wsa-ui"> <div class="wsa-history"></div> <div class="wsa-editor"> <div class="wsa-editor-actions wsa-controllers"> <button type="button" ${credits.get()<=0 ? 'disabled="disabled"' : ''} class="wsa-editor-send wsa-btn" title="${this.lang['dictionary'].nav.send}"> <i class="fa-solid fa-share fa-rotate-180"></i> </button> </div> <textarea class="wsa-userinput" ${credits.get()<=0 ? 'disabled="disabled"' : ''} tab-index="1" spellcheck="false" autocomplete="off"></textarea> <div class="wsa-controllers"> <div class="wsa-btn-group"> <button class="wsa-btn wsa-history-up" title="${this.lang['dictionary'].nav.lastestHistory}"><i class="fa-solid fa-clock-rotate-left fa-flip-horizontal"></i></button> <button class="wsa-btn wsa-history-down" title="${this.lang['dictionary'].nav.pastHistory}"><i class="fa-solid fa-clock-rotate-left"></i></button> <button class="wsa-btn wsa-history-clear" title="${this.lang['dictionary'].nav.clearHistory}"><i class="fa-solid fa-broom-wide"></i></button> </div> <div class="wsa-btn-group"> <button class="wsa-btn wsa-theme-change" wsa-current-theme="${this.theme}" title="${this.lang['dictionary'].nav.changeTheme}">${(this.theme==='light' ? '<i class="fa-solid fa-sun"></i>' : '<i class="fa-solid fa-moon-stars"></i>')}</button> <button class="wsa-btn wsa-clearBox" title="${this.lang['dictionary'].nav.clear}"><i class="fa-solid fa-eraser"></i></button> <button class="wsa-btn wsa-mic wsa-mic-muted" title="${this.lang['dictionary'].nav.mic}"><i class="fa-solid fa-microphone-slash"></i></button> <a href="https://github.com/XHiddenProjects/WebServerAI#readme" target="_blank"><button class="wsa-btn wsa-help" title="${this.lang['dictionary'].nav.help}"><i class="fa-solid fa-circle-question"></i></button></a> </div> <div class="wsa-btn-group"> <button class="wsa-btn wsa-dbq" title="${this.lang['dictionary'].nav.intxtdbl}"><i class="fa-solid fa-quotes"></i></button> <button class="wsa-btn wsa-sgq" title="${this.lang['dictionary'].nav.intxtsgl}"><i class="fa-solid fa-quote-left"></i></button> <button class="wsa-btn wsa-apt" title="${this.lang['dictionary'].nav.intxtaps}"><i class="fa-solid fa-apostrophe"></i></button> <button class="wsa-btn wsa-nl" title="${this.lang['dictionary'].nav.intxtnl}"><i class="fa-solid fa-file-dashed-line"></i></button> </div> </div> </div> </div> `; chatBox.appendChild(container); document.body.appendChild(chatBox); }else{ const el = document.querySelector(this.manualBox); if(el){ el.classList.add('wsa-userinput'); el.setAttribute('wsa-exclude',''); }else{ console.error(this.lang['dictionary'].console.chatBoxNotFound); document.write(''); return false; } } // VoiceType this.voice.getTranscript({ toggleBtn: '.wsa .wsa-mic', alternatives: 3, results: (event)=>{ const result = event.results[event.results.length - 1][0].transcript; document.querySelector('.wsa .wsa-userinput').value = result; }, error: (err)=>{ console.error(this.lang['dictionary'].console.voiceTypeSpeechError+': '+err.error); return; } }); if(this.previewBtn){ if(document.querySelector(this.previewBtn)){ document.querySelector(this.previewBtn).setAttribute('wsa-exclude',''); document.querySelector(this.previewBtn).addEventListener('click',()=>{ const preview = document.querySelector(this.preview), previewEditable = (preview.contentWindow||preview.contentDocument); preview.src = this.origin+'/WebServerAI/data/preview.html'; preview.addEventListener('load',()=>{ const parse = new DOMParser(); let htmlObject = parse.parseFromString(document.documentElement.innerHTML,'text/html'); htmlObject.documentElement.querySelectorAll('[wsa-exclude]').forEach((e)=>{e.remove();}); previewEditable.document.documentElement.innerHTML = htmlObject.documentElement.innerHTML; }); }); }else{ console.error(this.lang['dictionary']['console']['previewBtnNotFound']); document.write(''); return false; } } if(this.preview){ const preview = document.querySelector(this.preview); if(preview) preview.setAttribute('wsa-exclude',''); else{ console.error(this.lang['dictionary']['console']['previewNotFound']); document.write(''); return false; } } window.addEventListener('keydown',(e)=>{ let key = e.keyCode || e.which; if(e.ctrlKey&&key==79){ e.preventDefault(); const elem = document.querySelector('.wsa'); if( elem.getAttribute('wsa-stat')==='opened') elem.setAttribute('wsa-stat','closed'); else elem.setAttribute('wsa-stat','opened'); } if(this.preview){ if(!this.previewBtn){ if(e.ctrlKey&&key==80){ e.preventDefault(); const preview = document.querySelector(this.preview), previewEditable = (preview.contentWindow||preview.contentDocument); preview.src = this.origin+'/WebServerAI/data/preview.html'; preview.addEventListener('load',()=>{ const parse = new DOMParser(); let htmlObject = parse.parseFromString(document.documentElement.innerHTML,'text/html'); htmlObject.documentElement.querySelectorAll('[wsa-exclude]').forEach((e)=>{e.remove();}); previewEditable.document.documentElement.innerHTML = htmlObject.documentElement.innerHTML; }); } } } }); if(!this.manualBox){ document.querySelector('.wsa').addEventListener('mousedown',function(event){ if(!event.target.classList.contains('wsa-userinput')&&event.target.tagName.toLowerCase()!=='i'){ this.classList.add('dragging'); const pos = ['top left', 'top center' ,'top right', 'center left', 'center right' ,'bottom left', 'bottom center' ,'bottom right']; if(!document.querySelector('.wsa-drop-bubble')){ for(let i=0;i<pos.length;i++){ let x = document.createElement('div'); x.className = 'wsa-drop-bubble'; x.setAttribute('landing-pos',pos[i]); x.setAttribute('ondrop','DropBlock(event)'); x.setAttribute('ondragover','AllowDropBlock(event)'); document.body.appendChild(x); } } } },false); document.querySelector('.wsa').addEventListener('touchstart',function(event){ if(!event.target.classList.contains('wsa-userinput')&&event.target.tagName.toLowerCase()!=='i'){ this.classList.add('dragging'); const pos = ['top left', 'top center' ,'top right', 'center left', 'center right' ,'bottom left', 'bottom center' ,'bottom right']; if(!document.querySelector('.wsa-drop-bubble')){ for(let i=0;i<pos.length;i++){ let x = document.createElement('div'); x.className = 'wsa-drop-bubble'; x.setAttribute('landing-pos',pos[i]); x.addEventListener('click',(e)=>{ this.setAttribute('wsa-position',e.target.getAttribute('landing-pos')); this.classList.remove('dragging'); const bubbles = document.querySelectorAll('.wsa-drop-bubble'); for(let i=0;i<bubbles.length;i++){ bubbles[i].remove(); } }); document.body.appendChild(x); } } } },false); document.querySelector('.wsa').addEventListener('touchmove',function(event){ if(!event.target.classList.contains('wsa-userinput')&&event.target.tagName.toLowerCase()!=='i'){ this.classList.add('dragging'); const pos = ['top left', 'top center' ,'top right', 'center left', 'center right' ,'bottom left', 'bottom center' ,'bottom right']; if(!document.querySelector('.wsa-drop-bubble')){ for(let i=0;i<pos.length;i++){ let x = document.createElement('div'); x.className = 'wsa-drop-bubble'; x.setAttribute('landing-pos',pos[i]); x.addEventListener('click',(e)=>{ this.setAttribute('wsa-position',e.target.getAttribute('landing-pos')); this.classList.remove('dragging'); const bubbles = document.querySelectorAll('.wsa-drop-bubble'); for(let i=0;i<bubbles.length;i++){ bubbles[i].remove(); } }); document.body.appendChild(x); } } } },false); document.querySelector('.wsa').addEventListener('mouseup',function(){ this.classList.remove('dragging'); const bubbles = document.querySelectorAll('.wsa-drop-bubble'); for(let i=0;i<bubbles.length;i++){ bubbles[i].remove(); } }); document.querySelector('.wsa-theme-change').addEventListener('click',function(){ if(this.getAttribute('wsa-current-theme')==='light'){ this.setAttribute('wsa-current-theme', 'dark'); this.querySelector('i').className = 'fa-solid fa-moon-stars'; document.documentElement.setAttribute('wsa-theme','dark'); }else{ this.setAttribute('wsa-current-theme', 'light'); this.querySelector('i').className = 'fa-solid fa-sun'; document.documentElement.setAttribute('wsa-theme','light'); } document.querySelector('.wsa').setAttribute('wsa-theme',this.getAttribute('wsa-current-theme')); }); document.querySelector('.wsa-clearBox').addEventListener('click',()=>{ document.querySelector('.wsa-userinput').value = ''; }); document.querySelector('.wsa-history-clear').addEventListener('click',()=>{ document.querySelector('.wsa-ui .wsa-history').innerHTML = ''; this.history = []; this.request(window.location.origin+'/WebServerAI/libs/history.php?action=delete'); console.clear(); this.cmdID = 0; }); document.querySelector('.wsa-dbq').addEventListener('click',()=>{ const txtarea = document.querySelector('.wsa-userinput'); this.#replaceSelection(txtarea, '\\\"'+this.#getSel(txtarea)+'\\\"'); }); document.querySelector('.wsa-sgq').addEventListener('click',()=>{ const txtarea = document.querySelector('.wsa-userinput'); this.#replaceSelection(txtarea, '\\\''+this.#getSel(txtarea)+'\\\''); }); document.querySelector('.wsa-apt').addEventListener('click',()=>{ const txtarea = document.querySelector('.wsa-userinput'); this.#replaceSelection(txtarea, this.#getSel(txtarea)+'\\\`'); }); document.querySelector('.wsa-nl').addEventListener('click',()=>{ const txtarea = document.querySelector('.wsa-userinput'); this.#replaceSelection(txtarea, this.#getSel(txtarea)+'\\n'); }); const txtarea = document.querySelector('.wsa-userinput'), historyUp = document.querySelector('.wsa-history-up'), historyDown = document.querySelector('.wsa-history-down'); var inc=0; txtarea.addEventListener('keydown',(e)=>{ let k = e.keyCode || e.which; //38 = up; 40 = down if(k==38){ e.preventDefault(); inc+=1; if(inc > this.history.length-1){ inc = 0; } txtarea.value = (this.history[inc] ? this.history[inc].replaceAll('&#34;','"').replaceAll('&#39;',"'").replaceAll('\\,',',') : ''); }else if(k==40){ e.preventDefault(); inc-=1; if(inc < 0){ inc = this.history.length-1; } txtarea.value = (this.history[inc] ? this.history[inc].replaceAll('&#34;','"').replaceAll('&#39;',"'").replaceAll('\\,',',') : ''); } }); historyUp.addEventListener('click',()=>{ inc+=1; if(inc > this.history.length-1){ inc = 0; } txtarea.value = (this.history[inc] ? this.history[inc].replaceAll('&#34;','"').replaceAll('&#39;',"'").replaceAll('\\,',',') : ''); }); historyDown.addEventListener('click',()=>{ inc-=1; if(inc < 0){ inc = this.history.length-1; } txtarea.value = (this.history[inc] ? this.history[inc].replaceAll('&#34;','"').replaceAll('&#39;',"'").replaceAll('\\,',',') : ''); }); } window.addEventListener('load',()=>{ const sc = document.createElement('script'); sc.src = this.origin+'/WebServerAI/assets/AI/js/components/dragdrop.min.js'; sc.type = 'text/javascript'; sc.setAttribute('wsa-exclude',''); document.body.appendChild(sc); }); //hover selected element if(this.cte){ document.querySelector('html[wsa-active]').addEventListener('mouseover',(e)=>{ if(!e.target.matches('.wsa, .wsa *, .wsa-drop-bubble, .wsa-targetName, pre code, pre code *, code * , html, .code-toolbar .toolbar, .code-toolbar .toolbar *, .wpa-build-gps, .wpa-build-gps *, body')){ e.target.setAttribute('wsa-elemfocus',''); e.target.addEventListener('mouseout',(o)=>{ e.target.removeAttribute('wsa-elemfocus'); if(document.querySelector('.wsa-targetName')) document.querySelector('.wsa-targetName').remove(); e.target.removeAttribute('wsa-target-container'); }); const elem = document.createElement('div'); elem.classList.add('wsa-targetName'); elem.setAttribute('wsa-exclude',''); elem.innerHTML = `<div class="wsa-title-bag"> <div> <span class="wsa-target-tag">`+e.target.tagName+`</span><span class="wsa-target-attr">`+ (e.target.id ? '#'+e.target.id : '') + (e.target.classList.length > 0 ? '.'+e.target.className.replace(' ','.') : '')+`</span></div> <div class="wsa-swh">`+(isDecimal(e.target.getBoundingClientRect().width) ? e.target.getBoundingClientRect().width.toFixed(2) : e.target.getBoundingClientRect().width)+` x `+(isDecimal(e.target.getBoundingClientRect().height) ? e.target.getBoundingClientRect().height.toFixed(1) : e.target.getBoundingClientRect().height)+` </div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Background</span> <div class="wsa-color-info"> <span style="background-color:`+rgbaToHex(window.getComputedStyle(e.target,null).backgroundColor)+`;"></span> <span>`+ rgbaToHex(window.getComputedStyle(e.target,null).backgroundColor)+`</span> </div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Color</span> <div class="wsa-color-info"> <span style="background-color:`+rgbaToHex(window.getComputedStyle(e.target,null).color)+`;"></span> <span>`+ rgbaToHex(window.getComputedStyle(e.target,null).color)+`</span> </div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Font</span> <div class="wsa-font-info"> `+(window.getComputedStyle(e.target,null).font)+` </div> </div> `+(parseInt(window.getComputedStyle(e.target,null).margin)!=0 ? ` <div class="wsa-title-bag"> <span class="wsa-swh">Margin</span> <div class="wsa-font-info"> `+(window.getComputedStyle(e.target,null).margin)+` </div> </div> </div>` : ``)+ (parseInt(window.getComputedStyle(e.target,null).padding)!=0 ? ` <div class="wsa-title-bag"> <span class="wsa-swh">Padding</span> <div class="wsa-font-info"> `+(window.getComputedStyle(e.target,null).padding)+` </div> </div> </div>` : ``)+` <span>Accessibility------------------------------------</span> <div class="wsa-title-bag"> <span class="wsa-swh">Contrast</span> <div class="wsa-font-info"> <i class="fa-solid fa-font-case" style="font-size:12px;border:1px solid #000;padding:3px;"></i> `+calculateContrastRatio(window.getComputedStyle(e.target).color, window.getComputedStyle(e.target).backgroundColor)+` `+(calculateContrastRatio(window.getComputedStyle(e.target).color, window.getComputedStyle(e.target).backgroundColor,false) ? `<i class="fa-regular fa-circle-check" style="color: #008000;"></i>` : `<i class="fa-regular fa-circle-exclamation" style="color: #ffa500;"></i>`)+` </div> </div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Name</span> <div class="wsa-name-info">`+(e.target.hasAttribute('aria-name')&&!e.target.getAttribute('aria-name').match('null') ? e.target.getAttribute('aria-name') : '')+`</div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Role</span> <div class="wsa-role-info"> `+(e.target.getAttribute('role')||e.target.getAttribute('aria-role'))+` </div> </div> <div class="wsa-title-bag"> <span class="wsa-swh">Keyboard-focusable</span> <div class="wsa-role-info"> `+(keyboardFocusable(e.target) ? `<i class="fa-regular fa-circle-check" style="color: #008000;"></i>` : `<i class="fa-solid fa-ban" style="color: #808080;"></i>`)+` </div> </div> `; const width = window.innerWidth; elem.style.left = (e.clientX<=(width-300) ? e.clientX : width-300)+'px'; elem.style.top = (e.clientY+20)+'px'; document.body.appendChild(elem); document.body.setAttribute('wsa-target-container',''); } }); document.querySelector('html[wsa-active]').addEventListener('click',(e)=>{ if(e.ctrlKey){ if(!e.target.matches('.wsa, .wsa *, .wsa-drop-bubble, .wsa-targetName, pre code, pre code *, code * , html, .code-toolbar .toolbar, .code-toolbar .toolbar *, .wpa-build-gps, .wpa-build-gps *, input, body, [wsa-noselect], [wsa-noselect] *')){ const uit = this.#branchLoad(e.target); document.querySelector('.wsa-userinput').value+='"'+uit+'"'; } } }); document.querySelector('html[wsa-active]').addEventListener('touchstart',(e)=>{ if(!e.target.matches('.wsa, .wsa *, .wsa-drop-bubble, .wsa-targetName, pre code, pre code *, code * , html, .code-toolbar .toolbar, .code-toolbar .toolbar *, .wpa-build-gps, .wpa-build-gps *, input, body, [wsa-noselect], [wsa-noselect] *')){ const uit = this.#branchLoad(e.target); document.querySelector('.wsa-userinput').value+='"'+uit+'"'; } }); } } var screenY=0; if(document.querySelector('.wsa')){ document.querySelector('.wsa').addEventListener('touchmove',function(e){ if(e.touches[0].screenY<screenY) this.setAttribute('wsa-stat','opened'); else this.setAttribute('wsa-stat','closed'); screenY = e.touches[0].screenY; }); } window.addEventListener('load',()=>{ //syntax hightlight const hightlightStyle = document.createElement('link'), highlightScript = document.createElement('script'); hightlightStyle.href = this.origin+'/WebServerAI/assets/AI/css/prismjs/'+codeTheme+'/prism.min.css'; hightlightStyle.rel = 'stylesheet'; hightlightStyle.type = 'text/css'; document.head.appendChild(hightlightStyle); highlightScript.src = this.origin+'/WebServerAI/assets/AI/js/prismjs/prism.min.js'; highlightScript.type = 'text/javascript'; document.body.appendChild(highlightScript); const animationScript = document.createElement('script'); animationScript.src = 'https://cdn.jsdelivr.net/gh/XHiddenProjects/WebAnimate@0.0.5/assets/webanimate.js'; animationScript.type='text/javascript'; document.body.appendChild(animationScript); }); } #updateCredits(txt,submitBtn){ if(credits.get()<=0){ txt.classList.add('disabled'); submitBtn.disabled = true; } const x = setInterval((box=txt)=>{ if(box.classList.contains('disabled')){ box.disabled = true; box.classList.remove('disabled'); clearInterval(x); } },1500); } /** * Triggers on users input from textarea * @param {Function} callback The function that will activate on submit * @returns {String} The Users input */ submit(callback){ if(this.enabled){ if(credits.get()>0){ const txt = (!this.manualBox ? document.querySelector('.wsa-ui textarea') : document.querySelector(this.manualBox)), submitbtn = (!this.submitBtn ? document.querySelector('.wsa-ui .wsa-editor-send') : document.querySelector(this.submitBtn)); txt.addEventListener('keydown', (e)=>{ let key = e.keyCode || e.which; if((key===13&&(!this.isNull&&txt.value!==''))||(key===13&&this.isNull)){ e.preventDefault(); callback(this.#filter(txt.value)); setTimeout(()=>{ this.#updateCredits(txt,submitbtn); this.#clearTextbox(); },500); } }); submitbtn.addEventListener('click',(e)=>{ if((!this.isNull&&txt.value!=='')||this.isNull){ e.preventDefault(); callback(this.#filter(txt.value)); setTimeout(()=>{ this.#updateCredits(txt,submitbtn); this.#clearTextbox(); },500); } }); }else alert(this.lang['dictionary']['ai']['noCredits']+credits.renew()); } } /** * Clears out textbox */ #clearTextbox(){ if(this.enabled){ const txt = document.querySelector('.wsa-userinput'); txt.value = ''; } } /** * Returns the information * @param {Function} callback Get the results after submit */ results(callback){ callback(this.responces); } /** * Filters out special characters * @param {String} str String to filter * @returns {String} Filtered string */ #filter(str){ var lt = /</g, gt = />/g, ap = /'/g, ic = /"/g; return str.toString().replace(lt, "&lt;").replace(gt, "&gt;").replace(ap, "&#39;").replace(ic, "&#34;"); } #cmds(str){ let canReturn = true, lastID=0; if(str.match(/^wsa --clear$/)){ let matches = str.match(/^wsa --clear$/); document.querySelector('.wsa-ui .wsa-history').innerHTML = ''; this.history = []; this.cmdID = 0; document.querySelector('.wsa-userinput').disabled = false; console.clear(); canReturn = false; } if(str.match(/^wsa --preview$/)){ const match = str.match(/^wsa --preview$/); if(match){ const preview = window.open(this.origin+'/WebServerAI/data/preview.html','_blank','width='+this.previewBox.width+',height='+this.previewBox.height); preview.addEventListener('load',()=>{ const parse = new DOMParser(); let htmlObject = parse.parseFromString(document.documentElement.innerHTML,'text/html'); htmlObject.documentElement.querySelectorAll('[wsa-exclude]').forEach((e)=>{e.remove();}); preview.document.documentElement.innerHTML = htmlObject.documentElement.innerHTML; }); } canReturn = false; } if(str.match(/^wsa --info$/)){ setTimeout(()=>{ this.createCmd(this.botName, this.lang['dictionary'].name+': '+this.botName+'<br/>'+this.lang['dictionary'].version+' '+this.botInfo['Version']+'<br/>'+this.lang['dictionary'].updated+': '+ this.botInfo['Updated'], 'info'); document.querySelector('.wsa-userinput').disabled = false; },this.botInfo['ResponceTime']); canReturn = false; } if(str.match(/^wsa --connect (.*?)$/)){ const matches = str.match(/^wsa --connect (.*?)$/); window.open(matches[1],'_self'); document.querySelector('.wsa-userinput').disabled = false; canReturn = false; } if(str.match(/^wsa --help$/)){ setTimeout(()=>{ this.createCmd(this.botName, ` <b>help</b> - `+this.lang['dictionary'].cmd.help+`<br/> <b>clear{:int?}</b> - `+this.lang['dictionary'].cmd.clear+`<br/> <b>info</b> - `+this.lang['dictionary'].cmd.info+`<br/> <b>connect {url}</b> - `+this.lang['dictionary'].cmd.connect+`<br/> <b>preview</b> - `+this.lang['dictionary'].cmd.preview+`<br/> `,'info'); document.querySelector('.wsa-userinput').disabled = false; },this.botInfo['ResponceTime']); canReturn = false; } return canReturn; } createCmd(user,msg, type="normal", options=[]){ const ui = (!this.historyStorage ? document.querySelector('.wsa-ui .wsa-history') : document.querySelector(this.historyStorage)), addElem = document.createElement('div'); const tid = [], tname = []; let fixStr = ''; if(ui){ if(options.hasOwnProperty('taskInfo')){ options.taskInfo.forEach((opt)=>{ opt.forEach((item)=>{ tid.push(item.task_id); tname.push((item.task_name).toLocaleLowerCase()); }); }); for(let i=0;i<tid.length;i++){ fixStr+=tid[i] + ' ' + tname[i] + ', '; } msg = msg.replaceAll('{{task_info}}',fixStr.replace(/, ?$/,'').replace(/,([^,]+)$/,' and $1')); } addElem.setAttribute('wsa-cmdID',(this.cmdID+=1)); addElem.setAttribute('wsa-cmdType',type); addElem.innerHTML = `<p class="wsa-user">`+user+`:</p>`; addElem.innerHTML += `<p class="wsa-cmd"><span class="wsa-txt">`+msg+`</span> <button class="wsa-copymsg"><i class="fa-solid fa-copy"></i></button></p>`; addElem.classList.add('wsa-history-item'); addElem.querySelector('button').addEventListener('click',()=>{ navigator.clipboard.writeText(addElem.querySelector('button').parentElement.querySelector('.wsa-txt').innerText) .then(() => alert(this.lang['dictionary'].clipboard.success)) .catch((error) => alert(this.lang['dictionary'].clipboard.error, error)); }); ui.appendChild(addElem); if(type!=='normal') { aiVoice.speak(msg); } } } addCmd(msg){ const filterWords = this.botInfo['blockWords'].concat(this.botInfo['blockDomains']); msg = filter(msg, filterWords); let rsp = this.request(this.origin+'/WebServerAI/libs/ai_sender.php?wsaai='+encodeURIComponent(msg)), res = this.listen.render(rsp, this.preview); this.responces = res; if(res){ const tinfo = []; setTimeout(()=>{ res.forEach((res) => { if(res.task_info){ tinfo.push(res.task_info); } }); this.createCmd(this.botName, this.lang['dictionary'].ai.success, 'success',{taskInfo:tinfo}); document.querySelector('.wsa-userinput').disabled = false; },this.botInfo['ResponceTime']); }else{ setTim