48 lines
2.1 KiB
TypeScript
48 lines
2.1 KiB
TypeScript
import { gameFrontendRuntimeConfig } from '../config/runtimeConfig';
|
|
|
|
// 이름은 앱이 직접 연 탭에만 부여한다. URL/sessionStorage 표식은 링크 복사나
|
|
// 브라우저의 새 탭 열기에도 전달될 수 있으므로 닫기 권한 판정에 사용하지 않는다.
|
|
const auxiliaryWindowPrefix = 'sammo-auxiliary:';
|
|
|
|
export const isAuxiliaryWindow = (): boolean => window.name.startsWith(auxiliaryWindowPrefix);
|
|
|
|
export const installAuxiliaryNavigation = (): void => {
|
|
document.addEventListener(
|
|
'click',
|
|
(event: MouseEvent) => {
|
|
if (
|
|
event.defaultPrevented ||
|
|
event.button !== 0 ||
|
|
event.ctrlKey ||
|
|
event.metaKey ||
|
|
event.shiftKey ||
|
|
event.altKey
|
|
)
|
|
return;
|
|
const link = event.target instanceof Element ? event.target.closest('a') : null;
|
|
if (!link || link.target !== '_blank' || link.hasAttribute('download')) return;
|
|
const url = new URL(link.href, window.location.href);
|
|
const basePath = gameFrontendRuntimeConfig.appBasePath;
|
|
if (url.origin !== window.location.origin || !url.pathname.startsWith(basePath)) return;
|
|
|
|
event.preventDefault();
|
|
const child = window.open('about:blank', '_blank');
|
|
if (!child) {
|
|
// 팝업 차단 시 현재 탭에서 열어 돌아가기 동작을 제공한다.
|
|
window.location.assign(url.href);
|
|
return;
|
|
}
|
|
child.name = `${auxiliaryWindowPrefix}${crypto.randomUUID()}`;
|
|
child.opener = null;
|
|
// 새 문서 소유의 링크로 이동해야 원본 링크의 referrer 정책도 적용된다.
|
|
const destination = child.document.createElement('a');
|
|
destination.href = url.href;
|
|
destination.rel = link.rel;
|
|
destination.referrerPolicy = link.referrerPolicy;
|
|
child.document.body.append(destination);
|
|
destination.click();
|
|
},
|
|
true
|
|
);
|
|
};
|