Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Do not specify supported browsers and their versions in code comments or prose,

- The "fullscreen-api" directory is for examples and demos of the [Fullscreen API](https://wiki.developer.mozilla.org/docs/Web/API/Fullscreen_API). Run the [example live](https://mdn.github.io/dom-examples/fullscreen-api/).

- The "geolocation-element" directory is for examples and demos of the [`<geolocation>` element](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/geolocation). Go to the [`<geolocation>` element demo index](https://mdn.github.io/dom-examples/geolocation-element/) to see what's available.

- The "history-api" directory contains an example that demonstrates the [History API](https://developer.mozilla.org/docs/Web/API/History_API). [View the demo live](https://mdn.github.io/dom-examples/history-api/).

- The "indexeddb-api" directory contains a demo for the [IndexedDB API](https://mdn.github.io/dom-examples/indexeddb-api/index.html).
Expand Down
9 changes: 9 additions & 0 deletions geolocation-element/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MDN `<geolocation>` element examples

This set of examples demonstrates usage of the [`<geolocation>` element](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/geolocation) (also see the [specification](https://wicg.github.io/PEPC/permission-elements.html#geolocation-element)).

- [Basic `<geolocation>` example](basic-example/): Basic usage of the element to return geo data, with Geolocation API fallback.
- [Basic `<geolocation>` watch example](basic-watch-example/): Basic usage of the element to return geo data, with Geolocation API fallback, which continuously returns data each time the user's position changes.
- [Embedded map example](embedded-map/): Uses `<geolocation>` to return geo data, which is then used to plot the user's location on a map generated using [Leaflet JS](https://leafletjs.com/).
- [Exploring invalid reasons](exploring-invalid-reasons/): Provides a control to apply different styles to a `<geolocation>` element that make it invalid, and reports the `invalidReason` for each one.
- [Initial permission status example](initial-permission-status/): Shows how to use the `initialPermissionStatus` property to provide appropriate instructions to the user based on the `geolocation` permission on page load.
15 changes: 15 additions & 0 deletions geolocation-element/basic-example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Geolocation basic example</title>
<script defer src="index.js"></script>
</head>
<body>
<h1>Geolocation element basic example</h1>
<geolocation>
<button id="fallback">Use location</button>
</geolocation>
<p id="output"></p>
</body>
</html>
24 changes: 24 additions & 0 deletions geolocation-element/basic-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const outputElem = document.querySelector("#output");

if (typeof HTMLGeolocationElement === "function") {
const geo = document.querySelector("geolocation");
geo.addEventListener("location", () => {
if (geo.position) {
outputElem.textContent += `(${geo.position.coords.latitude},${geo.position.coords.longitude}), `;
} else if (geo.error) {
outputElem.textContent += `${geo.error.message}, `;
}
});
} else {
const fallback = document.querySelector("#fallback");
fallback.addEventListener("click", () => {
navigator.geolocation.getCurrentPosition(
(position) => {
outputElem.textContent += `(${position.coords.latitude}, ${position.coords.longitude}), `;
},
(error) => {
outputElem.textContent += `${error.message}, `;
}
);
});
}
15 changes: 15 additions & 0 deletions geolocation-element/basic-watch-example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Geolocation element basic watch example</title>
<script defer src="index.js"></script>
</head>
<body>
<h1>Geolocation element basic watch example</h1>
<geolocation watch>
<button id="fallback">Use location</button>
</geolocation>
<p id="output"></p>
</body>
</html>
24 changes: 24 additions & 0 deletions geolocation-element/basic-watch-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const outputElem = document.querySelector("#output");

if (typeof HTMLGeolocationElement === "function") {
const geo = document.querySelector("geolocation");
geo.addEventListener("location", () => {
if (geo.position) {
outputElem.textContent += `(${geo.position.coords.latitude},${geo.position.coords.longitude}), `;
} else if (geo.error) {
outputElem.textContent += `${geo.error.message}, `;
}
});
} else {
const fallback = document.querySelector("#fallback");
fallback.addEventListener("click", () => {
navigator.geolocation.watchPosition(
(position) => {
outputElem.textContent += `(${position.coords.latitude}, ${position.coords.longitude}), `;
},
(error) => {
outputElem.textContent += `${error.message}, `;
}
);
});
}
27 changes: 27 additions & 0 deletions geolocation-element/embedded-map/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Geolocation element embedded map</title>
<link href="style.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin="" />
<script
src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<script defer src="index.js"></script>
</head>
<body>
<h1>Geolocation element test</h1>
<geolocation autolocate>
<button id="fallback">Use location</button>
</geolocation>
<p id="status">Status:</p>
<hr />
<div id="map"></div>
</body>
</html>
69 changes: 69 additions & 0 deletions geolocation-element/embedded-map/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const statusElem = document.querySelector("#status");

if (typeof HTMLGeolocationElement === "function") {
const geo = document.querySelector("geolocation");

// Test attributes:
console.log(`isValid: ${geo.isValid}`);
console.log(`invalidReason: ${geo.invalidReason}`);
console.log(`autolocate: ${geo.autolocate}`);
console.log(`watch: ${geo.watch}`);
console.log(`initialPermissionStatus: ${geo.initialPermissionStatus}`);
console.log(`permissionStatus: ${geo.permissionStatus}`);

geo.addEventListener("location", () => {
if (geo.position) {
console.log(
`${geo.position.coords.latitude},${geo.position.coords.longitude}`
);
drawMap(geo.position.coords.latitude, geo.position.coords.longitude, geo);
} else if (geo.error) {
console.log(geo.error.message);
}
});

geo.addEventListener("promptdismiss", notifyUserRetrySelection);
geo.addEventListener("promptaction", notifyUserGrantPermission);

function notifyUserRetrySelection() {
statusElem.textContent =
'Please press the "Use location" button again and allow location for this site.';
}

function notifyUserGrantPermission() {
if (
geo.permissionStatus === "denied" ||
geo.permissionStatus === "prompt"
) {
statusElem.textContent =
'Please press the "Use location" button again and allow location for this site.';
}
}
} else {
const fallback = document.querySelector("#fallback");

// Fallback code
fallback.addEventListener("click", () => {
navigator.geolocation.getCurrentPosition(
(position) => {
drawMap(position.coords.latitude, position.coords.longitude, fallback);
},
(error) => {
statusElem.textContent += `${error.message}, `;
}
);
});
}

function drawMap(lat, long, btn) {
const map = L.map("map").setView([lat, long], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
const marker = L.marker([lat, long]).addTo(map);

statusElem.textContent = "Map drawn successfully.";
btn.style.display = "none";
}
12 changes: 12 additions & 0 deletions geolocation-element/embedded-map/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
* {
box-sizing: border-box;
}

#map {
width: 480px;
height: 320px;
}

geolocation {
font-size: small;
}
27 changes: 27 additions & 0 deletions geolocation-element/exploring-invalid-reasons/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Geolocation element exploring invalid reasons</title>
<script defer src="index.js"></script>
<link href="style.css" rel="stylesheet" />
</head>
<body>
<h1>Geolocation element exploring invalid reasons</h1>
<geolocation></geolocation>

<div id="cover">Cover element</div>
<p id="reason"></p>
<form>
<label for="invalidate"
>Choose a way to invalidate the &lt;geolocation&gt; element:</label
>
<select id="invalidate">
<option value="">None</option>
<option value="move-behind">Move behind element</option>
<option value="move-out">Move outside viewport</option>
<option value="bad-contrast">Bad contrast</option>
</select>
</form>
</body>
</html>
21 changes: 21 additions & 0 deletions geolocation-element/exploring-invalid-reasons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const geo = document.querySelector("geolocation");
const coverElem = document.querySelector("#cover");
const reasonElem = document.querySelector("#reason");
const selectElem = document.querySelector("select");

selectElem.addEventListener("input", () => {
geo.className = selectElem.value;
setTimeout(() => {
geo.className = "";
}, 4000);
});

reasonElem.textContent = `Invalid reason: ${geo.invalidReason}`;

geo.addEventListener("validationstatuschange", () => {
if (geo.isValid) {
reasonElem.textContent = `<geolocation> is valid`;
} else {
reasonElem.textContent = `Invalid reason: ${geo.invalidReason}`;
}
});
43 changes: 43 additions & 0 deletions geolocation-element/exploring-invalid-reasons/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
* {
box-sizing: border-box;
}

html {
font-family: sans-serif;
}

body {
margin-left: 50px;
}

geolocation {
font-size: small;
position: relative;
z-index: 1;
}

#cover {
position: absolute;
width: 200px;
height: 50px;
top: 72px;
left: 250px;
color: white;
background-color: darkblue;
padding: 10px;

z-index: 2;
}

.move-behind {
left: 150px;
}

.move-out {
right: 250px;
}

.bad-contrast {
background-color: red;
color: orange;
}
14 changes: 14 additions & 0 deletions geolocation-element/initial-permission-status/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Geolocation element initial permission status example</title>
<script defer src="index.js"></script>
</head>
<body>
<h1>Geolocation element initial permission status example</h1>
<geolocation></geolocation>
<p id="status"></p>
<p id="output"></p>
</body>
</html>
23 changes: 23 additions & 0 deletions geolocation-element/initial-permission-status/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const statusElem = document.querySelector("#status");
const outputElem = document.querySelector("#output");
const geo = document.querySelector("geolocation");

if (geo.initialPermissionStatus === "prompt") {
statusElem.textContent =
"Please press the button to allow access to your location data and start requesting it.";
} else if (geo.initialPermissionStatus === "denied") {
statusElem.textContent =
"Permission previously denied. Please press the button to allow access to your location data and start requesting it.";
} else if (geo.initialPermissionStatus === "granted") {
statusElem.textContent =
"Permission previously granted. Please press the button to start requesting location data.";
}

geo.addEventListener("location", () => {
statusElem.textContent = "Data requested";
if (geo.position) {
outputElem.textContent += `(${geo.position.coords.latitude},${geo.position.coords.longitude}), `;
} else if (geo.error) {
outputElem.textContent += `${geo.error.message}, `;
}
});