2023-11-23 08:53:28 +00:00
|
|
|
class WindowObject {
|
|
|
|
windowObject;
|
|
|
|
|
|
|
|
windowManager;
|
|
|
|
windowManagerLabel;
|
|
|
|
windowContent;
|
|
|
|
|
|
|
|
#orig_mousePosX;
|
|
|
|
#orig_mousePosY;
|
|
|
|
#orig_selfPosX;
|
|
|
|
#orig_selfPosY;
|
|
|
|
#isDragging;
|
|
|
|
|
2023-11-23 17:33:47 +00:00
|
|
|
constructor(parent, content, srcdoc) {
|
2023-11-23 08:53:28 +00:00
|
|
|
this.parentElement = parent;
|
2023-11-23 17:33:47 +00:00
|
|
|
this.windowObject = WindowObject.createWindow(this, content, srcdoc);
|
2023-11-23 08:53:28 +00:00
|
|
|
this.parentElement.appendChild(this.windowObject);
|
|
|
|
|
|
|
|
WindowObject.raiseWindow(this.windowObject);
|
|
|
|
|
|
|
|
this.windowManager = this.windowObject.querySelector(".window-manager");
|
|
|
|
this.windowManagerLabel = this.windowObject.querySelector(
|
|
|
|
".window-manager-label"
|
|
|
|
);
|
|
|
|
this.windowContent = this.windowObject.querySelector(".window-content");
|
|
|
|
|
|
|
|
this.windowManager.addEventListener("mousedown", (e) =>
|
|
|
|
this.event__dragMouseDown(e)
|
|
|
|
);
|
|
|
|
this.windowManager.addEventListener("mousemove", (e) =>
|
|
|
|
this.event__dragMouseMove(e)
|
|
|
|
);
|
|
|
|
this.windowManager.addEventListener("mouseup", (e) =>
|
|
|
|
this.event__dragMouseUp(e)
|
|
|
|
);
|
|
|
|
this.windowManager.addEventListener("mouseout", (e) =>
|
|
|
|
this.event__dragMouseMove(e)
|
|
|
|
);
|
|
|
|
|
|
|
|
this.windowObject.addEventListener("mousedown", (e) =>
|
|
|
|
WindowObject.raiseWindow(this.windowObject)
|
|
|
|
);
|
|
|
|
|
2023-11-23 17:33:47 +00:00
|
|
|
this.windowContent.contentWindow.addEventListener("mousedown", (e) =>
|
|
|
|
WindowObject.raiseWindow(this.windowObject)
|
|
|
|
);
|
|
|
|
|
|
|
|
window.addEventListener("beforeunload", () => this.destroy());
|
|
|
|
|
2023-11-23 08:53:28 +00:00
|
|
|
this.windowContent.addEventListener("load", () => {
|
|
|
|
this.title = this.windowContent.contentWindow.document.title;
|
2023-11-23 17:33:47 +00:00
|
|
|
if (!srcdoc)
|
|
|
|
this.windowManager
|
|
|
|
.querySelector(".window-new-button")
|
|
|
|
.addEventListener("click", () => {
|
|
|
|
window.open(this.content);
|
|
|
|
});
|
2023-11-23 08:53:28 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
get title() {
|
|
|
|
return this.windowManagerLabel.textContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
get content() {
|
2023-11-23 17:56:39 +00:00
|
|
|
return this.windowContent.src;
|
2023-11-23 08:53:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set title(content) {
|
|
|
|
this.windowManagerLabel.textContent = content;
|
|
|
|
}
|
|
|
|
|
|
|
|
set content(src) {
|
2023-11-23 17:56:39 +00:00
|
|
|
this.windowContent.src = src;
|
2023-11-23 08:53:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
minimizeWindow() {
|
|
|
|
if (this.windowObject.classList.contains("minimized")) {
|
|
|
|
this.windowObject.classList.remove("minimized");
|
|
|
|
|
|
|
|
WindowObject.raiseWindow(this.windowObject);
|
|
|
|
} else {
|
|
|
|
this.windowObject.classList.add("minimized");
|
|
|
|
this.windowObject.style.zIndex = 50;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
maximizeWindow() {
|
|
|
|
this.windowObject.classList.toggle("maximized");
|
|
|
|
|
|
|
|
WindowObject.raiseWindow(this.windowObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
2023-11-23 17:33:47 +00:00
|
|
|
if (this.windowContent.contentWindow != null) {
|
|
|
|
const unloadEvent = new Event("beforeunload");
|
|
|
|
this.windowContent.contentWindow.dispatchEvent(unloadEvent);
|
|
|
|
}
|
|
|
|
|
2023-11-23 08:53:28 +00:00
|
|
|
this.windowObject.classList.add("closed");
|
|
|
|
setTimeout(() => {
|
|
|
|
this.windowObject.remove();
|
|
|
|
var someWindow = this.parentElement.querySelector(
|
|
|
|
`.window-object:last-child`
|
|
|
|
);
|
|
|
|
if (someWindow != null) WindowObject.raiseWindow(someWindow);
|
|
|
|
}, 250);
|
|
|
|
}
|
|
|
|
|
|
|
|
event__dragMouseDown(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
this.#orig_mousePosX = e.clientX;
|
|
|
|
this.#orig_mousePosY = e.clientY;
|
|
|
|
this.#orig_selfPosX = this.windowObject.offsetLeft;
|
|
|
|
this.#orig_selfPosY = this.windowObject.offsetTop;
|
|
|
|
this.windowContent.style.userSelect = "none";
|
|
|
|
this.windowContent.style.pointerEvents = "none";
|
|
|
|
this.windowManager.style.cursor = "move";
|
|
|
|
this.#isDragging = true;
|
|
|
|
if (this.windowObject.style.zIndex != 100)
|
|
|
|
WindowObject.raiseWindow(this.windowObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
event__dragMouseUp(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
this.#orig_mousePosX = 0;
|
|
|
|
this.#orig_mousePosY = 0;
|
|
|
|
this.windowContent.style.userSelect = "auto";
|
|
|
|
this.windowContent.style.pointerEvents = "auto";
|
|
|
|
this.windowManager.style.cursor = "default";
|
|
|
|
this.#isDragging = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
event__dragMouseMove(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
if (this.#isDragging) {
|
|
|
|
this.windowObject.style.left =
|
|
|
|
this.#orig_selfPosX - (this.#orig_mousePosX - e.clientX) + "px";
|
|
|
|
this.windowObject.style.top =
|
|
|
|
this.#orig_selfPosY - (this.#orig_mousePosY - e.clientY) + "px";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static raiseWindow(windowObj) {
|
|
|
|
windowObj.parentElement.querySelectorAll(".window-object").forEach((x) => {
|
|
|
|
if (x.style.zIndex > 50) x.style.zIndex -= 1;
|
|
|
|
x.classList.add("unfocused");
|
|
|
|
});
|
|
|
|
windowObj.style.zIndex = 100;
|
|
|
|
windowObj.classList.remove("unfocused");
|
|
|
|
windowObj.focus();
|
|
|
|
}
|
|
|
|
|
2023-11-23 17:33:47 +00:00
|
|
|
static createWindow(windowRef, content, srcdoc) {
|
2023-11-23 08:53:28 +00:00
|
|
|
const windowObject = document.createElement("div");
|
|
|
|
windowObject.classList.add("window-object");
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowManager = document.createElement("div");
|
|
|
|
windowManager.classList.add("window-manager");
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowManagerStart = document.createElement("div");
|
|
|
|
windowManagerStart.classList.add("window-manager-start");
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowManagerLabel = document.createElement("span");
|
|
|
|
windowManagerLabel.textContent = "";
|
|
|
|
windowManagerLabel.classList.add("window-manager-label");
|
|
|
|
|
|
|
|
windowManagerStart.appendChild(windowManagerLabel);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowManager.appendChild(windowManagerStart);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowManagerEnd = document.createElement("div");
|
|
|
|
windowManagerEnd.classList.add("window-manager-end");
|
|
|
|
|
2023-11-23 17:33:47 +00:00
|
|
|
if (!srcdoc) {
|
2023-11-23 08:53:28 +00:00
|
|
|
const windowNewButton = document.createElement("button");
|
|
|
|
windowNewButton.innerHTML = "open_in_new";
|
|
|
|
windowNewButton.classList.add("window-new-button");
|
|
|
|
|
|
|
|
windowManagerEnd.appendChild(windowNewButton);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowMaximizeButton = document.createElement("button");
|
|
|
|
windowMaximizeButton.innerHTML = "maximize";
|
|
|
|
windowMaximizeButton.classList.add("window-maximize-button");
|
|
|
|
windowMaximizeButton.ariaHidden = true; // esoteric operation to screen-reader users
|
|
|
|
windowMaximizeButton.addEventListener("click", () =>
|
|
|
|
windowRef.maximizeWindow()
|
|
|
|
);
|
|
|
|
|
|
|
|
windowManagerEnd.appendChild(windowMaximizeButton);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowDestroyButton = document.createElement("button");
|
|
|
|
windowDestroyButton.innerHTML = "close";
|
|
|
|
windowDestroyButton.classList.add("window-destroy-button");
|
|
|
|
windowDestroyButton.ariaHidden = true;
|
|
|
|
windowDestroyButton.addEventListener("click", () =>
|
|
|
|
windowRef.destroy()
|
|
|
|
);
|
|
|
|
|
|
|
|
windowManagerEnd.appendChild(windowDestroyButton);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowManager.appendChild(windowManagerEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowObject.appendChild(windowManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const windowContent = document.createElement("iframe");
|
|
|
|
windowContent.classList.add("window-content");
|
|
|
|
|
|
|
|
{
|
2023-11-23 17:33:47 +00:00
|
|
|
if (srcdoc) windowContent.srcdoc = content;
|
|
|
|
else windowContent.src = content;
|
2023-11-23 08:53:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
windowObject.appendChild(windowContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return windowObject;
|
|
|
|
}
|
|
|
|
}
|