Files
zellij/zellij-client/assets/utils.js
Aram Drevekenin 3239d37b40 Native web mobile UI (#5441)
* initial chrome

* mobile state

* feat(mobile-web): implement browser→server actions (fit toggle, single-pane fullscreen, pane/tab focus) with fullscreen-truth reconciliation

* panning

* remove mobile plugin

* fix first load race

* improve web handshake

* rustfmt

* cleanups

* moar cleanups

* add bundle asset check to ci

* fix(mobile-web): tab-scope co-presence, yield single-pane to desktop clients, fix render-mode desync

* make mobile use no-ui fullscreen

* client side welcome screen for mobile

* attach web clients to first tab on tiles surface

* fix: opening new pane in mobile single mode no longer exits mobile single mode

* mobile chrome light theme support

* fix server races and flaky tests

* rustfmt

* fix flakes

* add pr
2026-08-05 15:32:53 +02:00

76 lines
2.3 KiB
JavaScript

/**
* Utility functions for the terminal web client
*/
/**
* Check if the current page is served over HTTPS
* @returns {boolean} true if protocol is https:, false otherwise
*/
export function is_https() {
return document.location.protocol === "https:";
}
export function isMac() {
if (navigator.userAgentData && navigator.userAgentData.platform) {
return navigator.userAgentData.platform === "macOS";
}
return navigator.platform.toUpperCase().includes("MAC");
}
/**
* Get the application base URL, derived from the location of this module.
* Modules are always served from `<base>/assets/<file>.js`, so stripping the
* trailing `/assets/<file>.js` yields the mount point of the web client.
* @returns {string} Base URL without a trailing slash
*/
export function getBaseUrl() {
try {
const moduleUrl = new URL(import.meta.url);
const path = moduleUrl.pathname.replace(/\/assets\/[^/]*$/, "");
return `${moduleUrl.origin}${path}`.replace(/\/$/, "");
} catch (_) {
return window.location.origin;
}
}
/**
* Check whether a target URL points at the page already being displayed,
* ignoring the query string and fragment.
* @param {string} target absolute or relative URL
* @returns {boolean} true if navigating there would only reload the page
*/
export function isCurrentLocation(target) {
try {
const targetUrl = new URL(target, window.location.href);
const stripTrailingSlash = (path) => path.replace(/\/$/, "");
return (
targetUrl.origin === window.location.origin &&
stripTrailingSlash(targetUrl.pathname) ===
stripTrailingSlash(window.location.pathname)
);
} catch (_) {
return false;
}
}
/**
* Detect a mobile viewport (coarse pointer + small width, or a mobile UA).
* @returns {boolean} true if the current viewport is considered mobile
*/
export function isMobileViewport() {
return (
(window.matchMedia &&
window.matchMedia("(pointer: coarse)").matches &&
window.innerWidth < 600) ||
/Mobi|Android|iPhone|iPad/i.test(navigator.userAgent)
);
}
/**
* Get the application base URL converted to a WebSocket URL
* @returns {string} WebSocket base URL
*/
export function getWebSocketBaseUrl() {
return getBaseUrl().replace(/^https?/, is_https() ? "wss" : "ws");
}