200 lines
6.3 KiB
TypeScript
200 lines
6.3 KiB
TypeScript
/* 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, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
|
|
// 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
|