wip: public screen
This commit is contained in:
parent
354fbfede9
commit
09a51edd5f
@ -130,7 +130,7 @@ public class CompetitionWS {
|
||||
|
||||
@OnTextMessage
|
||||
Multi<MessageOut> processAsync(WebSocketConnection connection, MessageIn message) {
|
||||
|
||||
System.out.println(message);
|
||||
if (message.type() == MessageType.REPLY || message.type() == MessageType.ERROR) {
|
||||
try {
|
||||
JsonUni<?> jsonUni = waitingResponse.get(connection).get(message.uuid());
|
||||
|
||||
32
src/main/webapp/src/hooks/useExternalWindow.jsx
Normal file
32
src/main/webapp/src/hooks/useExternalWindow.jsx
Normal file
@ -0,0 +1,32 @@
|
||||
import {createContext, useContext, useReducer} from "react";
|
||||
|
||||
const PubAffContext = createContext({next: [], c1: undefined, c2: undefined});
|
||||
const PubAffDispatchContext = createContext(() => {
|
||||
});
|
||||
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case 'SET_DATA':
|
||||
return {...state, ...action.payload}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export function PubAffProvider({children}) {
|
||||
const [state, dispatch] = useReducer(reducer, {})
|
||||
|
||||
return <PubAffContext.Provider value={state}>
|
||||
<PubAffDispatchContext.Provider value={dispatch}>
|
||||
{children}
|
||||
</PubAffDispatchContext.Provider>
|
||||
</PubAffContext.Provider>
|
||||
}
|
||||
|
||||
export function usePubAffState() {
|
||||
return useContext(PubAffContext)
|
||||
}
|
||||
|
||||
export function usePubAffDispatch() {
|
||||
return useContext(PubAffDispatchContext)
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import {createContext, useContext, useEffect, useId, useReducer, useRef, useState} from "react";
|
||||
import {apiAxios} from "../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
import {useAuth} from "./useAuth.jsx";
|
||||
|
||||
function uuidv4() {
|
||||
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
|
||||
@ -42,6 +43,7 @@ const mountCounter = {};
|
||||
|
||||
export function WSProvider({url, onmessage, children}) {
|
||||
const id = useId();
|
||||
const {is_authenticated} = useAuth()
|
||||
const [isReady, setIsReady] = useState(false)
|
||||
const [state, dispatch] = useReducer(reducer, {listener: []})
|
||||
const ws = useRef(null)
|
||||
@ -71,17 +73,21 @@ export function WSProvider({url, onmessage, children}) {
|
||||
socket.onclose = () => {
|
||||
setIsReady(false)
|
||||
if (mountCounter[id] > 0) {
|
||||
console.log("WSProvider: reconnecting to", url);
|
||||
setTimeout(() => {
|
||||
try {
|
||||
const newSocket = new WebSocket(url)
|
||||
ws.current = newSocket
|
||||
newSocket.onopen = socket.onopen
|
||||
newSocket.onclose = socket.onclose
|
||||
newSocket.onmessage = socket.onmessage
|
||||
}catch (e) {
|
||||
//if (is_authenticated){
|
||||
console.log("WSProvider: reconnecting to", url);
|
||||
try {
|
||||
const newSocket = new WebSocket(url)
|
||||
ws.current = newSocket
|
||||
newSocket.onopen = socket.onopen
|
||||
newSocket.onclose = socket.onclose
|
||||
newSocket.onmessage = socket.onmessage
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
//}else{
|
||||
// console.log("WSProvider: not reconnecting, user is not authenticated");
|
||||
//}
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,11 @@ import {faCircleQuestion} from "@fortawesome/free-regular-svg-icons";
|
||||
import {DrawGraph} from "../../result/DrawGraph.jsx";
|
||||
import {scorePrint, win} from "../../../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
import {createPortal} from "react-dom";
|
||||
import {copyStyles} from "../../../utils/copyStyles.js";
|
||||
import {PubAffProvider, usePubAffDispatch, usePubAffState} from "../../../hooks/useExternalWindow.jsx";
|
||||
import {faDisplay} from "@fortawesome/free-solid-svg-icons";
|
||||
import {PubAffWindow} from "./PubAffWindow.jsx";
|
||||
|
||||
function CupImg() {
|
||||
return <img decoding="async" loading="lazy" width={"16"} height={"16"} className="wp-image-1635"
|
||||
@ -18,33 +23,90 @@ function CupImg() {
|
||||
|
||||
export function CMTable() {
|
||||
const [catId, setCatId] = useState(-1);
|
||||
const menuAction = useRef({});
|
||||
|
||||
return <div className="text-center">
|
||||
<div className="row">
|
||||
<div className="col-md-12 col-lg">
|
||||
<div style={{backgroundColor: "#00c700"}}>
|
||||
A
|
||||
</div>
|
||||
<div style={{backgroundColor: "#0099c7"}}>
|
||||
B
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-12 col-xl-6 col-xxl-5">
|
||||
<div className="card">
|
||||
<div className="card-header">Matches</div>
|
||||
<div className="card-body">
|
||||
<CategorieSelect catId={catId} setCatId={setCatId}/>
|
||||
return <PubAffProvider>
|
||||
<div className="text-center">
|
||||
<div className="row">
|
||||
<div className="col-md-12 col-lg">
|
||||
<div style={{backgroundColor: "#00c700"}}>
|
||||
A
|
||||
</div>
|
||||
<div style={{backgroundColor: "#0099c7"}}>
|
||||
B
|
||||
</div>
|
||||
</div>
|
||||
<div style={{backgroundColor: "#c70000"}}>
|
||||
D
|
||||
<div className="col-md-12 col-xl-6 col-xxl-5">
|
||||
<div className="card">
|
||||
<div className="card-header">Matches</div>
|
||||
<div className="card-body">
|
||||
<CategorieSelect catId={catId} setCatId={setCatId} menuAction={menuAction}/>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{backgroundColor: "#c70000"}}>
|
||||
D
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Menu menuAction={menuAction}/>
|
||||
</div>
|
||||
</div>
|
||||
</PubAffProvider>
|
||||
}
|
||||
|
||||
function CategorieSelect({catId, setCatId}) {
|
||||
const windowName = "FFSAFScorePublicWindow";
|
||||
|
||||
function Menu({menuAction}) {
|
||||
const e = document.getElementById("actionMenu")
|
||||
const [showPubAff, setShowPubAff] = useState(false)
|
||||
|
||||
const externalWindow = useRef(null)
|
||||
const containerEl = useRef(document.createElement("div"))
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionStorage.getItem(windowName + "_open") === "true") {
|
||||
handlePubAff();
|
||||
}
|
||||
//return () => {
|
||||
// if (!externalWindow.current)
|
||||
// return;
|
||||
// externalWindow.current.close();
|
||||
//}
|
||||
}, []);
|
||||
|
||||
const handlePubAff = __ => {
|
||||
if (showPubAff === false || !externalWindow.current || externalWindow.current.closed) {
|
||||
externalWindow.current = window.open("", windowName, "width=800,height=600,left=200,top=200")
|
||||
externalWindow.current.document.body.innerHTML = ""
|
||||
externalWindow.current.document.body.appendChild(containerEl.current)
|
||||
copyStyles(document, externalWindow.current.document)
|
||||
|
||||
externalWindow.current.addEventListener("beforeunload", () => {
|
||||
setShowPubAff(false);
|
||||
externalWindow.current.close();
|
||||
externalWindow.current = null;
|
||||
sessionStorage.removeItem(windowName + "_open");
|
||||
});
|
||||
setShowPubAff(true);
|
||||
sessionStorage.setItem(windowName + "_open", "true");
|
||||
} else {
|
||||
externalWindow.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
if (!e)
|
||||
return <></>;
|
||||
return <>
|
||||
{createPortal(
|
||||
<>
|
||||
<div className="vr" style={{margin: "0 0.5em", height: "100%"}}></div>
|
||||
<FontAwesomeIcon icon={faDisplay} size="xl" style={{color: showPubAff ? "#00c700" : "#6c757d", cursor: "pointer"}}
|
||||
onClick={handlePubAff}/>
|
||||
</>, document.getElementById("actionMenu"))}
|
||||
{externalWindow.current && createPortal(<PubAffWindow document={externalWindow.current.document}/>, containerEl.current)}
|
||||
</>
|
||||
}
|
||||
|
||||
function CategorieSelect({catId, setCatId, menuAction}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data: cats, setData: setCats} = useRequestWS('getAllCategory', {}, setLoading);
|
||||
const {dispatch} = useWS();
|
||||
@ -68,11 +130,11 @@ function CategorieSelect({catId, setCatId}) {
|
||||
<option key={c.id} value={c.id}>{c.name}</option>))}
|
||||
</select>
|
||||
</div>
|
||||
{catId !== -1 && <MatchPanel catId={catId} cat={cat}/>}
|
||||
{catId !== -1 && <MatchPanel catId={catId} cat={cat} menuAction={menuAction}/>}
|
||||
</>
|
||||
}
|
||||
|
||||
function MatchPanel({catId, cat}) {
|
||||
function MatchPanel({catId, cat, menuAction}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {sendRequest, dispatch} = useWS();
|
||||
const [trees, setTrees] = useState([]);
|
||||
@ -144,10 +206,10 @@ function MatchPanel({catId, cat}) {
|
||||
}
|
||||
}, [catId]);
|
||||
|
||||
return <ListMatch cat={cat} matches={matches} trees={trees}/>
|
||||
return <ListMatch cat={cat} matches={matches} trees={trees} menuAction={menuAction}/>
|
||||
}
|
||||
|
||||
function ListMatch({cat, matches, trees}) {
|
||||
function ListMatch({cat, matches, trees, menuAction}) {
|
||||
const [type, setType] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
@ -156,7 +218,7 @@ function ListMatch({cat, matches, trees}) {
|
||||
}, [cat]);
|
||||
|
||||
return <div style={{marginTop: "1em"}}>
|
||||
{cat.type === 3 && <>
|
||||
{cat && cat.type === 3 && <>
|
||||
<ul className="nav nav-tabs">
|
||||
<li className="nav-item">
|
||||
<div className={"nav-link" + (type === 1 ? " active" : "")} aria-current={(type === 1 ? " page" : "false")}
|
||||
@ -184,12 +246,24 @@ function ListMatch({cat, matches, trees}) {
|
||||
|
||||
function MatchList({matches, cat}) {
|
||||
const [activeMatch, setActiveMatch] = useState(null)
|
||||
const publicAffDispatch = usePubAffDispatch();
|
||||
|
||||
const liceName = (cat.liceName || "N/A").split(";");
|
||||
const marches2 = matches.filter(m => m.categorie_ord !== -42)
|
||||
.sort((a, b) => a.categorie_ord - b.categorie_ord)
|
||||
.map(m => ({...m, win: win(m.scores)}))
|
||||
|
||||
const match = matches.find(m => m.id === activeMatch)
|
||||
useEffect(() => {
|
||||
if (!match) {
|
||||
publicAffDispatch({type: 'SET_DATA', payload: {c1: undefined, c2: undefined, next: []}});
|
||||
} else {
|
||||
publicAffDispatch({
|
||||
type: 'SET_DATA',
|
||||
payload: {c1: match.c1, c2: match.c2, next: marches2.filter(m => !m.end && m.id !== activeMatch).map(m => ({c1: m.c1, c2: m.c2}))}
|
||||
});
|
||||
}
|
||||
}, [match]);
|
||||
//useEffect(() => {
|
||||
// if (activeMatch !== null)
|
||||
// setActiveMatch(null);
|
||||
@ -239,7 +313,7 @@ function MatchList({matches, cat}) {
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{activeMatch && <LoadingProvider><ScorePanel matchId={activeMatch} matches={matches}/></LoadingProvider>}
|
||||
{activeMatch && <LoadingProvider><ScorePanel matchId={activeMatch} match={match}/></LoadingProvider>}
|
||||
</>
|
||||
}
|
||||
|
||||
@ -247,6 +321,24 @@ function BuildTree({treeData, matches}) {
|
||||
const scrollRef = useRef(null)
|
||||
const [currentMatch, setCurrentMatch] = useState(null)
|
||||
const {getComb} = useCombs()
|
||||
const publicAffDispatch = usePubAffDispatch();
|
||||
|
||||
const match = matches.find(m => m.id === currentMatch?.matchSelect)
|
||||
useEffect(() => {
|
||||
if (!match) {
|
||||
publicAffDispatch({type: 'SET_DATA', payload: {c1: undefined, c2: undefined}});
|
||||
} else {
|
||||
publicAffDispatch({type: 'SET_DATA', payload: {c1: match.c1, c2: match.c2}});
|
||||
}
|
||||
}, [match]);
|
||||
const next_match = matches.find(m => m.id === currentMatch?.matchNext)
|
||||
useEffect(() => {
|
||||
if (!next_match) {
|
||||
publicAffDispatch({type: 'SET_DATA', payload: {next: []}});
|
||||
} else {
|
||||
publicAffDispatch({type: 'SET_DATA', payload: {next: [{c1: next_match.c1, c2: next_match.c2}]}});
|
||||
}
|
||||
}, [next_match]);
|
||||
|
||||
function parseTree(data_in) {
|
||||
if (data_in?.data == null)
|
||||
@ -292,17 +384,15 @@ function BuildTree({treeData, matches}) {
|
||||
matchSelect={currentMatch?.matchSelect} matchNext={currentMatch?.matchNext} size={23}/>
|
||||
</div>
|
||||
|
||||
{currentMatch?.matchSelect && <LoadingProvider><ScorePanel matchId={currentMatch?.matchSelect} matches={matches}/></LoadingProvider>}
|
||||
{currentMatch?.matchSelect && <LoadingProvider><ScorePanel matchId={currentMatch?.matchSelect} match={match}/></LoadingProvider>}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
function ScorePanel({matchId, matches}) {
|
||||
function ScorePanel({matchId, match}) {
|
||||
const {sendRequest} = useWS()
|
||||
const setLoading = useLoadingSwitcher()
|
||||
|
||||
const match = matches.find(m => m.id === matchId)
|
||||
|
||||
const [end, setEnd] = useState(match?.end || false)
|
||||
const [scoreIn, setScoreIn] = useState("")
|
||||
const inputRef = useRef(null)
|
||||
@ -382,8 +472,8 @@ function ScorePanel({matchId, matches}) {
|
||||
if (!match || match?.end === end)
|
||||
return;
|
||||
|
||||
if (end){
|
||||
if (win(match?.scores) === 0 && match.categorie_ord === -42){
|
||||
if (end) {
|
||||
if (win(match?.scores) === 0 && match.categorie_ord === -42) {
|
||||
toast.error("Impossible de terminer un match nul en tournois.");
|
||||
setEnd(false);
|
||||
return;
|
||||
|
||||
@ -74,8 +74,10 @@ function WSStatus({setPerm}) {
|
||||
|
||||
return <div className="row">
|
||||
<h2 className="col">{name}</h2>
|
||||
<div className="col-auto" style={{margin: "auto 0"}}>Serveur: <ColoredCircle color={isReady ? (inWait ? "#ffad32" : "#00c700") : "#e50000"}/>
|
||||
<div className="col-auto" style={{margin: "auto 0", padding: 0}}>Serveur: <ColoredCircle
|
||||
color={isReady ? (inWait ? "#ffad32" : "#00c700") : "#e50000"}/>
|
||||
</div>
|
||||
<div className="col-auto " id="actionMenu" style={{verticalAlign: "center", textAlign: "center", margin: "auto 0", padding: 0}}></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
134
src/main/webapp/src/pages/competition/editor/PubAffWindow.jsx
Normal file
134
src/main/webapp/src/pages/competition/editor/PubAffWindow.jsx
Normal file
@ -0,0 +1,134 @@
|
||||
import {useCombs} from "../../../hooks/useComb.jsx";
|
||||
import {usePubAffState} from "../../../hooks/useExternalWindow.jsx";
|
||||
|
||||
const noMP = {margin: 0, padding: 0};
|
||||
const redBackground = "radial-gradient(circle, #C80000FF 0%, #000000FF 100%)"
|
||||
const blueBackground = "radial-gradient(circle, #0000C8FF 0%, #000000FF 100%)"
|
||||
const combHeight = "15vh";
|
||||
const text1Style = {fontSize: "min(2.25vw, 8vh)", fontWeight: "bold", marginLeft: "0.5em"};
|
||||
const text2Style = {fontSize: "min(1.7vw, 7vh)", fontWeight: "bold"};
|
||||
|
||||
export function PubAffWindow({document}) {
|
||||
const state = usePubAffState();
|
||||
|
||||
document.title = "A React portal window"
|
||||
document.body.className = "bg-dark text-white overflow-hidden";
|
||||
|
||||
const showScore = false;
|
||||
|
||||
return <>
|
||||
<div className="row text-center"
|
||||
style={{background: "linear-gradient(to bottom, #000000, #323232)", height: `calc(100vh - ${combHeight} * 2)`, ...noMP}}>
|
||||
<div>
|
||||
<div style={{fontSize: "30vh", lineHeight: "30vh"}}>01:30</div>
|
||||
{showScore &&
|
||||
<div className="row" style={noMP}>
|
||||
<div className="col-4" style={noMP}>
|
||||
<div style={{fontSize: "30vh", lineHeight: "30vh", color: "#ff1414"}}>0</div>
|
||||
</div>
|
||||
<div className="col-4" style={noMP}>
|
||||
</div>
|
||||
<div className="col-4" style={noMP}>
|
||||
<div style={{fontSize: "30vh", lineHeight: "30vh", color: "#14adff"}}>0</div>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="row fixed-bottom text-center" style={noMP}>
|
||||
|
||||
</div>
|
||||
<div className="fixed-bottom text-center" style={noMP}>
|
||||
<div className="row" style={noMP}>
|
||||
<div className="col" style={noMP}>
|
||||
<CombDisplay combId={state?.c1} background={"red"}>
|
||||
<span className="position-absolute top-0 start-0 translate-middle-y" style={text1Style}>Actuel</span>
|
||||
</CombDisplay>
|
||||
</div>
|
||||
<div className="col" style={noMP}>
|
||||
<CombDisplay combId={state?.c2} background={"blue"}>
|
||||
<span className="position-absolute bottom-0 start-0 translate-middle-x" style={text2Style}>contre</span>
|
||||
</CombDisplay>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row" style={noMP}>
|
||||
<div className="col" style={noMP}>
|
||||
<CombDisplay combId={state?.next?.[0]?.c1} background={"red"}>
|
||||
<span className="position-absolute top-0 start-0 translate-middle-y" style={text1Style}>Suivant</span>
|
||||
</CombDisplay>
|
||||
</div>
|
||||
<div className="col" style={noMP}>
|
||||
<CombDisplay combId={state?.next?.[0]?.c2} background={"blue"}>
|
||||
<span className="position-absolute bottom-0 start-0 translate-middle-x" style={text2Style}>contre</span>
|
||||
</CombDisplay>
|
||||
</div>
|
||||
</div>
|
||||
{!showScore && <div className="row" style={noMP}>
|
||||
<MatchDisplay state={state}/>
|
||||
</div>}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
function MatchDisplay({state}) {
|
||||
const {getComb} = useCombs();
|
||||
const combs = state?.next?.slice(1, 6) || [];
|
||||
|
||||
console.log("Rendering MatchDisplay for", combs);
|
||||
|
||||
return <div className="col-12 position-relative" style={{height: `calc(${combHeight} * 2)`}}>
|
||||
<div className="position-absolute bottom-0 start-0" style={{height: "100%", background: redBackground, width: "50vw"}}/>
|
||||
<div className="position-absolute bottom-0 start-50" style={{height: "100%", background: blueBackground, width: "50vw"}}/>
|
||||
<div className="position-absolute top-0 start-0 w-100" style={{...noMP, height: "0.4vh", backgroundColor: "#646464AA"}}/>
|
||||
<div className="position-absolute top-0 start-50" style={{
|
||||
...noMP,
|
||||
height: `calc(${combHeight} * 1.5)`,
|
||||
width: "0.4vh",
|
||||
backgroundColor: "#646464AA",
|
||||
margin: `calc(${combHeight} * 0.25) 0`
|
||||
}}/>
|
||||
|
||||
<div className="position-relative" style={{marginTop: `1vh`, color: "#dcdcdc"}}>
|
||||
{combs.map((match, index) => {
|
||||
const c1 = getComb(match.c1, "");
|
||||
const c2 = getComb(match.c2, "");
|
||||
|
||||
return <div key={index} className="row" style={noMP}>
|
||||
<div className="col" style={{fontSize: `3vh`, margin: "0.5vh 1vw"}}>
|
||||
{c1.fname} {c1.lname}
|
||||
</div>
|
||||
<div className="col" style={{fontSize: `3vh`}}>
|
||||
{c2.fname} {c2.lname}
|
||||
</div>
|
||||
{index !== combs.length - 1 && <div className="w-75" style={{...noMP, height: "0.2vh", margin: "0 12.5vw", backgroundColor: "#646464AA"}}/>}
|
||||
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
function CombDisplay({combId, background, children}) {
|
||||
const {getComb} = useCombs();
|
||||
const comb = getComb(combId, "");
|
||||
|
||||
//console.log("Rendering CombDisplay for", combId, comb);
|
||||
|
||||
return <div className="col position-relative"
|
||||
style={{
|
||||
height: combHeight,
|
||||
background: background === "red" ? redBackground : blueBackground,
|
||||
display: "flex",
|
||||
flexDirection: background === "red" ? "row" : "row-reverse",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}>
|
||||
{comb !== "" && <>
|
||||
<img src={`/flags/svg/ad.svg`} alt={"fr"} style={{width: "6vw", height: "min(9vh, 6vw)", objectFit: "contain", margin: "0 .5vw"}}/>
|
||||
<div style={{fontSize: "min(3.5vw, 10vh)"}}>{comb.fname} {comb.lname}</div>
|
||||
<img src={`/flags/svg/${comb.country.toLowerCase()}.svg`} alt={comb.country}
|
||||
style={{width: "4vw", height: "8vh", objectFit: "contain", margin: "0 1.25vw"}}/>
|
||||
</>}
|
||||
<div className="position-absolute top-0 start-0 w-100" style={{...noMP, height: "0.4vh", backgroundColor: "#646464AA"}}/>
|
||||
{children}
|
||||
</div>
|
||||
}
|
||||
21
src/main/webapp/src/utils/copyStyles.js
Normal file
21
src/main/webapp/src/utils/copyStyles.js
Normal file
@ -0,0 +1,21 @@
|
||||
export function copyStyles(sourceDoc, targetDoc) {
|
||||
Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
|
||||
if (styleSheet.cssRules) {
|
||||
// true for inline styles
|
||||
const newStyleEl = sourceDoc.createElement("style");
|
||||
|
||||
Array.from(styleSheet.cssRules).forEach(cssRule => {
|
||||
newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
|
||||
});
|
||||
|
||||
targetDoc.head.appendChild(newStyleEl);
|
||||
} else if (styleSheet.href) {
|
||||
// true for stylesheets loaded from a URL
|
||||
const newLinkEl = sourceDoc.createElement("link");
|
||||
|
||||
newLinkEl.rel = "stylesheet";
|
||||
newLinkEl.href = styleSheet.href;
|
||||
targetDoc.head.appendChild(newLinkEl);
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user