// The new-ticket form's keyboard. Everything here is a shortcut for
// something the form already does without script: submit is the
// button, "open and start another" is the checkbox, a chip is a
// native select a Tab reaches and a letter types into.
(function () {
"use strict";
var form = document.querySelector("form[data-hook=ticket-new]");
if (!form) return;
function typing(el) {
if (!el) return false;
var t = el.tagName;
return t === "INPUT" || t === "TEXTAREA" || t === "SELECT" || el.isContentEditable;
}
// Cmd/Ctrl+Enter files the ticket from anywhere in the form;
// with Shift it files and comes back for the next one.
form.addEventListener("keydown", function (e) {
if (e.key !== "Enter" || !(e.metaKey || e.ctrlKey)) return;
e.preventDefault();
var more = form.querySelector("input[name=another]");
if (more && e.shiftKey) more.checked = true;
if (form.requestSubmit) form.requestSubmit(); else form.submit();
});
// Inside a focused chip, a digit picks that word: 1 is the first word
// the tracker lists, so the order on screen is the order of the keys.
form.addEventListener("keydown", function (e) {
var sel = e.target;
if (!sel || sel.tagName !== "SELECT" || !sel.closest(".chip")) return;
if (e.metaKey || e.ctrlKey || e.altKey || !/^[1-9]$/.test(e.key)) return;
var words = Array.prototype.filter.call(sel.options, function (o) {
return o.value !== "" && o.value !== "__new";
});
var pick = words[Number(e.key) - 1];
if (!pick) return;
e.preventDefault();
sel.value = pick.value;
sel.dispatchEvent(new Event("change", { bubbles: true }));
});
// Choosing a type brings its template into the description — but only
// into one the reporter has not written in: empty, or still exactly
// some template. Words somebody typed are never replaced.
function template(type) {
var el = form.querySelector('template[data-tn-template="' + (window.CSS && CSS.escape ? CSS.escape(type) : type) + '"]') ||
form.querySelector('template[data-tn-template=""]');
return el ? el.content.textContent : "";
}
function untouched(text) {
var t = text.trim();
if (t === "") return true;
return Array.prototype.some.call(form.querySelectorAll("template[data-tn-template]"), function (el) {
return el.content.textContent.trim() === t;
});
}
form.addEventListener("change", function (e) {
if (!e.target || e.target.name !== "type") return;
var box = form.querySelector("textarea[name=comment]");
if (!box || !untouched(box.value)) return;
box.value = template(e.target.value);
box.dispatchEvent(new Event("input", { bubbles: true }));
});
// A letter outside any text box moves to its chip: S status,
// V severity, P priority, U subsystem. Only on this page, only when
// nothing is being typed, and never with a modifier held.
var keys = { s: "status", v: "severity", p: "priority", u: "subsystem" };
document.addEventListener("keydown", function (e) {
if (e.metaKey || e.ctrlKey || e.altKey || typing(document.activeElement)) return;
var name = keys[e.key];
if (!name) return;
var sel = form.querySelector(".chip select[name=" + name + "]");
if (!sel) return;
e.preventDefault();
sel.focus();
});
})();