From d391b42aa5da2c89a3c2ebf2b823db9619ee1063 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 12:10:57 +0200 Subject: [PATCH 1/6] Rename to re-use to toggle Experimental Browser features --- webapp/templates/team/index.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/templates/team/index.html.twig b/webapp/templates/team/index.html.twig index ae6244810d..3f0f9b04c2 100644 --- a/webapp/templates/team/index.html.twig +++ b/webapp/templates/team/index.html.twig @@ -24,7 +24,7 @@ {% block messages %}{% endblock %} {% block content %} -
+
{% include 'team/partials/index_content.html.twig' %}
{% endblock %} @@ -37,7 +37,7 @@ $flash = $('[data-flash-messages]').children(); } - function setFlashAndProgress() { + function setFlashAndProgressAndExperimentalFeatures() { var $newProgress = $('[data-ajax-refresh-target] > [data-progress-bar]'); if ($newProgress.length) { var $oldProgress = $('body > [data-progress-bar]'); From f3164af27dd0dc2a25d69f429a7e9241f1415529 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 12:16:07 +0200 Subject: [PATCH 2/6] Add the button Default is this hidden as only 50% of the browser engines on my system support this feature. --- webapp/public/js/domjudge.js | 19 +++++++++++++++++++ webapp/public/style_domjudge.css | 8 ++++++++ webapp/templates/team/index.html.twig | 2 ++ .../team/partials/index_content.html.twig | 9 +++++++++ 4 files changed, 38 insertions(+) diff --git a/webapp/public/js/domjudge.js b/webapp/public/js/domjudge.js index e3b9250c3b..62bdbcb874 100644 --- a/webapp/public/js/domjudge.js +++ b/webapp/public/js/domjudge.js @@ -1292,3 +1292,22 @@ function initScoreboardSubmissions() { }); }); } + +$(function () { + function checkExperimentalFeature() { + if ("documentPictureInPicture" in window) { + // Only the team interface has this button. + const togglePipButton = document.querySelector("#pop-out-button"); + if (togglePipButton) { + togglePipButton.style.display = 'inline'; + togglePipButton.addEventListener("click", togglePictureInPicture, false); + } + } else { + const pipMessage = document.querySelector("#no-picture-in-picture"); + if (pipMessage) { + pipMessage.style.display = 'inline'; + } + } + } + checkExperimentalFeature(); +}); \ No newline at end of file diff --git a/webapp/public/style_domjudge.css b/webapp/public/style_domjudge.css index 18eb31ef24..f8a9454e7e 100644 --- a/webapp/public/style_domjudge.css +++ b/webapp/public/style_domjudge.css @@ -757,3 +757,11 @@ blockquote { height: 80vh; border: 1px solid grey; } + +#pop-out-button { + display: none; +} + +#no-picture-in-picture { + display: none; +} \ No newline at end of file diff --git a/webapp/templates/team/index.html.twig b/webapp/templates/team/index.html.twig index 3f0f9b04c2..b735aa6f64 100644 --- a/webapp/templates/team/index.html.twig +++ b/webapp/templates/team/index.html.twig @@ -46,6 +46,8 @@ } $('[data-flash-messages]').html($flash); + + checkExperimentalFeature(); } window.initModalClarificationPreviewAdd = function() { diff --git a/webapp/templates/team/partials/index_content.html.twig b/webapp/templates/team/partials/index_content.html.twig index 34c7ca453c..22b3cbb194 100644 --- a/webapp/templates/team/partials/index_content.html.twig +++ b/webapp/templates/team/partials/index_content.html.twig @@ -46,6 +46,15 @@ Request clarification
+

Experimental feature

+
+

+ Ask your Tech team for another browser (Document Picture-in-Picture API not available +

+ + PR Pop-out + +

{% endif %} From 6c555d869e6dc75a675c511c654dfde47d8db8a0 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:54:41 +0200 Subject: [PATCH 3/6] Show minimal page to pop-out --- webapp/templates/team/partials/index_content.html.twig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/templates/team/partials/index_content.html.twig b/webapp/templates/team/partials/index_content.html.twig index 22b3cbb194..88004111c0 100644 --- a/webapp/templates/team/partials/index_content.html.twig +++ b/webapp/templates/team/partials/index_content.html.twig @@ -54,6 +54,15 @@ PR Pop-out + +
+
+ {% set displayRank = not contest.freezeData.showFrozen %} + {% include 'partials/scoreboard_table.html.twig' with {displayRank: displayRank, jury: false, public: false} %} + 3 + C++/warning +
+
From 1743f212d172a233212b912bd83ad78229097c3a Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:55:35 +0200 Subject: [PATCH 4/6] Hide the box In the next commits we can pop it out, and display it there. --- webapp/public/style_domjudge.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webapp/public/style_domjudge.css b/webapp/public/style_domjudge.css index f8a9454e7e..f81335392b 100644 --- a/webapp/public/style_domjudge.css +++ b/webapp/public/style_domjudge.css @@ -764,4 +764,8 @@ blockquote { #no-picture-in-picture { display: none; +} + +#pop-out-container { + display: none; } \ No newline at end of file From d7ecb66de975244364b81f5533e6ea5a68bc3fd2 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:08:26 +0200 Subject: [PATCH 5/6] Demo the pop-out --- webapp/public/js/domjudge.js | 81 ++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/webapp/public/js/domjudge.js b/webapp/public/js/domjudge.js index 62bdbcb874..527433fcb3 100644 --- a/webapp/public/js/domjudge.js +++ b/webapp/public/js/domjudge.js @@ -1294,7 +1294,7 @@ function initScoreboardSubmissions() { } $(function () { - function checkExperimentalFeature() { + window.checkExperimentalFeature = function () { if ("documentPictureInPicture" in window) { // Only the team interface has this button. const togglePipButton = document.querySelector("#pop-out-button"); @@ -1308,6 +1308,81 @@ $(function () { pipMessage.style.display = 'inline'; } } - } + }; checkExperimentalFeature(); -}); \ No newline at end of file + + // Heavily based on: https://github.com/mdn/dom-examples/tree/main/document-picture-in-picture + const popOutFrame = document.querySelector("#pop-out-frame"); + const popOutContainer = document.querySelector("#pop-out-container"); + async function togglePictureInPicture() { + if (!(popOutFrame && popOutContainer)) { + console.log("Unexpected page, we only run if both are available."); + return; + } + + popOutContainer.style.display = 'block'; + // Early return if there's already a Picture-in-Picture window open + if (window.documentPictureInPicture.window) { + popOutContainer.append(popOutFrame); + window.documentPictureInPicture.window.close(); + return; + } + + // Open a Picture-in-Picture window. + const pipWindow = await window.documentPictureInPicture.requestWindow({ + width: popOutFrame.clientWidth, + height: popOutFrame.clientHeight + }); + + pipWindow.document.body.style.padding = 0; + pipWindow.document.body.style.margin = 0; + const scoreBoards = document.querySelectorAll("#pop-out-frame .scoreboard"); + scoreBoards.forEach((scoreBoard) => { + scoreBoard.style.margin = 0; + }); + console.log("sb", scoreBoards); + + // Add pagehide listener to handle the case of the pip window being closed using the browser X button + pipWindow.addEventListener("pagehide", (event) => { + popOutContainer.style.display = 'none'; + popOutContainer.append(popOutFrame); + }); + + + // Copy style sheets over from the initial document + // so that the player looks the same. + [...document.styleSheets].forEach((styleSheet) => { + try { + if (styleSheet.href) { + const link = document.createElement("link"); + + link.rel = "stylesheet"; + link.type = styleSheet.type; + link.media = styleSheet.media; + link.href = styleSheet.href; + + pipWindow.document.head.appendChild(link); + } else { + const cssRules = [...styleSheet.cssRules] + .map((rule) => rule.cssText) + .join(""); + const style = document.createElement("style"); + + style.textContent = cssRules; + pipWindow.document.head.appendChild(style); + } + } catch (e) { + const link = document.createElement("link"); + + link.rel = "stylesheet"; + link.type = styleSheet.type; + link.media = styleSheet.media; + link.href = styleSheet.href; + + pipWindow.document.head.appendChild(link); + } + }); + + pipWindow.document.body.append(popOutFrame); + } +}); From fd84c32e7e5f934427e0978066b462da83dbbdea Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:23:12 +0200 Subject: [PATCH 6/6] Remove implementation comment. --- webapp/templates/team/partials/index_content.html.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/webapp/templates/team/partials/index_content.html.twig b/webapp/templates/team/partials/index_content.html.twig index 88004111c0..f2fd898d3b 100644 --- a/webapp/templates/team/partials/index_content.html.twig +++ b/webapp/templates/team/partials/index_content.html.twig @@ -54,7 +54,6 @@ PR Pop-out -
{% set displayRank = not contest.freezeData.showFrozen %}