Skip to content

Commit a51e288

Browse files
Add demo for Window Management API
1 parent e745b9b commit a51e288

File tree

4 files changed

+263
-14
lines changed

4 files changed

+263
-14
lines changed

README.md

+16-14
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ Code examples that accompany various MDN DOM and Web API documentation pages.
55

66
* 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/).
77

8-
* 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/).
8+
* 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/).
99

1010
* 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/).
1111

12-
* 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/).
12+
* 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/).
1313

1414
* 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/).
1515

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

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

24-
* 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).
24+
* 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).
2525

26-
* 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/).
26+
* 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/).
2727

28-
* 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).
28+
* 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).
2929

3030
* 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).
3131

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

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

36-
* 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/).
36+
* 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/).
3737

3838
* 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.
3939

40-
* 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).
40+
* 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).
4141

42-
* 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).
42+
* 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).
4343

4444
* 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/).
4545

4646
* 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/).
4747

48-
* 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.
48+
* 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.
4949

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

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

5454
* 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.
5555

56-
* 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/).
56+
* 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/).
5757

58-
* 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/).
58+
* 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/).
5959

60-
* 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/).
60+
* 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/).
6161

62-
* 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/).
62+
* 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/).
6363

6464
* 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.
6565

6666
* 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/).
6767

68-
* 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/).
68+
* 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/).
69+
70+
* 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/).

window-management-api/index.css

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
html {
2+
font-family: Arial, Helvetica, sans-serif;
3+
font-size: 1.1rem;
4+
}
5+
6+
body {
7+
width: 70%;
8+
max-width: 800px;
9+
margin: 0 auto;
10+
}
11+
12+
p,
13+
li {
14+
letter-spacing: 0.5px;
15+
line-height: 1.5;
16+
}
17+
18+
hr {
19+
color: gray;
20+
border-width: 3px;
21+
}

window-management-api/index.html

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Window Management API demo</title>
7+
8+
<link href="index.css" rel="stylesheet">
9+
<script defer src="index.js"></script>
10+
</head>
11+
12+
<body>
13+
<h1>Window Management API demo</h1>
14+
15+
<p>This page provides a basic demo of the <a
16+
href="https://developer.mozilla.org/en-US/docs/Web/API/Window_Management_API">Window Management API</a>, which in
17+
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Window_Management_API#browser_compatibility">supporting
18+
browsers</a> provides a button to open multiple windows to provide an HTML, CSS, and JavaScript learning
19+
environment, tailored to whether you have one, two, or more screens available.
20+
</p>
21+
22+
<p>On non-supporting browsers it will provide links to the different windows instead, so users of those browsers can
23+
have access to that content, and can choose to arrange the opened pages in new tabs or windows as they see fit.</p>
24+
25+
<hr>
26+
27+
<section>
28+
29+
30+
</section>
31+
</body>
32+
33+
</html>

window-management-api/index.js

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// Data for the sites to open
2+
const sites = [
3+
{
4+
"name": "MDN code playground",
5+
"url": "https://developer.mozilla.org/en-US/play"
6+
},
7+
{
8+
"name": "MDN HTML reference",
9+
"url": "https://developer.mozilla.org/en-US/docs/Web/HTML"
10+
},
11+
{
12+
"name": "MDN CSS reference",
13+
"url": "https://developer.mozilla.org/en-US/docs/Web/CSS"
14+
},
15+
{
16+
"name": "MDN JavaScript reference",
17+
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript"
18+
}
19+
]
20+
21+
const outputElem = document.querySelector("section");
22+
23+
// Array to hold references to the currently open windows
24+
let windowRefs = [];
25+
26+
// Constants to represent the width and height of the Chrome UI when calculating the window size to open
27+
const WINDOW_CHROME_Y = 51;
28+
const WINDOW_CHROME_X = 1;
29+
30+
// Feature detection: we'll open windows in sites that support the API
31+
// and create links in sites that do not
32+
if ("getScreenDetails" in window) {
33+
// The Window Management API is supported
34+
createButton();
35+
} else {
36+
// The Window Management API is not supported
37+
createLinks(sites);
38+
}
39+
40+
// Functions for creating the links or the button
41+
42+
function createLinks(sites) {
43+
const list = document.createElement("ul");
44+
45+
sites.forEach(site => {
46+
const listItem = document.createElement("li");
47+
const link = document.createElement("a");
48+
49+
link.textContent = site.name;
50+
link.href = site.url;
51+
52+
listItem.appendChild(link);
53+
list.appendChild(listItem);
54+
});
55+
56+
outputElem.appendChild(list);
57+
}
58+
59+
function createButton() {
60+
const btn = document.createElement("button");
61+
btn.textContent = "Open learning environment"
62+
outputElem.appendChild(btn);
63+
64+
btn.addEventListener("click", openWindows);
65+
}
66+
67+
// Functions for creating the windows
68+
69+
function openWindow(left, top, width, height, url) {
70+
const windowFeatures = `left=${left},top=${top},width=${width},height=${height}`;
71+
const windowRef = window.open(
72+
url,
73+
Math.random().toString(), // a target is needed for it to open as a separate window rather than a tab
74+
windowFeatures,
75+
);
76+
77+
78+
79+
// Store a reference to the window in the windowRefs array
80+
windowRefs.push(windowRef);
81+
82+
}
83+
84+
function closeAllWindows() {
85+
// Loop through all window refs and close each one
86+
windowRefs.forEach(windowRef => {
87+
windowRef.close();
88+
});
89+
windowRefs = [];
90+
}
91+
92+
async function openWindows() {
93+
const screenDetails = await window.getScreenDetails();
94+
const noOfScreens = screenDetails.screens.length;
95+
96+
if (noOfScreens === 1) {
97+
// Only one screen
98+
const screen1 = screenDetails.screens[0];
99+
// Windows will be half the width and half the height of the screen
100+
let windowWidth = Math.floor((screen1.availWidth - 2 * WINDOW_CHROME_X) / 2);
101+
let windowHeight = Math.floor((screen1.availHeight - 2 * WINDOW_CHROME_Y) / 2);
102+
103+
openWindow(screen1.availLeft,
104+
screen1.availTop,
105+
windowWidth,
106+
windowHeight,
107+
sites[0].url);
108+
openWindow(windowWidth + screen1.availLeft + WINDOW_CHROME_X,
109+
screen1.availTop,
110+
windowWidth,
111+
windowHeight,
112+
sites[1].url);
113+
openWindow(screen1.availLeft,
114+
windowHeight + screen1.availHeight + WINDOW_CHROME_Y,
115+
windowWidth,
116+
windowHeight,
117+
sites[2].url);
118+
openWindow(windowWidth + screen1.availLeft + WINDOW_CHROME_X,
119+
windowHeight + screen1.availHeight + WINDOW_CHROME_Y,
120+
windowWidth,
121+
windowHeight,
122+
sites[3].url);
123+
124+
} else {
125+
// Two screens or more
126+
const screen1 = screenDetails.screens[0];
127+
const screen2 = screenDetails.screens[1];
128+
// Windows will be a third the width and the full height of the screen
129+
let windowWidth = Math.floor((screen1.availWidth - 3 * WINDOW_CHROME_X) / 3);
130+
let windowHeight = Math.floor(screen1.availHeight - WINDOW_CHROME_Y);
131+
132+
// Open the reference windows in thirds across the entire height of the primary screen
133+
openWindow(screen1.availLeft,
134+
screen1.availTop,
135+
windowWidth,
136+
windowHeight,
137+
sites[1].url);
138+
openWindow(windowWidth + screen1.availLeft + WINDOW_CHROME_X,
139+
screen1.availTop,
140+
windowWidth,
141+
windowHeight,
142+
sites[2].url);
143+
openWindow((windowWidth * 2) + screen1.availLeft + (WINDOW_CHROME_X * 2),
144+
screen1.availTop,
145+
windowWidth,
146+
windowHeight,
147+
sites[2].url);
148+
149+
// Open the code editor the full size of the secondary screen
150+
openWindow(screen2.availLeft,
151+
screen2.availTop,
152+
screen2.availWidth,
153+
screen2.availHeight,
154+
sites[0].url);
155+
156+
}
157+
158+
// Check whether one of our popup windows has been closed
159+
// If so, close them all
160+
161+
closeMonitor = setInterval(checkWindowClose, 250);
162+
163+
function checkWindowClose() {
164+
windowRefs.forEach(windowRef => {
165+
if (windowRef.closed) {
166+
closeAllWindows();
167+
return;
168+
}
169+
});
170+
}
171+
172+
// Also close our popup windows if the main app window is closed
173+
174+
window.addEventListener("beforeunload", () => {
175+
closeAllWindows();
176+
});
177+
178+
screenDetails.addEventListener("screenschange", (event) => {
179+
// If the new number of screens is different to the old number of screens, report the difference
180+
if (screenDetails.screens.length !== noOfScreens) {
181+
console.log(
182+
`The screen count changed from ${noOfScreens} to ${screenDetails.screens.length}`,
183+
);
184+
}
185+
186+
// If the windows are open, close them and then open them again
187+
// So that they fit with the new screen configuration
188+
if (windowRefs.length > 0) {
189+
closeAllWindows();
190+
openWindows();
191+
}
192+
});
193+
}

0 commit comments

Comments
 (0)