Work on js syntax highlighting in textarea
This commit is contained in:
@@ -2,9 +2,8 @@
|
|||||||
// TODO: Parse JSON to YAML
|
// TODO: Parse JSON to YAML
|
||||||
// TODO: Download YAML
|
// TODO: Download YAML
|
||||||
// Injection scripts
|
// Injection scripts
|
||||||
// TODO: Javascript syntax highlighting within textarea layout, styling and event listeners
|
// TODO: Textarea handle events (tab key, shift tab, scroll)
|
||||||
// TODO: Textarea handlers and logic for javascript (e.g. tab, newline)
|
// TODO: Javascript escaping/unescaping as required to prevent XSS and satisfy API requirements
|
||||||
// TODO: Javascript escaping/unescaping as required
|
|
||||||
// TODO: remove tailwind play cdn script in head of playground.html after syntax highlighting work complete
|
// TODO: remove tailwind play cdn script in head of playground.html after syntax highlighting work complete
|
||||||
// Ninja Keys improvements
|
// Ninja Keys improvements
|
||||||
// TODO: Group related items for Ninja Keys
|
// TODO: Group related items for Ninja Keys
|
||||||
@@ -161,14 +160,14 @@ function getValues(id, description, params) {
|
|||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
focusTrap.destroy();
|
focusTrap.destroy();
|
||||||
modalBody.removeEventListener("keydown", handleEscapeKey);
|
modalBody.removeEventListener("keydown", handleKeyboardEvents);
|
||||||
modalBody.removeEventListener("keydown", handleEnterKey);
|
|
||||||
modalContainer.removeEventListener("click", handleClickOutside);
|
modalContainer.removeEventListener("click", handleClickOutside);
|
||||||
modalSubmitButton.removeEventListener("click", closeModal);
|
modalSubmitButton.removeEventListener("click", closeModal);
|
||||||
modalClose.removeEventListener("click", closeModal);
|
modalClose.removeEventListener("click", closeModal);
|
||||||
inputEventListeners.forEach((listener, index) => {
|
inputEventListeners.forEach((listener, index) => {
|
||||||
inputs[index].removeEventListener("input", listener);
|
inputs[index].removeEventListener("input", listener);
|
||||||
});
|
});
|
||||||
|
modalContent.classList.remove("relative", "h-[220px]");
|
||||||
inputEventListeners.length = 0;
|
inputEventListeners.length = 0;
|
||||||
inputs.length = 0;
|
inputs.length = 0;
|
||||||
values = [];
|
values = [];
|
||||||
@@ -182,13 +181,10 @@ function getValues(id, description, params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEscapeKey(e) {
|
function handleKeyboardEvents(e) {
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function handleEnterKey(e) {
|
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
if (e.target.tagName.toLowerCase() === "textarea") {
|
if (e.target.tagName.toLowerCase() === "textarea") {
|
||||||
return;
|
return;
|
||||||
@@ -196,20 +192,43 @@ function getValues(id, description, params) {
|
|||||||
modalSubmitButton.click();
|
modalSubmitButton.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
e.key === "Tab" &&
|
||||||
|
!e.shiftKey &&
|
||||||
|
e.target.tagName.toLowerCase() === "textarea"
|
||||||
|
) {
|
||||||
|
e.preventDefault();
|
||||||
|
let text = e.target.value;
|
||||||
|
const start = e.target.selectionStart;
|
||||||
|
const end = e.target.selectionEnd;
|
||||||
|
e.target.value = text.substring(0, start) + "\t" + text.substring(end);
|
||||||
|
e.target.dispatchEvent(new Event("input"));
|
||||||
|
e.target.setSelectionRange(start + 1, start + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("modal-title").innerHTML = id;
|
document.getElementById("modal-title").innerHTML = id;
|
||||||
document.getElementById("modal-description").innerHTML = description;
|
document.getElementById("modal-description").innerHTML = description;
|
||||||
|
|
||||||
params.map((param, i) => {
|
params.map((param, i) => {
|
||||||
function textareaEventListener(event) {
|
function textareaEventListener(e) {
|
||||||
codeElement = document.querySelector("code");
|
codeElement = document.querySelector("code");
|
||||||
codeElement.innerText = event.target.value;
|
let text = e.target.value;
|
||||||
Prism.highlightElement(codeElement);
|
|
||||||
values[i] = "|" + " " + event.target.value;
|
if (text[text.length - 1] == "\n") {
|
||||||
|
text += " ";
|
||||||
}
|
}
|
||||||
function inputEventListener(event) {
|
|
||||||
values[i] = event.target.value;
|
codeElement.innerHTML = text
|
||||||
|
.replace(new RegExp("&", "g"), "&")
|
||||||
|
.replace(new RegExp("<", "g"), "<");
|
||||||
|
|
||||||
|
Prism.highlightElement(codeElement);
|
||||||
|
values[i] = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputEventListener(e) {
|
||||||
|
values[i] = e.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = document.createElement("label");
|
const label = document.createElement("label");
|
||||||
@@ -219,17 +238,39 @@ function getValues(id, description, params) {
|
|||||||
if (param.name === "js") {
|
if (param.name === "js") {
|
||||||
input = document.createElement("textarea");
|
input = document.createElement("textarea");
|
||||||
input.type = "textarea";
|
input.type = "textarea";
|
||||||
|
input.setAttribute("spellcheck", "false");
|
||||||
|
input.placeholder = "Enter your JavaScript injection code ...";
|
||||||
input.classList.add(
|
input.classList.add(
|
||||||
"min-h-[200px]",
|
"h-[200px]",
|
||||||
|
"w-full",
|
||||||
"font-mono",
|
"font-mono",
|
||||||
"whitespace-break-spaces",
|
"whitespace-break-spaces",
|
||||||
"font-semibold"
|
"font-semibold",
|
||||||
|
"absolute",
|
||||||
|
"text-base",
|
||||||
|
"leading-6",
|
||||||
|
"rounded-md",
|
||||||
|
"ring-1",
|
||||||
|
"ring-slate-900/10",
|
||||||
|
"shadow-sm",
|
||||||
|
"z-10",
|
||||||
|
"p-4",
|
||||||
|
"m-0",
|
||||||
|
"my-2",
|
||||||
|
"bg-transparent",
|
||||||
|
"text-transparent",
|
||||||
|
"overflow-auto",
|
||||||
|
"resize-none",
|
||||||
|
"caret-white",
|
||||||
|
"hover:ring-slate-300",
|
||||||
|
"dark:bg-slate-800",
|
||||||
|
"dark:highlight-white/5",
|
||||||
|
"hyphens-none"
|
||||||
);
|
);
|
||||||
|
input.style.tabSize = "4";
|
||||||
} else {
|
} else {
|
||||||
input = document.createElement("input");
|
input = document.createElement("input");
|
||||||
input.type = "text";
|
input.type = "text";
|
||||||
}
|
|
||||||
input.id = `input-${i}`;
|
|
||||||
input.classList.add(
|
input.classList.add(
|
||||||
"w-full",
|
"w-full",
|
||||||
"text-sm",
|
"text-sm",
|
||||||
@@ -242,16 +283,42 @@ function getValues(id, description, params) {
|
|||||||
"py-1.5",
|
"py-1.5",
|
||||||
"pl-2",
|
"pl-2",
|
||||||
"pr-3",
|
"pr-3",
|
||||||
|
"mt-0",
|
||||||
"hover:ring-slate-300",
|
"hover:ring-slate-300",
|
||||||
"dark:bg-slate-800",
|
"dark:bg-slate-800",
|
||||||
"dark:highlight-white/5"
|
"dark:highlight-white/5",
|
||||||
|
"overflow-auto"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
input.id = `input-${i}`;
|
||||||
modalContent.appendChild(label);
|
modalContent.appendChild(label);
|
||||||
modalContent.appendChild(input);
|
modalContent.appendChild(input);
|
||||||
if (input.type === "textarea") {
|
if (input.type === "textarea") {
|
||||||
|
label.classList.add("sr-only", "hidden");
|
||||||
preElement = document.createElement("pre");
|
preElement = document.createElement("pre");
|
||||||
codeElement = document.createElement("code");
|
codeElement = document.createElement("code");
|
||||||
preElement.setAttribute("aria-hidden", "true");
|
preElement.setAttribute("aria-hidden", "true");
|
||||||
|
preElement.classList.add(
|
||||||
|
"bg-[#2d2d2d]",
|
||||||
|
"h-[200px]",
|
||||||
|
"w-full",
|
||||||
|
"rounded-md",
|
||||||
|
"ring-1",
|
||||||
|
"ring-slate-900/10",
|
||||||
|
"shadow-sm",
|
||||||
|
"p-0",
|
||||||
|
"m-0",
|
||||||
|
"my-2",
|
||||||
|
"font-mono",
|
||||||
|
"text-base",
|
||||||
|
"leading-6",
|
||||||
|
"whitespace-break-spaces",
|
||||||
|
"font-semibold",
|
||||||
|
"absolute",
|
||||||
|
"z-0",
|
||||||
|
"overflow-auto"
|
||||||
|
);
|
||||||
|
modalContent.classList.add("relative", "h-[220px]");
|
||||||
preElement.setAttribute("tabindex", "-1");
|
preElement.setAttribute("tabindex", "-1");
|
||||||
codeElement.classList.add("language-javascript");
|
codeElement.classList.add("language-javascript");
|
||||||
preElement.appendChild(codeElement);
|
preElement.appendChild(codeElement);
|
||||||
@@ -269,8 +336,7 @@ function getValues(id, description, params) {
|
|||||||
document.getElementById("input-0").focus();
|
document.getElementById("input-0").focus();
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
modalBody.addEventListener("keydown", handleEscapeKey);
|
modalBody.addEventListener("keydown", handleKeyboardEvents);
|
||||||
modalBody.addEventListener("keydown", handleEnterKey);
|
|
||||||
modalContainer.addEventListener("click", handleClickOutside);
|
modalContainer.addEventListener("click", handleClickOutside);
|
||||||
modalClose.addEventListener("click", () => {
|
modalClose.addEventListener("click", () => {
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>ladder | playground</title>
|
<title>ladder | playground</title>
|
||||||
<link rel="stylesheet" href="/styles.css" />
|
<!-- <link rel="stylesheet" href="/styles.css" /> -->
|
||||||
<!-- <script src="https://cdn.tailwindcss.com"></script> -->
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<style>
|
<style>
|
||||||
#modifierContainer::-webkit-scrollbar {
|
#modifierContainer::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
@@ -416,7 +416,7 @@
|
|||||||
<p id="modal-description">DESCRIPTION</p>
|
<p id="modal-description">DESCRIPTION</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="my-2 flex flex-col gap-2"
|
class="my-2 flex flex-col gap-2 w-full"
|
||||||
id="modal-content"
|
id="modal-content"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user