Skip to content

Commit

Permalink
Merge pull request #225 from chrisdavidmills/window-management-demo
Browse files Browse the repository at this point in the history
Add demo for Window Management API
  • Loading branch information
Rumyra authored Oct 18, 2023
2 parents df1f3a0 + 4f04471 commit 3e75d61
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 14 deletions.
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ Code examples that accompany various MDN DOM and Web API documentation pages.

* The "audiocontext-setsinkid" directory contains an example of how to use the [`AudioContext.setSinkId()`](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId) method and related features. [Run the example live](https://mdn.github.io/dom-examples/audiocontext-setsinkid/).

* The "auxclick" directory contains a simple example demonstrating the new <code>auxclick</code> event type. See [GlobalEventHandlers.auxclick](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onauxclick) for more details, or [run the example live](https://mdn.github.io/dom-examples/auxclick/).
* The "auxclick" directory contains a basic example demonstrating the new <code>auxclick</code> event type. See [GlobalEventHandlers.auxclick](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onauxclick) for more details, or [run the example live](https://mdn.github.io/dom-examples/auxclick/).

* The "canvas" directory contains an example "chroma-keying" demonstrating how to use the Canvas API to manipulate videos: see [Manipulating video using canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas) or [run the example live](https://mdn.github.io/dom-examples/canvas/chroma-keying/).

* The "channel-messaging-basic" directory contains a simple example demonstrating the basics of channel messaging; see [Channel Messaging API](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API) or [run the example live](https://mdn.github.io/dom-examples/channel-messaging-basic/).
* The "channel-messaging-basic" directory contains a basic example demonstrating the basics of channel messaging; see [Channel Messaging API](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API) or [run the example live](https://mdn.github.io/dom-examples/channel-messaging-basic/).

* The "channel-messaging-multimessage" directory contains another channel messaging demo, showing how multiple messages can be sent between browsing contexts. See [Channel Messaging API](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API) for more details. [Run the demo live](https://mdn.github.io/dom-examples/channel-messaging-multimessage/).

Expand All @@ -21,48 +21,50 @@ Code examples that accompany various MDN DOM and Web API documentation pages.

* The "indexeddb-api" directory contains a demo for the [IndexedDB API](https://mdn.github.io/dom-examples/indexeddb-api/index.html).

* The "insert-adjacent" directory contains simple demos for [insertAdjacentElement](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentElement.html) and [insertAdjacentText](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentText.html).
* The "insert-adjacent" directory contains basic demos for [insertAdjacentElement](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentElement.html) and [insertAdjacentText](https://mdn.github.io/dom-examples/insert-adjacent/insertAdjacentText.html).

* The "matchmedia" directory contains a simple demo to test matchMedia functionality. See [Window.matchMedia](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) for more details. [Run the demo live](https://mdn.github.io/dom-examples/matchmedia/).
* The "matchmedia" directory contains a basic demo to test matchMedia functionality. See [Window.matchMedia](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) for more details. [Run the demo live](https://mdn.github.io/dom-examples/matchmedia/).

* The "mediaquerylist" directory contains a simple demo to test more advanced matchMedia/mediaquerylist functionality. See [MediaQueryList](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList) for more details. [Run the demo live](https://mdn.github.io/dom-examples/mediaquerylist/index.html).
* The "mediaquerylist" directory contains a basic demo to test more advanced matchMedia/mediaquerylist functionality. See [MediaQueryList](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList) for more details. [Run the demo live](https://mdn.github.io/dom-examples/mediaquerylist/index.html).

* The "media" directory contains examples and demos showing how to use HTML and DOM [media elements and APIs](https://developer.mozilla.org/en-US/docs/Web/Media).

* The "payment-request" directory contains examples of the [Payment Request API](https://developer.mozilla.org/en-US/docs/Web/API/Payment_Request_API).

* The "pointerevents" directory is for examples and demos of the [Pointer Events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) standard.

* The "pointer-lock" directory contains a simple demo to show usage of the Pointer Lock API. You can find more explanation of how the demo works at the main MDN [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) page. [Run the demo live](https://mdn.github.io/dom-examples/pointer-lock/).
* The "pointer-lock" directory contains a basic demo to show usage of the Pointer Lock API. You can find more explanation of how the demo works at the main MDN [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) page. [Run the demo live](https://mdn.github.io/dom-examples/pointer-lock/).

* The "popover-api" directory is for examples and demos of the [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) standard. Go to the [Popover API demo index](popover-api/) to see what's available.

* The "reporting-api" directory contains a couple of simple demos to show usage of the Reprting API. You can find more explanation of how the API works in the main MDN [Reporting API](https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API) docs. [Run the deprecation report demo live](https://mdn.github.io/dom-examples/reporting-api/deprecation_report.html).
* The "reporting-api" directory contains a couple of basic demos to show usage of the Reprting API. You can find more explanation of how the API works in the main MDN [Reporting API](https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API) docs. [Run the deprecation report demo live](https://mdn.github.io/dom-examples/reporting-api/deprecation_report.html).

* The "resize-event" directory contains a simple demo to show how you can use the [resize event](https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event). Resize the browser window either by height or width to see the size of your current window. [Run the demo live](https://mdn.github.io/dom-examples/resize-event).
* The "resize-event" directory contains a basic demo to show how you can use the [resize event](https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event). Resize the browser window either by height or width to see the size of your current window. [Run the demo live](https://mdn.github.io/dom-examples/resize-event).

* The "screenleft-screentop" directory contains a demo to show how you could use the [Window.screenLeft](https://developer.mozilla.org/en-US/docs/Web/API/Window/screenLeft) and [Window.screenTop](https://developer.mozilla.org/en-US/docs/Web/API/Window/screenTop) properties to draw a circle on a canvas that always stays in the same physical place on the screen when you move your browser window. [Run the demo live](https://mdn.github.io/dom-examples/screenleft-screentop/).

* The "scrolltooptions" directory contains a demo to show how you could use the [ScrollToOptions](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions) dictionary along with the [Window.ScrollTo()](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) method to programmatically scroll a web page. [Run the demo live](https://mdn.github.io/dom-examples/scrolltooptions/).

* The "server-sent-events" directory contains a very simple SSE demo that uses PHP to create the server. You can find more information in our [Using server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) article. To run the demo you'll need to serve the files from a server that supports PHP; [MAMP](https://www.mamp.info/en/) is a good PHP test server environment.
* The "server-sent-events" directory contains a very basic SSE demo that uses PHP to create the server. You can find more information in our [Using server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) article. To run the demo you'll need to serve the files from a server that supports PHP; [MAMP](https://www.mamp.info/en/) is a good PHP test server environment.

* The "streams" directory contains demos of the Streams API for using low-level I/O processing.

* The "touchevents" directory is for examples and demos of the [Touch Events](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events) standard.

* The "web-animations-api" directory contains [Web Animation API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) demos. See the [web animations README](web-animations-api/README.md) for more information.

* The "web-storage" directory contains a simple demo to show usage of the Web Storage API. For more detail on how it works, read [Using the Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API). [View the demo live](https://mdn.github.io/dom-examples/web-storage/).
* The "web-storage" directory contains a basic demo to show usage of the Web Storage API. For more detail on how it works, read [Using the Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API). [View the demo live](https://mdn.github.io/dom-examples/web-storage/).

* The "view-transitions" directory contains a simple demo to show usage of the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API). [View the demo live](https://mdn.github.io/dom-examples/view-transitions/).
* The "view-transitions" directory contains a basic demo to show usage of the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API). [View the demo live](https://mdn.github.io/dom-examples/view-transitions/).

* The "web-share" directory contains a simple demo to show usage of the [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share). [View the demo live](https://mdn.github.io/dom-examples/web-share/).
* The "web-share" directory contains a basic demo to show usage of the [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share). [View the demo live](https://mdn.github.io/dom-examples/web-share/).

* The "web-workers" directory contains a simple web worker to demonstrate how [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) work. [View the demo live](https://mdn.github.io/dom-examples/web-workers/simple-web-worker/).
* The "web-workers" directory contains a basic web worker to demonstrate how [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) work. [View the demo live](https://mdn.github.io/dom-examples/web-workers/simple-web-worker/).

* The ["webgl-examples"](webgl-examples/README.md) directory contains a number of WebGL examples that demonstrate the [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), which is used for 2D and 3D graphics on the web.

* The "webgpu-compute-demo" directory contains an example that demonstrates basic usage of the [WebGPU API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) compute pipeline, which is used for performing general computation on the GPU. [View the demo live](https://mdn.github.io/dom-examples/webgpu-compute-demo/).

* The "webgpu-render-demo" directory contains an example that demonstrates basic usage of the [WebGPU API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) render pipeline, which is used for rendering high-performance graphics via the GPU. [View the demo live](https://mdn.github.io/dom-examples/webgpu-render-demo/).
* The "webgpu-render-demo" directory contains an example that demonstrates basic usage of the [WebGPU API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) render pipeline, which is used for rendering high-performance graphics via the GPU. [View the demo live](https://mdn.github.io/dom-examples/webgpu-render-demo/).

* The "window-management-api" directory contains a basic demo to show usage of the [Window Management API](https://developer.mozilla.org/en-US/docs/Web/API/Window_Management_API). [View the demo live](https://mdn.github.io/dom-examples/window-management-api/).
21 changes: 21 additions & 0 deletions window-management-api/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
html {
font-family: Arial, Helvetica, sans-serif;
font-size: 1.1rem;
}

body {
width: 70%;
max-width: 800px;
margin: 0 auto;
}

p,
li {
letter-spacing: 0.5px;
line-height: 1.5;
}

hr {
color: gray;
border-width: 3px;
}
33 changes: 33 additions & 0 deletions window-management-api/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Window Management API demo</title>

<link href="index.css" rel="stylesheet">
<script defer src="index.js"></script>
</head>

<body>
<h1>Window Management API demo</h1>

<p>This page provides a basic demo of the <a
href="https://developer.mozilla.org/en-US/docs/Web/API/Window_Management_API">Window Management API</a>, which in
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Window_Management_API#browser_compatibility">supporting
browsers</a> provides a button to open multiple windows to provide an HTML, CSS, and JavaScript learning
environment, tailored to whether you have one, two, or more screens available.
</p>

<p>On non-supporting browsers it will provide links to the different windows instead, so users of those browsers can
have access to that content, and can choose to arrange the opened pages in new tabs or windows as they see fit.</p>

<hr>

<section>


</section>
</body>

</html>
190 changes: 190 additions & 0 deletions window-management-api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Data for the sites to open
const sites = [
{
"name": "MDN code playground",
"url": "https://developer.mozilla.org/en-US/play"
},
{
"name": "MDN HTML reference",
"url": "https://developer.mozilla.org/en-US/docs/Web/HTML"
},
{
"name": "MDN CSS reference",
"url": "https://developer.mozilla.org/en-US/docs/Web/CSS"
},
{
"name": "MDN JavaScript reference",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript"
}
]

const outputElem = document.querySelector("section");

// Array to hold references to the currently open windows
let windowRefs = [];

// Constants to represent the width and height of the Chrome UI when calculating the window size to open
const WINDOW_CHROME_Y = 51;
const WINDOW_CHROME_X = 1;

// Feature detection: we'll open windows in sites that support the API
// and create links in sites that do not
if ("getScreenDetails" in window) {
// The Window Management API is supported
createButton();
} else {
// The Window Management API is not supported
createLinks(sites);
}

// Functions for creating the links or the button

function createLinks(sites) {
const list = document.createElement("ul");

sites.forEach(site => {
const listItem = document.createElement("li");
const link = document.createElement("a");

link.textContent = site.name;
link.href = site.url;

listItem.appendChild(link);
list.appendChild(listItem);
});

outputElem.appendChild(list);
}

function createButton() {
const btn = document.createElement("button");
btn.textContent = "Open learning environment"
outputElem.appendChild(btn);

btn.addEventListener("click", openWindows);
}

// Functions for creating the windows

function openWindow(left, top, width, height, url) {
const windowFeatures = `left=${left},top=${top},width=${width},height=${height}`;
const windowRef = window.open(
url,
"_blank", // needed for it to open in a new window
windowFeatures,
);

// Store a reference to the window in the windowRefs array
windowRefs.push(windowRef);

}

function closeAllWindows() {
// Loop through all window refs and close each one
windowRefs.forEach(windowRef => {
windowRef.close();
});
windowRefs = [];
}

async function openWindows() {
const screenDetails = await window.getScreenDetails();

// Return the number of screens
const noOfScreens = screenDetails.screens.length;

if (noOfScreens === 1) {
// Only one screen
const screen1 = screenDetails.screens[0];
// Windows will be half the width and half the height of the screen
let windowWidth = Math.floor((screen1.availWidth - 2 * WINDOW_CHROME_X) / 2);
let windowHeight = Math.floor((screen1.availHeight - 2 * WINDOW_CHROME_Y) / 2);

openWindow(screen1.availLeft,
screen1.availTop,
windowWidth,
windowHeight,
sites[0].url);
openWindow(windowWidth + screen1.availLeft + WINDOW_CHROME_X,
screen1.availTop,
windowWidth,
windowHeight,
sites[1].url);
openWindow(screen1.availLeft,
windowHeight + screen1.availHeight + WINDOW_CHROME_Y,
windowWidth,
windowHeight,
sites[2].url);
openWindow(windowWidth + screen1.availLeft + WINDOW_CHROME_X,
windowHeight + screen1.availHeight + WINDOW_CHROME_Y,
windowWidth,
windowHeight,
sites[3].url);

} else {
// Two screens or more
const screen1 = screenDetails.screens[0];
const screen2 = screenDetails.screens[1];
// Windows will be a third the width and the full height of the screen
let windowWidth = Math.floor((screen1.availWidth - 3 * WINDOW_CHROME_X) / 3);
let windowHeight = Math.floor(screen1.availHeight - WINDOW_CHROME_Y);

// Open the reference windows in thirds across the entire height of the primary screen
openWindow(screen1.availLeft,
screen1.availTop,
windowWidth,
windowHeight,
sites[1].url);
openWindow(screen1.availLeft + windowWidth + WINDOW_CHROME_X,
screen1.availTop,
windowWidth,
windowHeight,
sites[2].url);
openWindow(screen1.availLeft + ((windowWidth + WINDOW_CHROME_X) * 2),
screen1.availTop,
windowWidth,
windowHeight,
sites[3].url);

// Open the code editor the full size of the secondary screen
openWindow(screen2.availLeft,
screen2.availTop,
screen2.availWidth,
screen2.availHeight,
sites[0].url);
}

// Check whether one of our popup windows has been closed
// If so, close them all

closeMonitor = setInterval(checkWindowClose, 250);

function checkWindowClose() {
if (windowRefs.some(windowRef => windowRef.closed)) {
closeAllWindows();
clearInterval(closeMonitor);
}
}

// Also close our popup windows if the main app window is closed

window.addEventListener("beforeunload", () => {
closeAllWindows();
});

screenDetails.addEventListener("screenschange", () => {
// If the new number of screens is different to the old number of screens, report the difference
if (screenDetails.screens.length !== noOfScreens) {
console.log(
`The screen count changed from ${noOfScreens} to ${screenDetails.screens.length}`,
);
}

// If the windows are open, close them and then open them again
// So that they fit with the new screen configuration
if (windowRefs.length > 0) {
closeAllWindows();
openWindows();
}
});
}

0 comments on commit 3e75d61

Please sign in to comment.