2018-05-15 17:36:45 +00:00
|
|
|
/**
|
|
|
|
* @author n1474335 [n1474335@gmail.com]
|
|
|
|
* @copyright Crown Copyright 2016
|
|
|
|
* @license Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2019-08-29 14:08:56 +01:00
|
|
|
import { debounce } from "../../core/Utils.mjs";
|
|
|
|
|
2018-05-15 17:36:45 +00:00
|
|
|
/**
|
|
|
|
* Waiter to handle events related to the window object.
|
|
|
|
*/
|
|
|
|
class WindowWaiter {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* WindowWaiter constructor.
|
|
|
|
*
|
|
|
|
* @param {App} app - The main view object for CyberChef.
|
2023-05-09 14:56:44 +12:00
|
|
|
* @param {Manager} manager - The CyberChef event manager.
|
2018-05-15 17:36:45 +00:00
|
|
|
*/
|
2023-05-09 14:56:44 +12:00
|
|
|
constructor(app, manager) {
|
2018-05-15 17:36:45 +00:00
|
|
|
this.app = app;
|
2023-05-09 14:56:44 +12:00
|
|
|
this.manager = manager;
|
2018-05-15 17:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for window resize events.
|
2023-05-09 14:56:44 +12:00
|
|
|
*
|
2022-05-30 22:53:17 +01:00
|
|
|
* Resets adjustable component sizes after 200ms (so that continuous resizing doesn't cause
|
2018-05-15 17:36:45 +00:00
|
|
|
* continuous resetting).
|
|
|
|
*/
|
|
|
|
windowResize() {
|
2023-05-10 21:53:29 +12:00
|
|
|
if (window.innerWidth >= this.app.breakpoint) {
|
2023-05-09 14:56:44 +12:00
|
|
|
this.onResizeToDesktop();
|
2023-04-19 15:35:17 +12:00
|
|
|
} else {
|
2023-05-09 14:56:44 +12:00
|
|
|
this.onResizeToMobile();
|
|
|
|
}
|
|
|
|
|
|
|
|
// #output can be maximised on all screen sizes, so if it was open while resizing,
|
|
|
|
// it can be kept maximised until minimised manually
|
2023-05-10 21:53:29 +12:00
|
|
|
if (document.getElementById("output").classList.contains("maximised-pane")) {
|
|
|
|
this.manager.controls.setPaneMaximised("output", true);
|
2023-04-19 15:35:17 +12:00
|
|
|
}
|
2023-04-24 22:44:09 +12:00
|
|
|
|
2023-04-26 23:08:44 +12:00
|
|
|
debounce(this.app.adjustComponentSizes, 200, "windowResize", this.app, [])();
|
2018-05-15 17:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-05-10 21:53:29 +12:00
|
|
|
/**
|
|
|
|
* Set desktop UI and close #recipe / #input maximised panes if there were any.
|
|
|
|
* Correct the height of #recipe
|
|
|
|
*/
|
|
|
|
onResizeToDesktop() {
|
2023-05-09 14:56:44 +12:00
|
|
|
this.app.setDesktopUI(false);
|
|
|
|
|
|
|
|
// if a window is resized past breakpoint while #recipe or #input is maximised,
|
|
|
|
// the maximised pane is set to its default ( non-maximised ) state
|
2023-05-10 21:53:29 +12:00
|
|
|
["recipe", "input"].forEach(paneId => this.manager.controls.setPaneMaximised(paneId, false));
|
2023-05-09 14:56:44 +12:00
|
|
|
|
|
|
|
// to prevent #recipe from keeping the height set in divideAvailableSpace
|
|
|
|
document.getElementById("recipe").style.height = "100%";
|
|
|
|
}
|
|
|
|
|
2023-05-10 21:53:29 +12:00
|
|
|
/**
|
|
|
|
* Set mobile UI and close any maximised panes if there were any
|
|
|
|
*/
|
|
|
|
onResizeToMobile() {
|
2023-05-09 14:56:44 +12:00
|
|
|
this.app.setMobileUI();
|
|
|
|
|
|
|
|
// when mobile devices' keyboards pop up, it triggers a window resize event. Here
|
|
|
|
// we keep the maximised panes open until the minimise button is clicked / tapped
|
|
|
|
["recipe", "input", "output"]
|
2023-05-10 21:53:29 +12:00
|
|
|
.map(paneId => document.getElementById(paneId))
|
|
|
|
.filter(pane => pane.classList.contains("maximised-pane"))
|
|
|
|
.forEach(pane => this.manager.controls.setPaneMaximised(pane.id, true));
|
2023-05-09 14:56:44 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-05-15 17:36:45 +00:00
|
|
|
/**
|
|
|
|
* Handler for window blur events.
|
2019-10-16 15:38:20 +01:00
|
|
|
* Saves the current time so that we can calculate how long the window was unfocused for when
|
2018-05-15 17:36:45 +00:00
|
|
|
* focus is returned.
|
|
|
|
*/
|
|
|
|
windowBlur() {
|
2020-03-12 15:23:22 +00:00
|
|
|
this.windowBlurTime = Date.now();
|
2018-05-15 17:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for window focus events.
|
|
|
|
*
|
|
|
|
* When a browser tab is unfocused and the browser has to run lots of dynamic content in other
|
|
|
|
* tabs, it swaps out the memory for that tab.
|
|
|
|
* If the CyberChef tab has been unfocused for more than a minute, we run a silent bake which will
|
|
|
|
* force the browser to load and cache all the relevant JavaScript code needed to do a real bake.
|
|
|
|
* This will stop baking taking a long time when the CyberChef browser tab has been unfocused for
|
|
|
|
* a long time and the browser has swapped out all its memory.
|
|
|
|
*/
|
|
|
|
windowFocus() {
|
2020-03-12 15:23:22 +00:00
|
|
|
const unfocusedTime = Date.now() - this.windowBlurTime;
|
2018-05-15 17:36:45 +00:00
|
|
|
if (unfocusedTime > 60000) {
|
|
|
|
this.app.silentBake();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export default WindowWaiter;
|