securityos/node_modules/next/dist/esm/client/components/app-router-announcer.js

64 lines
2.7 KiB
JavaScript

import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
const ANNOUNCER_TYPE = "next-route-announcer";
const ANNOUNCER_ID = "__next-route-announcer__";
function getAnnouncerNode() {
var _existingAnnouncer_shadowRoot;
const existingAnnouncer = document.getElementsByName(ANNOUNCER_TYPE)[0];
if (existingAnnouncer == null ? void 0 : (_existingAnnouncer_shadowRoot = existingAnnouncer.shadowRoot) == null ? void 0 : _existingAnnouncer_shadowRoot.childNodes[0]) {
return existingAnnouncer.shadowRoot.childNodes[0];
} else {
const container = document.createElement(ANNOUNCER_TYPE);
container.style.cssText = "position:absolute";
const announcer = document.createElement("div");
announcer.ariaLive = "assertive";
announcer.id = ANNOUNCER_ID;
announcer.role = "alert";
announcer.style.cssText = "position:absolute;border:0;height:1px;margin:-1px;padding:0;width:1px;clip:rect(0 0 0 0);overflow:hidden;white-space:nowrap;word-wrap:normal";
// Use shadow DOM here to avoid any potential CSS bleed
const shadow = container.attachShadow({
mode: "open"
});
shadow.appendChild(announcer);
document.body.appendChild(container);
return announcer;
}
}
export function AppRouterAnnouncer(param) {
let { tree } = param;
const [portalNode, setPortalNode] = useState(null);
useEffect(()=>{
const announcer = getAnnouncerNode();
setPortalNode(announcer);
return ()=>{
const container = document.getElementsByTagName(ANNOUNCER_TYPE)[0];
if (container == null ? void 0 : container.isConnected) {
document.body.removeChild(container);
}
};
}, []);
const [routeAnnouncement, setRouteAnnouncement] = useState("");
const previousTitle = useRef();
useEffect(()=>{
let currentTitle = "";
if (document.title) {
currentTitle = document.title;
} else {
const pageHeader = document.querySelector("h1");
if (pageHeader) {
currentTitle = pageHeader.innerText || pageHeader.textContent || "";
}
}
// Only announce the title change, but not for the first load because screen
// readers do that automatically.
if (previousTitle.current !== undefined && previousTitle.current !== currentTitle) {
setRouteAnnouncement(currentTitle);
}
previousTitle.current = currentTitle;
}, [
tree
]);
return portalNode ? /*#__PURE__*/ createPortal(routeAnnouncement, portalNode) : null;
}
//# sourceMappingURL=app-router-announcer.js.map