diff --git a/OpenScript.js b/OpenScript.js index 996d7c2..e3764f1 100644 --- a/OpenScript.js +++ b/OpenScript.js @@ -1317,6 +1317,10 @@ var OpenScript = { } root.append(rootFrag); + + root.toString = function(){ + return this.outerHTML; + } if(parent) { @@ -1455,25 +1459,7 @@ var OpenScript = { * @param {string|HTMLElement} value */ toElement = (value) => { - - if(value instanceof DocumentFragment || value instanceof HTMLElement) { - return value; - } - - if(value?.length === 0) return this.dom.createTextNode(''); - - let tmp = this.dom.createElement("ojs-group"); - tmp.innerHTML = value; - - if(tmp.children.length > 1) return tmp; - - if(tmp.children.length === 0 - && - tmp.firstChild.nodeName === "#text" - ) return this.dom.createTextNode(value); - - - return tmp.children[0]; + return value; } }, @@ -1560,6 +1546,141 @@ var OpenScript = { } return text.replace(/\./g, "/"); } + + /** + * Splits a file into smaller strings + * based on the class in that file + */ + Splitter = class Splitter { + + /** + * Gets the class Signature + * @param {string} content + * @param {int} start + * @param {object<>} signature {name: string, signature: string, start: number, end: number} + */ + classSignature(content, start) { + const signature = {name: '', definition: '', start: -1, end: -1, parent: null}; + + let startAt = start; + + let output = []; + let tmp = ''; + + let pushTmp = (index) => { + if(tmp.length === 0) return; + + if(output.length === 0) startAt = index; + + output.push(tmp); + tmp = ''; + } + + for(let i = start; i < content.length; i++){ + let ch = content[i]; + + if(/[\s\r\t\n]/.test(ch)) { + pushTmp(i); + + continue; + } + + if(/\{/.test(ch)) { + pushTmp(i); + signature.end = i; + + break; + } + + tmp += ch; + } + + signature.start = startAt; + + if(output.length % 2 !== 0) throw Error(`Invalid Class File. Could not parse \`${content}\` from index ${start} because it doesn't have the proper syntax. ${content.substring(start)}`); + + if(output.length > 2) { + signature.parent = output[3]; + } + + signature.name = output[1]; + signature.definition = output.join(' '); + + return signature; + } + + /** + * Splits the content of the file by + * class + * @param {string} content file content + * @return {Map} class map + */ + classes(content) { + + content = content.trim(); + + const stack = []; + const map = new Map(); + const qMap = new Map([[`'`, true], [`"`, true], ["`", true]]); + + + let index = 0; + let code = ''; + + while(index < content.length){ + + let signature = this.classSignature(content, index); + index = signature.end; + + let ch = content[index]; + stack.push(ch); + + code += signature.definition + ' '; + code += ch; + + let text = []; + + index++; + + while(stack.length && index < content.length){ + ch = content[index]; + code += ch; + + if(qMap.has(ch)){ + + text.push(ch); + index++; + + while(text.length && index < content.length){ + ch = content[index]; + code += ch; + + let last = text.length - 1; + + if(qMap.has(ch) && ch === text[last]) { + text.pop(); + } + else if(ch === '\n' && (text[last] === '"' || text[last] === "'")) { + text.pop(); + } + + index++; + } + continue; + } + if(/\{/.test(ch)) stack.push(ch); + if(/\}/.test(ch)) stack.pop(); + + index++; + } + + map.set(signature.name, {extends: signature.parent, code, name: signature.name, signature: signature.definition}); + code = ''; + } + + return map; + } + } /** * @@ -1574,14 +1695,7 @@ var OpenScript = { let response = await fetch(`${this.dir}/${this.normalize(fileName)}${this.extension}?v=${this.version}`); let classes = await response.text(); - - let matches = classes.match(/class\s+[A-Za-z]+/g); - - - // checking if there is only one class - if(matches && matches.index) matches = [matches[0]]; - - classes = classes.split(/class\s+[A-Za-z]+/g); + let content = classes; let classMap = new Map(); let codeMap = new Map(); @@ -1591,31 +1705,20 @@ var OpenScript = { let prefix = prefixArray.join('.'); if(prefix.length > 0 && !/^\s+$/.test(prefix)) prefix += '.'; - classes.shift(); + let splitter = new this.Splitter(); - for(let k in classes){ - if(classes[k].length === 0 || /^[\s+\n+\r+\t+]*$/.test(classes[k])) continue; - - classes[k] = classes[k].trim(); - matches[k] = matches[k].trim(); - - let m = matches[k].match(/\s+/); - let name = matches[k].substring(m['index'])?.trim(); - - let key = prefix + name; - - classMap.set(key, [name, `${matches[k]} ${classes[k]}`]); + classes = splitter.classes(content); + for(let [k, v] of classes){ + let key = prefix + k; + classMap.set(key, [k, v.code]); } for(let [k, arr] of classMap){ - let inheritance = arr[1].match(/extends[\s\n]+\s*.+\s*[\s\n]+\{/); + let parent = classes.get(arr[0]).extends; - if(inheritance) { - - let parent = inheritance[0].replace(/[\n\s\{]+/g, " "); - parent = parent.replace(/extends/g, "").trim(); + if(parent) { let original = parent; @@ -1639,10 +1742,12 @@ var OpenScript = { } } else { - let replacement = inheritance[0].replace(original, parent); + let signature = classes.get(arr[0]).signature; + + let replacement = signature.replace(original, parent); //console.log(k, arr[1]); - let c = arr[1].replace(inheritance[0], replacement); + let c = arr[1].replace(signature, replacement); arr[1] = c; } }