Skip to content
Snippets Groups Projects
Commit 3a690530 authored by baletiballo's avatar baletiballo
Browse files

Transition to TypeScript complete

parent c7cec09a
No related branches found
No related tags found
No related merge requests found
"use strict";
// A hack to make a list of strings on type level.
// If you add another type to be parsable i.e. implement a parser for it, also add its name here
const parsable = ["string", "MathMLElement", "HTMLElement", "SVGElement"];
const primitives = ["string", "MathMLElement", "HTMLElement", "SVGElement"];
function is_primitive(a) {
return "parseAs" in a
&& parsable.includes(a.parseAs)
&& primitives.includes(a.parseAs)
&& "content" in a
&& typeof a.content === "string";
}
const parser = new DOMParser;
// A shorthand we will need several times
function parse(s) {
const doc = parser.parseFromString(s, "text/html");
const errorNode = doc.querySelector("parsererror");
if (errorNode) {
console.error(errorNode);
throw {};
}
else {
return doc.body.firstChild;
}
}
/**
*
* @param json_object
* @returns
* @throws TypeError if {@link json_object} doesn't adhere to the JSON schema
*/
function backendObject_fromJSON(json_object) {
const parser = new DOMParser;
// just a shorthand we will need several times
const parse = function (s) {
const element = parser.parseFromString(s, "text/xml").childNodes[0];
return element;
};
// the Backend_Object to be
const bo = {};
let bo = {};
// If the input is sensible this works, otherwise we have to throw a TypeError anyway
for (let i in json_object) {
const member = json_object[i];
//console.log(member)
if (is_primitive(member)) {
switch (member.parseAs) {
case "string":
bo[i] = member.content;
break;
// all other cases are identical ()
case "MathMLElement":
bo[i] = parse(member.content);
break;
case "HTMLElement":
bo[i] = parse(member.content);
break;
case "SVGElement":
//console.log(i, parse(member.content), bo)
bo[i] = parse(member.content);
break;
}
}
else {
bo[i] = backendObject_fromJSON(member);
if (Array.isArray(member)) {
bo[i] = [];
member.forEach((value, index) => {
bo[i][index] = backendObject_fromJSON(value);
});
}
else {
bo[i] = backendObject_fromJSON(member);
}
}
}
if (bo.label instanceof MathMLElement
&& typeof bo.uri === "string"
&& typeof bo.type === "string") {
return bo;
if (!("label" in bo)) {
console.error(`Attribute 'label' is missing. Cannot finish parsing`, json_object, bo);
throw new TypeError;
}
else {
console.error(`This is not a Backend_Object:`, json_object);
throw new TypeError(`This is not a Backend_Object: \n ${json_object}`);
if (!("uri" in bo && typeof bo.uri === "string")) {
console.error(`Attribute 'uri': ${bo.uri} is missing or not a string. Cannot finish parsing`, json_object, bo);
throw new TypeError;
}
if (!("type" in bo && typeof bo.type === "string")) {
console.error(`Attribute 'type': ${bo.type} is missing or not a string. Cannot finish parsing`, json_object, bo);
throw new TypeError;
}
// for some reason ts does not believe the conditions above
return bo;
}
......@@ -9,9 +9,15 @@ function RenderScroll() {
return;
}
const scroll_json = JSON.parse(dataSource.dataset.scrollDynamic);
const scroll = backendObject_fromJSON(scroll_json);
if (!isScroll(scroll)) {
console.error("The Scroll in the Unity-Data-Interface cannot be parsed");
let scroll;
try {
scroll = backendObject_fromJSON(scroll_json);
if (!Scroll.isScroll(scroll)) {
throw {};
}
}
catch (error) {
console.error(error, `Cannot parse the scroll:`, scroll_json);
return;
}
//console.log(scroll.requiredFacts);
......
This diff is collapsed.
// A hack to make a list of strings on type level.
// If you add another type to be parsable i.e. implement a parser for it, also add its name here
const parsable = ["string", "MathMLElement", "HTMLElement", "SVGElement"] as const
const primitives = ["string", "MathMLElement", "HTMLElement", "SVGElement"] as const
type Primitive = string | MathMLElement | HTMLElement | SVGElement
type Parsable_Primitive = { parseAs: typeof parsable[number], content: string };
type Parsable_Primitive = { parseAs: typeof primitives[number], content: string };
function is_primitive(a: any): a is Parsable_Primitive {
return "parseAs" in a
&& parsable.includes(a.parseAs)
return "parseAs" in a
&& primitives.includes(a.parseAs)
&& "content" in a
&& typeof a.content === "string"
}
type Parsable_BO = {[key: string]: Parsable_Primitive | Parsable_BO};
// type Typed_JSONObject = { [data: string]: Primitive | Backend_Object }
function backendObject_fromJSON(json_object: Parsable_BO): Backend_Object {
const parser = new DOMParser;
// just a shorthand we will need several times
const parse = function <E extends Element>(s: string): E {
const element = parser.parseFromString(s, "text/xml").childNodes[0]
return element as E
// declare var Generic_BackendObject: {
// label: MathMLElement
// uri: string
// type: string
// [data: string]: any
// prototype: Backend_Object;
// };
type Parsable_BO = { [key: string]: Parsable_Primitive | Parsable_BO | [Parsable_BO] };
const parser = new DOMParser;
// A shorthand we will need several times
function parse (s: string): Primitive {
const doc = parser.parseFromString(s, "text/html")
const errorNode = doc.querySelector("parsererror");
if (errorNode) {
console.error(errorNode)
throw{}
} else {
return doc.body.firstChild as Primitive
}
}
/**
*
* @param json_object
* @returns
* @throws TypeError if {@link json_object} doesn't adhere to the JSON schema
*/
function backendObject_fromJSON(json_object: Parsable_BO): Backend_Object {
// the Backend_Object to be
const bo: {
[key: keyof typeof json_object]: Primitive | Backend_Object
} = { }
let bo: {[data:string]: any} = {}
// If the input is sensible this works, otherwise we have to throw a TypeError anyway
for (let i in json_object) {
const member = json_object[i]
//console.log(member)
if (is_primitive(member)) {
switch (member.parseAs) {
case "string":
bo[i] = member.content
break;
// all other cases are identical ()
case "MathMLElement":
bo[i] = parse<MathMLElement>(member.content)
break;
case "HTMLElement":
bo[i] = parse<HTMLElement>(member.content)
break;
case "SVGElement":
bo[i] = parse<SVGElement>(member.content)
//console.log(i, parse(member.content), bo)
bo[i] = parse(member.content)
break;
}
}
else {
bo[i] = backendObject_fromJSON(member)
if (Array.isArray(member)) {
bo[i] = []
member.forEach((value, index) => {
bo[i][index] = backendObject_fromJSON(value)
})
}
else { bo[i] = backendObject_fromJSON(member) }
}
}
if (bo.label instanceof MathMLElement
&& typeof bo.uri === "string"
&& typeof bo.type === "string") {
return bo as unknown as Backend_Object
if (!("label" in bo)) {
console.error(`Attribute 'label' is missing. Cannot finish parsing`, json_object, bo)
throw new TypeError
}
if (!("uri" in bo && typeof bo.uri === "string")) {
console.error(`Attribute 'uri': ${bo.uri} is missing or not a string. Cannot finish parsing`, json_object, bo)
throw new TypeError
}
else {
console.error(`This is not a Backend_Object:`, json_object)
throw new TypeError(`This is not a Backend_Object: \n ${json_object}`)
if (!("type" in bo && typeof bo.type === "string")) {
console.error(`Attribute 'type': ${bo.type} is missing or not a string. Cannot finish parsing`, json_object, bo)
throw new TypeError
}
// for some reason ts does not believe the conditions above
return bo as unknown as Backend_Object
}
\ No newline at end of file
......@@ -10,9 +10,12 @@ function RenderScroll() {
return
}
const scroll_json = JSON.parse(dataSource.dataset.scrollDynamic);
const scroll = backendObject_fromJSON(scroll_json)
if (!isScroll(scroll)) {
console.error("The Scroll in the Unity-Data-Interface cannot be parsed")
let scroll: Backend_Object
try {
scroll = backendObject_fromJSON(scroll_json)
if (!Scroll.isScroll(scroll)) {throw {} }
} catch (error) {
console.error(error, `Cannot parse the scroll:`, scroll_json)
return
}
//console.log(scroll.requiredFacts);
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment