summaryrefslogblamecommitdiffstats
path: root/typescript/src/getNewHTML.ts
blob: f5d2070d9d9cacc48329e0e1dc71f6e0acab4305 (plain) (tree)






































































































































































































                                                                                                                                                              
/* SPDX-License-Identifier: AGPL-3.0-or-later */

import type AjaxResponse from "./AjaxResponse.js";
import type AjaxSettings from "./AjaxSettings.js";
import type Pod from "./Pod.js";
import PodsClassName from "./podsClassName.js";
import type State from "./State.js";
import type SubPod from "./SubPod.js";

export default (
  AjaxSettings: AjaxSettings,
  AjaxResponse: AjaxResponse
): string =>
  `
    <div class="${PodsClassName}">
      <div>
        <div>
          <section>
            ${
              // Wolfram Alpha does have some limitations when it comes to processing certain types of input.
              // When "input" is an empty string,
              // the "pods" property will not be present in the "queryresult" object.
              // To see an example of an empty input string,
              // visit the following URL:
              // https://www.wolframalpha.com/input?i=
              Object.freeze(AjaxResponse) === undefined
                ? (console.warn({ AjaxResponse }), "")
                : AjaxResponse.queryresult === undefined
                ? (console.warn({ AjaxResponse }), "")
                : AjaxResponse.queryresult.pods === undefined
                ? "" // console.warn
                : AjaxResponse.queryresult.pods.map(buildPod).join("")
            }
            <section>
              <div>
                <h2>
                  Technical information
                </h2>
              </div>
              <div> </div>
              <div>
                <div>
                  <div>
                    <details>
                      <div>
                        If you have programming knowledge, feel free to explore the technical information provided below:
                      </div>
                      <textarea name="technical-information">${
                        Object.freeze(AjaxSettings) === undefined
                          ? (console.warn({ AjaxSettings }), "")
                          : Object.freeze(AjaxResponse) === undefined
                          ? (console.warn({ AjaxResponse }), "")
                          : escapeHTML(tryStringify(AjaxSettings, AjaxResponse))
                      }</textarea>
                    </details>
                  </div>
                </div>
              </div>
              <div> </div>
            </section>
          </section>
        </div>
      </div>
    </div>
  `;

const buildPod = (pod: Pod): string =>
  `
    <section>
      <div>
        ${
          pod.title === undefined
            ? (console.warn({ pod }), "")
            : `<h2>${escapeHTML(pod.title)}</h2>`
        }
        ${
          // In most cases, pods are stateless and do not have specific states.
          // As a result, the "states" property of "pod" is typically undefined.
          pod.states === undefined
            ? "" // console.warn
            : pod.states.map(buildSelectElement).join("")
        }
      </div>
      <div> </div>
      ${
        pod.subpods === undefined
          ? (console.warn({ pod }), "")
          : pod.subpods.map(buildSubpod).join("")
      }
    </section>
  `;

const buildSelectElement = (state: State): string =>
  // Although it is possible to handle the scenario where the "states" property is undefined,
  // implementing the necessary logic may result in a cluttered user interface.
  // This challenge is primarily due to my limited expertise in front-end design.
  // Consequently, the current implementation of the parsing logic is still insufficient in addressing the situation where the "states" property is undefined.
  state.states === undefined
    ? "" // console.warn
    : `
        <select name="pod-states">
          ${
            state.value === undefined
              ? (console.warn({ state }), "")
              : `
                  <option>${escapeHTML(state.value)}</option>
                `
          }
          ${state.states.map(buildOption).join("")}
        </select>
      `;

const buildOption = (state: { name?: string }): string =>
  state.name === undefined
    ? (console.warn({ state }), "")
    : `
        <option>${escapeHTML(state.name)}</option>
      `;

const buildSubpod = (subpod: SubPod): string =>
  `
    ${
      subpod.img === undefined
        ? (console.warn({ subpod }), "")
        : `
            <div>
              <div>
                <img
                  src="${escapeHTML(
                    subpod.img.src === undefined
                      ? (console.warn({ subpod }), "")
                      : subpod.img.src
                  )}"
                  alt="${escapeHTML(
                    subpod.img.alt === undefined
                      ? (console.warn({ subpod }), "")
                      : subpod.img.alt
                  )}"
                >
              </div>
            </div>
          `
    }
    ${
      subpod.plaintext === undefined
        ? (console.warn({ subpod }), "")
        : `
            <div style="font-family: monospace; overflow: auto;">
              <div>
                <div>
                  <details>
                    <summary style="direction: rtl;"></summary>
                    <div>
                      <pre>${escapeHTML(subpod.plaintext)}</pre>
                    </div>
                    <br />
                  </details>
                </div>
              </div>
            </div>
          `
    }
  `;

const tryStringify = (
  AjaxSettings: AjaxSettings,
  AjaxResponse: AjaxResponse
): string => {
  try {
    return JSON.stringify(
      {
        document,
        AjaxSettings,
        AjaxResponse,
      },
      null,
      4
    );
  } catch (error) {
    console.warn({ error });
    return error instanceof TypeError ? error.message + "\n" + error.stack : "";
    // JSON.stringify() - JavaScript | MDN
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#exceptions
  }
};

const escapeHTML = (unsafeHTML: string): string =>
  unsafeHTML
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");

// Can I escape HTML special chars in JavaScript? - Stack Overflow
// https://stackoverflow.com/questions/6234773/can-i-escape-html-special-chars-in-javascript

// test case:
// https://www.wolframalpha.com/input?i=solve+%7By%27%28x%29+%3D+-2+y%2C+y%280%29%3D1%7D+from+0+to+10+using+r+k+f+algorithm