UNPKG

derya

Version:

Multi-Parser & Code-Generator, developed with TypeScript on node.js.

670 lines (628 loc) 27.6 kB
//Imports import {Grabber, TableValues} from "./grabber"; import * as sys from "samara"; import * as uniques from "./ref/html_tags_unique.json"; //Constants const generatedMethods:string = "//Generated-Methods"; const url_css_functions:string = "https://www.w3schools.com/cssref/css_functions.asp"; const url_css_properties:string = "https://www.w3schools.com/cssref/default.asp"; const url_css_selectors:string = "https://www.w3schools.com/cssref/css_selectors.asp"; const url_html_event_atts:string = "https://www.w3schools.com/TAGS/ref_eventattributes.asp"; const url_html_global_atts:string = "https://www.w3schools.com/TAGS/ref_standardattributes.asp"; const url_html_tags:string = "https://www.w3schools.com/TAGS/default.ASP"; //Classes export class Generator{ //Declarations //Constructor constructor(){ } //Methods async createCSSFunctions(){ console.log("createCSSFunctions"); let grabber:Grabber = new Grabber(url_css_functions); await grabber.read(); let tableValues:TableValues = grabber.getTable("<h2>CSS Functions</h2>"); let values:string[] = []; for(let row of tableValues.rows){ //console.log("ROW0: " + row[0]); let value:string = row[0]; value = sys.removeTags(value).trim().toLowerCase(); //console.log("VALUE: " + value); values.push(value); } this.saveCSSFunctions(values); } async createCSSProperties(){ console.log("createCSSProperties"); let grabber:Grabber = new Grabber(url_css_properties); await grabber.read(); let char:string = "A"; let count:number = 0; let emptyProperties:string[] = []; let properties:CSSProperty[] = []; while(count < 26){ //console.log("CHAR: " + char); if(grabber.sc.indexOf("<h2>" + char + "</h2>") > -1){ //console.log("CHAR: " + char); let tableValues:TableValues = grabber.getTable("<h2>" + char + "</h2>"); for(let row of tableValues.rows){ //console.log("ROW: " + row[0]); if(row[0].indexOf("href") > -1){ let url:string = "https://www.w3schools.com/cssref/" + this.extractHREF(row[0]); //console.log("URL: " + url); let grabber:Grabber = new Grabber(url); await grabber.read(); let name = extractName(grabber.sc); //console.log("NAME: " + name); let tableValues:TableValues = grabber.getTable("<h2>Property Values</h2>"); let subValues:string[] = []; for(let attValues of tableValues.rows){ let value:string = attValues[0]; if(value.indexOf("<") > -1){ //console.log("TTT: " + value); if(value.indexOf("<br>") < 0){ value = "#" + sys.removeTags(value).trim().toLowerCase(); subValues.push(value); }else{ let split:string[] = value.split("<br>"); for(let value of split){ value = value.trim().toLowerCase() if(!sys.isNull(value)){ if(value.indexOf("<") > -1){ value = "#" + sys.removeTags(value).trim().toLowerCase(); subValues.push(value); }else{ subValues.push(value.trim().toLowerCase()); } } } } }else{ subValues.push(value.trim().toLowerCase()); } } //console.log("VALUE: " + subValues); properties.push(new CSSProperty(name, subValues)); }else{ emptyProperties.push(row[0]); } } } char = nextChar(char); count++; } this.saveCSSProperties(properties, emptyProperties); //console.log("PROPERTIES: " + properties); //SubFunctions function extractName(str:string):string{ str = str.substring(str.indexOf("<h1>"), str.length); str = str.substring(str.indexOf("<span"), str.length); str = str.substring(str.indexOf(">") + 1, str.length); str = str.substring(0, str.indexOf("</span>")); return str.trim().toLowerCase(); } function nextChar(char:string):string{ return String.fromCharCode(char.charCodeAt(0) + 1); } } async createCSSSelectors(){ console.log("createCSSSelectors"); let grabber:Grabber = new Grabber(url_css_selectors); await grabber.read(); let tableValues:TableValues = grabber.getTable("<h2>CSS Selectors</h2>"); let values:string[] = []; for(let row of tableValues.rows){ //console.log("ROW0: " + row[0]); let value:string = row[0]; value = sys.removeTags(value).trim().toLowerCase(); //console.log("VALUE: " + value); values.push(value); } this.saveCSSSelectors(values); } async createHTMLEventAttributes(){ console.log("createHTMLEventAttributes"); let grabber:Grabber = new Grabber(url_html_event_atts); await grabber.read(); let events_window:string[] = extractEvents("<h2>Window Event Attributes</h2>"); let events_form:string[] = extractEvents("<h2>Form Events</h2>"); let events_keyboard:string[] = extractEvents("<h2>Keyboard Events</h2>"); let events_mouse:string[] = extractEvents("<h2>Mouse Events</h2>"); let events_drag:string[] = extractEvents("<h2>Drag Events</h2>"); let events_clipboard:string[] = extractEvents("<h2>Clipboard Events</h2>"); let events_media:string[] = extractEvents("<h2>Media Events</h2>"); let events_misc:string[] = extractEvents("<h2>Misc Events</h2>"); this.saveHTMLEventAttributes(events_window, events_form, events_keyboard, events_mouse, events_drag, events_clipboard, events_media, events_misc); //SubFunctions function extractEvents(search:string):string[]{ let tableValues:TableValues = grabber.getTable(search); let events:string[] = []; for(let row of tableValues.rows){ let event:string = row[0]; if(event.indexOf("<") > -1){ event = event.substring(event.indexOf(">") + 1, event.length); event = event.substring(0, event.indexOf("<")); } event = event.trim().toLowerCase(); events.push(event); } return events; } } async createHTMLGlobalAttributes(){ console.log("createHTMLGlobalAttributes"); let grabber:Grabber = new Grabber(url_html_global_atts); await grabber.read(); let tableValues:TableValues = grabber.getTable("<h2>HTML Global Attributes</h2>"); let values:HTMLAttribute[] = []; for(let row of tableValues.rows){ let url:string = "https://www.w3schools.com/TAGS/" + this.extractHREF(row[0]); let grabber:Grabber = new Grabber(url); await grabber.read(); let name = extractName(grabber.sc); let tableValues:TableValues = grabber.getTable("<h2>Attribute Values</h2>"); let subValues:string[] = []; for(let attValues of tableValues.rows){ let attValue:string = attValues[0].toLowerCase(); if(attValue.indexOf("<") > -1){ attValue = "#" + sys.removeTags(attValue); } subValues.push(attValue); } values.push(new HTMLAttribute(name, subValues)); } this.saveHTMLGlobalAttributes(values); //SubFunctions function extractName(str:string):string{ str = str.substring(str.indexOf("<h1>"), str.length); str = str.substring(str.indexOf("<span"), str.length); str = str.substring(str.indexOf(">") + 1, str.length); str = str.substring(0, str.indexOf("</span>")); return str.trim().toLowerCase(); } } async createHTMLTags(){ console.log("createHTMLTags"); let grabber:Grabber = new Grabber(url_html_tags); await grabber.read(); let tableValues:TableValues = grabber.getTable("<h2>HTML Tags Ordered Alphabetically</h2>"); let values:HTMLTag[] = []; for(let row of tableValues.rows){ if(row[1].indexOf("Not supported in HTML5.") < 0){ let url:string = "https://www.w3schools.com/TAGS/" + this.extractHREF(row[0]); //console.log("URL: " + url); if(!this.isForbiddenURL(url)){ let grabber:Grabber = new Grabber(url); await grabber.read(); let name:string = extractName(grabber.sc); //console.log("Name: " + name); let closed:Boolean = isClosed(grabber.sc, name); //console.log("Closed: " + closed); let events:Boolean = supportsEvents(grabber.sc, name); //console.log("Events: " + events); let globals:Boolean = supportsGlobals(grabber.sc, name); //console.log("Globals: " + globals); let unique:Boolean = isUnique(name); //console.log("Unique: " + unique); let tag:HTMLTag = new HTMLTag(name, closed, events, globals, unique); let tableValues:TableValues = grabber.getTable("<h2>Attributes</h2>"); for(let tableValue of tableValues.rows){ //console.log("ATTS: " + tableValue[0] + " || " + tableValue[1]); let attname:string = tableValue[0]; attname = attname.substring(attname.indexOf(">") + 1, attname.length); attname = attname.substring(0, attname.indexOf("<")).trim().toLowerCase(); //console.log("Attname: " + attname); let split:string[] = tableValue[1].split("<br>"); let vals:string[] = []; for(let val of split){ if(!sys.isNull(val)){ val = val.trim().toLowerCase(); if(val.indexOf("<") > -1){ val = "#" + sys.removeTags(val); } //console.log("Attval: " + val); vals.push(val); } } tag.addAttribute(new HTMLAttribute(attname, vals)); } values.push(tag); } } } this.saveHTMLTags(values); //SubFunctions function extractName(sc:string):string{ sc = sc.substring(sc.indexOf("<h1>"), sc.length); sc = sc.substring(sc.indexOf("&lt;") + 4, sc.length); sc = sc.substring(0, sc.indexOf("&gt;")); sc = sys.removeAll(sc, "!") return sc.trim().toLowerCase(); } function isClosed(sc:string, name:string):Boolean{ if(sc.indexOf("/" + name) > -1){ return true; }else{ return false; } } function isUnique(name:string):Boolean{ for(let tag of uniques.tags){ if(tag === name){ return true; } } return false; } function supportsEvents(sc:string, name:string):Boolean{ if(sc.indexOf("<a href=\"ref_eventattributes.asp\">Event Attributes in HTML</a>") > -1){ return true; }else{ return false; } } function supportsGlobals(sc:string, name:string):Boolean{ if(sc.indexOf("<a href=\"ref_standardattributes.asp\">Global Attributes in HTML</a>") > -1){ return true; }else{ return false; } } } extractHREF(str:string):string{ if(str.indexOf("href=\"") > -1){ str = str.substring(str.indexOf("href=\"") + 6, str.length); str = str.substring(0, str.indexOf("\"")); } return str; } generateSourcecode(){ console.log("generateSourcecode"); let adds:string[] = []; let closes:string[] = []; let opens:string[] = []; let atts:string[] = []; let styles:string[] = []; let json = JSON.parse(sys.readFile("./lib/ref/html_tags.json")); for(let tag of json.tags){ //console.log("TAG: " + tag.name); if(tag.closed){ closes.push(tag.name); opens.push(tag.name); }else{ adds.push(tag.name); } for(let att of tag.attributes){ if(!exists(atts, att.name)){ //console.log("X1: " + att.name); atts.push(att.name); } } } json = JSON.parse(sys.readFile("./lib/ref/html_event_attributes.json")); for(let att of json.attributes){ if(!exists(atts, att.name)){ //console.log("X2: " + att.name); atts.push(att.name); } } json = JSON.parse(sys.readFile("./lib/ref/html_global_attributes.json")); for(let att of json.attributes){ if(!exists(atts, att.name)){ //console.log("X3: " + att.name); atts.push(att.name); } } json = JSON.parse(sys.readFile("./lib/ref/css_properties.json")); for(let prop of json.properties){ styles.push(prop.name); } for(let prop of json.emptyProperties){ styles.push(prop); } //Tags let sc_add:sys.SourceObject = new sys.SourceObject(); for(let data of adds){ if(data !== "doctype"){ sc_add.add("add" + createName(data) + "():HTMLElement{", 1); sc_add.add("return this.addTagUnsafe(\"" + data + "\");", 2); sc_add.add("}", 1); } } let sc_close:sys.SourceObject = new sys.SourceObject(); for(let data of closes){ sc_close.add("close" + createName(data) + "():HTMLElement{", 1); sc_close.add("return this.closeTagUnsafe(\"" + data + "\");", 2); sc_close.add("}", 1); } let sc_open:sys.SourceObject = new sys.SourceObject(); for(let data of opens){ sc_open.add("open" + createName(data) + "():HTMLElement{", 1); sc_open.add("return this.openTagUnsafe(\"" + data + "\");", 2); sc_open.add("}", 1); } let sc_ts:string = sys.readFile("./lib/html_sourcecode.ts"); sc_ts = sc_ts.substring(0, sc_ts.indexOf(generatedMethods) + generatedMethods.length); sc_ts += "\n" + sc_add.getString(); sc_ts += "\n" + sc_close.getString(); sc_ts += "\n" + sc_open.getString(); sc_ts += "}"; sys.writeFile("./lib/html_sourcecode.ts", sc_ts); //Attributes & Styles let sc_att:sys.SourceObject = new sys.SourceObject(); for(let data of atts){ sc_att.add("addAttribute" + createName(data) + "(value:string):void{", 1); sc_att.add("this.addAttributeUnsafe(\"" + data + "\", value);", 2); sc_att.add("}", 1); } let sc_style:sys.SourceObject = new sys.SourceObject(); for(let data of styles){ sc_style.add("addStyle" + createName(data) + "(value:string):void{", 1); sc_style.add("if(this.validateStyleValue(\"" + data + "\", value)){", 2); sc_style.add("this.addStyleUnsafe(\"" + data + "\", value);", 3); sc_style.add("}", 2); sc_style.add("}", 1); } sc_ts = sys.readFile("./lib/html_element.ts"); sc_ts = sc_ts.substring(0, sc_ts.indexOf(generatedMethods) + generatedMethods.length); sc_ts += "\n" + sc_att.getString(); sc_ts += "\n" + sc_style.getString(); sc_ts += "}"; sys.writeFile("./lib/html_element.ts", sc_ts); //CSS-Properties let sc_css:sys.SourceObject = new sys.SourceObject(); for(let data of styles){ sc_css.add("addProperty" + createName(data) + "(value:string):void{", 1); sc_css.add("this.addPropertyUnsafe(\"" + data + "\", value);", 2); sc_css.add("}", 1); } sc_ts = sys.readFile("./lib/css_element.ts"); sc_ts = sc_ts.substring(0, sc_ts.indexOf(generatedMethods) + generatedMethods.length); sc_ts += "\n" + sc_css.getString(); sc_ts += "}"; sys.writeFile("./lib/css_element.ts", sc_ts); //SubFunctions function createName(str:string):string{ str = sys.removeAll(str, "@"); //str = sys.removeAll(str, "*"); if(str.indexOf("-") < 0){ str = sys.capitalizeFirstLetter(str); }else{ let parts:string[] = str.split("-"); str = ""; for(let part of parts){ str += sys.capitalizeFirstLetter(part); } } return str; } function exists(atts:string[], att:string):Boolean{ if(att.indexOf("*") > -1){ return true; } if(sys.isNull(att)){ return true; } for(let a of atts){ if(a === att){ return true; } } return false; } } isForbiddenURL(url:string):Boolean{ let forbidden:string[] = []; forbidden.push("https://www.w3schools.com/TAGS/tag_comment.asp"); for(let f of forbidden){ if(f === url){ return true; } } return false; } saveCSSFunctions(functions:string[]):void{ console.log("saveCSSFunctions"); let json = new sys.JSONObject(); json.addName("functions"); json.openArray(); for(let i:number = 0; i < functions.length; i++){ json.add("\"" + functions[i] + "\""); i < functions.length - 1 ? json.addComma() : {}; } json.closeArray(); sys.writeFile("./lib/ref/css_functions.json", json.getString()); } saveCSSProperties(properties:any[], emptyProperties:string[]):void{ //console.log("saveCSSProperties"); console.log("TEST: " + properties.length + "/" + emptyProperties.length); let json = new sys.JSONObject(); json.addName("properties"); json.openArray(); for(let i:number = 0; i < properties.length; i++){ json.openObject(); json.addValue("name", properties[i].name, true, true); json.addName("values"); json.openArray(); let subValues = properties[i].values; for(let o:number = 0; o < subValues.length; o++){ json.add("\"" + subValues[o] + "\""); o < subValues.length - 1 ? json.addComma() : {}; } json.closeArray(); json.closeObject(); i < properties.length - 1 ? json.addComma() : {}; } json.closeArray(); json.addComma(); json.addName("emptyProperties"); json.openArray(); for(let i:number = 0; i < emptyProperties.length; i++){ json.add("\"" + emptyProperties[i] + "\""); i < emptyProperties.length - 1 ? json.addComma() : {}; } json.closeArray(); sys.writeFile("./lib/ref/css_properties.json", json.getString()); } saveCSSSelectors(selectors:string[]):void{ console.log("saveCSSSelectors"); let json = new sys.JSONObject(); json.addName("selectors"); json.openArray(); for(let i:number = 0; i < selectors.length; i++){ json.add("\"" + selectors[i] + "\""); i < selectors.length - 1 ? json.addComma() : {}; } json.closeArray(); sys.writeFile("./lib/ref/css_selectors.json", json.getString()); } saveHTMLEventAttributes(window:string[], form:string[], keyboard:string[], mouse:string[], drag:string[], clipboard:string[], media:string[], misc:string[]):void{ console.log("saveHTMLEventAttributes"); let json = new sys.JSONObject(); json.addName("attributes"); json.openArray(); json.add(get("window", window)); json.add(get("form", form)); json.add(get("keyboard", keyboard)); json.add(get("mouse", mouse)); json.add(get("drag", drag)); json.add(get("clipboard", clipboard)); json.add(get("media", media)); json.add(get("misc", misc)); json.closeArray(); let str = json.getString(); str = sys.replaceAll(str, "},]", "}]"); sys.writeFile("./lib/ref/html_event_attributes.json", str); //SubFunctions function get(type:string, data:string[]):string{ let json = new sys.JSONObject(); for(let i:number = 0; i < data.length; i++){ json.openObject(); json.addValue("name", data[i], true, true); json.addValue("type", type, true, false); json.closeObject(); json.addComma() //i < data.length - 1 ? json.addComma() : {}; } let str = json.getString(); return str.substring(1, str.length - 1); } } saveHTMLGlobalAttributes(values:HTMLAttribute[]):void{ console.log("saveHTMLGlobalAttributes"); let json = new sys.JSONObject(); json.addName("attributes"); json.openArray(); for(let i:number = 0; i < values.length; i++){ json.openObject(); json.addValue("name", values[i].name, true, true); json.addName("types"); json.openArray(); let subValues = values[i].values; for(let o:number = 0; o < subValues.length; o++){ json.add("\"" + subValues[o] + "\""); o < subValues.length - 1 ? json.addComma() : {}; } json.closeArray(); json.closeObject(); i < values.length - 1 ? json.addComma() : {}; } json.closeArray(); sys.writeFile("./lib/ref/html_global_attributes.json", json.getString()); } saveHTMLTags(values:HTMLTag[]):void{ console.log("saveHTMLTags"); let json = new sys.JSONObject(); json.addName("tags"); json.openArray(); for(let i:number = 0; i < values.length; i++){ json.openObject(); json.addValue("name", values[i].name, true, true); json.addValue("closed", values[i].closed.toString(), false, true); json.addValue("events", values[i].events.toString(), false, true); json.addValue("globals", values[i].globals.toString(), false, true); json.addValue("unique", values[i].unique.toString(), false, true); json.addName("attributes"); json.openArray(); let subValues = values[i].attributes; for(let o:number = 0; o < subValues.length; o++){ json.openObject(); json.addValue("name", subValues[o].name, true, true); json.addName("types"); json.openArray(); let subSubValues = subValues[o].values; for(let u:number = 0; u < subSubValues.length; u++){ json.add("\"" + subSubValues[u] + "\""); u < subSubValues.length - 1 ? json.addComma() : {}; } json.closeArray(); json.closeObject(); o < subValues.length - 1 ? json.addComma() : {}; } json.closeArray(); json.closeObject(); i < values.length - 1 ? json.addComma() : {}; } json.closeArray(); sys.writeFile("./lib/ref/html_tags.json", json.getString()); } async start(download:Boolean){ console.log("Start Generator"); if(download){ console.log("Start Downloads"); await this.createHTMLGlobalAttributes(); await this.createHTMLTags(); await this.createHTMLEventAttributes(); await this.createCSSProperties(); await this.createCSSSelectors(); await this.createCSSFunctions(); } console.log("Start Sourcecode-Generation"); this.generateSourcecode(); //TODO: All } } //Internal Classes class CSSProperty{ name:string; values:string[]; //Constructor constructor(name:string, values:string[]){ this.name = name; this.values = values; } } class HTMLAttribute{ //Declarations name:string; values:string[]; //Constructor constructor(name:string, values:string[]){ this.name = name; this.values = values; } } class HTMLTag{ //Declarations attributes:HTMLAttribute[]; closed:Boolean; events:Boolean; globals:Boolean; name:string; unique:Boolean; //Constructor constructor(name:string, closed:Boolean, events:Boolean, globals:Boolean, unique:Boolean){ this.name = name; this.closed = closed; this.events = events; this.globals = globals; this.unique = unique; this.attributes = [] } //Methods addAttribute(attribute:HTMLAttribute):void{ this.attributes.push(attribute); } }