function escapeHtml(text) { var map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, function(m) { return map[m]; }); } function highlightText(searchText, container_selector, selectors = []) { const container = u(container_selector) const regexp = new RegExp(`(${searchText})`, 'gi') function highlightNode(node) { if(node.nodeType == 3) { let newNode = escapeHtml(node.nodeValue) newNode = newNode.replace(regexp, (match, ...args) => { return `${escapeHtml(match)}` }) const tempDiv = document.createElement('div') tempDiv.innerHTML = newNode while(tempDiv.firstChild) { node.parentNode.insertBefore(tempDiv.firstChild, node) } node.parentNode.removeChild(node) } else if(node.nodeType === 1 && node.tagName !== 'SCRIPT' && node.tagName !== 'BR' && node.tagName !== 'STYLE' && !node.classList.contains('highlight')) { Array.from(node.childNodes).forEach(highlightNode); } } selectors.forEach(selector => { elements = container.find(selector) if(!elements || elements.length < 1) return; elements.nodes.forEach(highlightNode) }) } String.prototype.escapeHtml = function() { try { return escapeHtml(this) } catch(e) { return '' } } function fmtTime(time) { const mins = String(Math.floor(time / 60)).padStart(2, '0'); const secs = String(Math.floor(time % 60)).padStart(2, '0'); return `${ mins}:${ secs}`; } function fastError(message) { MessageBox(tr("error"), message, [tr("ok")], [Function.noop]) } function humanFileSize(bytes, si) { var thresh = si ? 1000 : 1024; if(Math.abs(bytes) < thresh) { return bytes + ' B'; } var units = si ? ['kB','MB','GB','TB','PB','EB','ZB','YB'] : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']; var u = -1; do { bytes /= thresh; ++u; } while(Math.abs(bytes) >= thresh && u < units.length - 1); return bytes.toFixed(1)+' '+units[u]; } function trim(string) { var newStr = string.substring(0, 10); if(newStr.length !== string.length) newStr += "…"; return newStr; } function trimNum(string, num) { return ovk_proc_strtr(string, num); } function ovk_proc_strtr(string, length = 0) { const newString = string.substring(0, length); return newString + (string !== newString ? "…" : ""); } function chunkSubstr(string, size) { const numChunks = Math.ceil(string.length / size); const chunks = new Array(numChunks); for (let i = 0, o = 0; i < numChunks; ++i, o += size) { chunks[i] = string.substr(o, size); } return chunks; } function random_int(min, max) { return Math.round(Math.random() * (max - min) + min) } function makeError(text, color = 'Red', timeout = 10000, uid = 0) { const rand_id = uid != 0 ? uid : random_int(0, 10000) if(uid != 0 && u(`.upLeftErrors .upLeftError[data-id='${uid}']`).length > 0) { return } u('.upLeftErrors').append(`
${escapeHtml(text)}
`) setTimeout(() => { u(`.upLeftError[data-id='${rand_id}']`).remove() }, timeout) } function array_splice(array, key) { let resultArray = []; for(let i = 0; i < array.length; i++){ if(i != key){ resultArray.push(array[i]); } } return resultArray; } function strip_tags(text) { return text.replace(/(<([^>]+)>)/gi, "") } function find_author(id, profiles, groups) { if(id > 0) { const profile = profiles.find(prof => prof.id == id) if(profile) { return profile } } else { const group = groups.find(grou => grou.id == Math.abs(id)) if(group) { return group } } return null } function collect_attachments(target) { const horizontal_array = [] const horizontal_attachments = target.find(`.post-horizontal > a`) horizontal_attachments.nodes.forEach(_node => { horizontal_array.push(`${_node.dataset.type}${_node.dataset.id}`) }) const vertical_array = [] const vertical_attachments = target.find(`.post-vertical > .vertical-attachment`) vertical_attachments.nodes.forEach(_node => { vertical_array.push(`${_node.dataset.type}${_node.dataset.id}`) }) return horizontal_array.concat(vertical_array) } function getRemainingTime(fullTime, time) { let timer = fullTime - time if(timer < 0) return "-00:00" return "-" + fmtTime(timer) } function serializeForm(form, submitter = null) { const u_ = u(form) const inputs = u_.find('input, textarea, button, select') let fd = new FormData() inputs.nodes.forEach(inp => { if(!inp || !inp.name) { return } if(inp.type == 'submit') { if(inp !== submitter) { return } } switch(inp.type) { case 'hidden': case 'text': case 'textarea': case 'select': case 'select-one': case 'submit': case 'email': case 'phone': case 'search': case 'password': case 'date': case 'datetime-local': fd.append(inp.name, inp.value) break case 'checkbox': if(inp.checked) { fd.append(inp.name, inp.value) } break case 'file': if(!inp.multiple) { if(inp.files[0]) { fd.append(inp.name, inp.files[0]) } else { const emptyFile = new Blob([], { type: 'application/octet-stream' }) fd.append(inp.name, emptyFile, '') } } break } }) return fd } async function copyToClipboard(text) { let fallback = () => { prompt(text); } if(typeof navigator.clipboard == "undefined") { fallback() } else { try { await navigator.clipboard.writeText(text) } catch(e) { fallback() } } } function remove_file_format(text) { return text.replace(/\.[^.]*$/, '') } function sleep(time) { return new Promise((resolve) => setTimeout(resolve, time)); }