Skip to content
Snippets Groups Projects
API_Parsers.js 2.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • "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 primitives = ["string", "MathMLElement", "HTMLElement", "SVGElement"];
    
    function is_primitive(a) {
        return "parseAs" in a
    
            && 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) {
        // the Backend_Object to be
    
        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":
                    case "HTMLElement":
                    case "SVGElement":
    
                        //console.log(i, parse(member.content), bo)
    
                        bo[i] = parse(member.content);
                        break;
                }
            }
            else {
    
                if (Array.isArray(member)) {
                    bo[i] = [];
                    member.forEach((value, index) => {
                        bo[i][index] = backendObject_fromJSON(value);
                    });
                }
                else {
                    bo[i] = backendObject_fromJSON(member);
                }
    
        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;
        }
        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;