summaryrefslogtreecommitdiffstats
path: root/browser/fxr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /browser/fxr
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/fxr')
-rw-r--r--browser/fxr/content/assets/icon-backward.svg4
-rw-r--r--browser/fxr/content/assets/icon-forward.svg4
-rw-r--r--browser/fxr/content/assets/icon-home.svg4
-rw-r--r--browser/fxr/content/assets/icon-logo-settings-preview.pngbin0 -> 5515 bytes
-rw-r--r--browser/fxr/content/assets/icon-refresh.svg4
-rw-r--r--browser/fxr/content/assets/icon-reportissue.svg4
-rw-r--r--browser/fxr/content/assets/icon-secure.svg4
-rw-r--r--browser/fxr/content/assets/icon-settings.svg4
-rw-r--r--browser/fxr/content/assets/icon-stop-reload.svg4
-rw-r--r--browser/fxr/content/assets/icon-toggle-off.pngbin0 -> 9592 bytes
-rw-r--r--browser/fxr/content/assets/icon-toggle-on.pngbin0 -> 9721 bytes
-rw-r--r--browser/fxr/content/common.css44
-rw-r--r--browser/fxr/content/common.js48
-rw-r--r--browser/fxr/content/fxr-fullScreen.js64
-rw-r--r--browser/fxr/content/fxrui.css146
-rw-r--r--browser/fxr/content/fxrui.html54
-rw-r--r--browser/fxr/content/fxrui.js288
-rw-r--r--browser/fxr/content/fxrui_blue.css72
-rw-r--r--browser/fxr/content/permissions.js146
-rw-r--r--browser/fxr/content/prefs.css185
-rw-r--r--browser/fxr/content/prefs.html80
-rw-r--r--browser/fxr/content/prefs.js118
-rw-r--r--browser/fxr/jar.mn31
-rw-r--r--browser/fxr/moz.build7
24 files changed, 1315 insertions, 0 deletions
diff --git a/browser/fxr/content/assets/icon-backward.svg b/browser/fxr/content/assets/icon-backward.svg
new file mode 100644
index 0000000000..a824b50cad
--- /dev/null
+++ b/browser/fxr/content/assets/icon-backward.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><path d="M87.53,174a8.23,8.23,0,0,1-5.61-2.19L11.3,106.63a8.28,8.28,0,0,1,0-12.18L81.92,29.31A8.28,8.28,0,0,1,93.15,41.48l-64,59.06,64,59.06A8.28,8.28,0,0,1,87.53,174Z"/><path d="M182.39,108.82H16.91a8.28,8.28,0,0,1,0-16.56H182.39a8.28,8.28,0,1,1,0,16.56Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-forward.svg b/browser/fxr/content/assets/icon-forward.svg
new file mode 100644
index 0000000000..0c7bc478e1
--- /dev/null
+++ b/browser/fxr/content/assets/icon-forward.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><path d="M112,174.23a8.28,8.28,0,0,1-5.62-14.37l64-59.06-64-59.06a8.28,8.28,0,0,1,11.23-12.17l70.62,65.14a8.28,8.28,0,0,1,0,12.18L117.65,172A8.29,8.29,0,0,1,112,174.23Z"/><path d="M182.65,109.08H17.18a8.28,8.28,0,1,1,0-16.56H182.65a8.28,8.28,0,1,1,0,16.56Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-home.svg b/browser/fxr/content/assets/icon-home.svg
new file mode 100644
index 0000000000..5643dffad0
--- /dev/null
+++ b/browser/fxr/content/assets/icon-home.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><path d="M161.53,192.17H125a8.28,8.28,0,0,1-8.28-8.28v-49H83.63v49a8.28,8.28,0,0,1-8.28,8.28H38.8a8.28,8.28,0,0,1-8.28-8.28V120H18.15a8.29,8.29,0,0,1-6.28-13.69l82-95.21a8.28,8.28,0,0,1,12.55,0l82,95.21A8.29,8.29,0,0,1,182.18,120H169.81v63.94A8.28,8.28,0,0,1,161.53,192.17Zm-28.27-16.56h20V111.67a8.28,8.28,0,0,1,8.28-8.28h2.59l-64-74.25L36.21,103.39H38.8a8.28,8.28,0,0,1,8.28,8.28v63.94h20v-49a8.27,8.27,0,0,1,8.28-8.28H125a8.27,8.27,0,0,1,8.28,8.28Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-logo-settings-preview.png b/browser/fxr/content/assets/icon-logo-settings-preview.png
new file mode 100644
index 0000000000..0e516aaa7b
--- /dev/null
+++ b/browser/fxr/content/assets/icon-logo-settings-preview.png
Binary files differ
diff --git a/browser/fxr/content/assets/icon-refresh.svg b/browser/fxr/content/assets/icon-refresh.svg
new file mode 100644
index 0000000000..afcd3baab2
--- /dev/null
+++ b/browser/fxr/content/assets/icon-refresh.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><path d="M182.14,25.22a8.43,8.43,0,0,0-9.07-8.38,8.72,8.72,0,0,0-8.38,9.06l1.67,43A78.45,78.45,0,1,0,93.91,177.18a78,78,0,0,0,62.83-31.39,8.73,8.73,0,1,0-14-10.5,61.07,61.07,0,1,1,9.47-54.82c.1.3.32.52.44.8H110.36a8.73,8.73,0,0,0,0,17.46h64.31a8.09,8.09,0,0,0,1.09-.22c.05,0,.09,0,.14,0h.35a8.72,8.72,0,0,0,8.38-9.06Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-reportissue.svg b/browser/fxr/content/assets/icon-reportissue.svg
new file mode 100644
index 0000000000..4c563c848c
--- /dev/null
+++ b/browser/fxr/content/assets/icon-reportissue.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 20" fill="context-fill"><path d="M11.62,9.51a1.13,1.13,0,1,1-2.25,0V5a1.13,1.13,0,1,1,2.25,0ZM10.5,15.14a1.13,1.13,0,1,1,0-2.25,1.13,1.13,0,0,1,0,2.25ZM10.5.52C4.91.52.38,4.62.38,9.66A8.52,8.52,0,0,0,2,14.6a1.91,1.91,0,0,1,.17.24,1.34,1.34,0,0,1,.16.6c0,.08-.95,3.43-.95,3.43a.5.5,0,0,0,.4.59.32.32,0,0,0,.13,0,1.38,1.38,0,0,0,.2,0l.08,0,2.67-1.3.53-.23A1.63,1.63,0,0,1,6,17.77a1.61,1.61,0,0,1,.54.09,0,0,0,0,1,0,0l.08,0a11.15,11.15,0,0,0,4,.61c5.59,0,10.07-3.8,10.07-8.85S16.09.52,10.5.52Z"/></svg> \ No newline at end of file
diff --git a/browser/fxr/content/assets/icon-secure.svg b/browser/fxr/content/assets/icon-secure.svg
new file mode 100644
index 0000000000..d0231acca3
--- /dev/null
+++ b/browser/fxr/content/assets/icon-secure.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><rect x="44.73" y="90.19" width="110.54" height="76.6" rx="8.91"/><path d="M102.1,52.28A16.14,16.14,0,0,1,118,68.57v32.3a16.14,16.14,0,0,1-15.93,16.29H97.9A16.13,16.13,0,0,1,82,100.87V68.57A16.13,16.13,0,0,1,97.9,52.28h4.2m0-19.07H97.9c-19,0-34.57,15.91-34.57,35.36v32.3c0,19.45,15.55,35.36,34.57,35.36h4.2c19,0,34.58-15.91,34.58-35.36V68.57c0-19.45-15.56-35.36-34.58-35.36Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-settings.svg b/browser/fxr/content/assets/icon-settings.svg
new file mode 100644
index 0000000000..f719544a06
--- /dev/null
+++ b/browser/fxr/content/assets/icon-settings.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 19" fill="context-fill"><path d="M17.57,9.5l.95-1.24a1.82,1.82,0,0,0,.25-1.81L18.21,5.1A1.85,1.85,0,0,0,16.76,4l-1.55-.2L15,2.24A1.85,1.85,0,0,0,13.9.79L12.55.23a1.86,1.86,0,0,0-.7-.14,1.77,1.77,0,0,0-1.11.39l-1.24,1L8.26.48A1.77,1.77,0,0,0,7.15.09a1.86,1.86,0,0,0-.7.14L5.1.79A1.85,1.85,0,0,0,4,2.24l-.2,1.55L2.24,4A1.85,1.85,0,0,0,.79,5.1L.23,6.45A1.84,1.84,0,0,0,.47,8.26l1,1.24-1,1.24a1.84,1.84,0,0,0-.24,1.81L.79,13.9A1.85,1.85,0,0,0,2.24,15l1.55.2L4,16.76A1.85,1.85,0,0,0,5.1,18.21l1.35.56a1.86,1.86,0,0,0,.7.14,1.82,1.82,0,0,0,1.11-.38l1.24-1,1.24.95a1.77,1.77,0,0,0,1.11.39,1.86,1.86,0,0,0,.7-.14l1.35-.56A1.85,1.85,0,0,0,15,16.76l.2-1.55,1.55-.2a1.85,1.85,0,0,0,1.45-1.11l.56-1.35a1.82,1.82,0,0,0-.25-1.81Zm-.49,2.35-.56,1.35-2.22.28-.82.82-.28,2.22-1.35.56-1.77-1.37H8.92L7.15,17.08,5.8,16.52,5.52,14.3l-.82-.82L2.48,13.2l-.56-1.35,1.37-1.77V8.92L1.92,7.15,2.48,5.8,4.7,5.52l.82-.82L5.8,2.48l1.35-.56L8.92,3.29h1.16l1.77-1.37,1.35.56.28,2.22.82.82,2.22.28.56,1.35L15.71,8.92v1.16Z"/><path d="M9.5,5.2a4.3,4.3,0,1,0,4.3,4.3A4.31,4.31,0,0,0,9.5,5.2ZM9.5,12A2.48,2.48,0,1,1,12,9.5,2.48,2.48,0,0,1,9.5,12Z"/></svg> \ No newline at end of file
diff --git a/browser/fxr/content/assets/icon-stop-reload.svg b/browser/fxr/content/assets/icon-stop-reload.svg
new file mode 100644
index 0000000000..662810ab3d
--- /dev/null
+++ b/browser/fxr/content/assets/icon-stop-reload.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="context-fill"><path d="M163.4,170.84a8,8,0,0,1-5.66-2.33L30.93,42.92A8,8,0,0,1,42.26,31.49L169.07,157.08a8,8,0,0,1-5.67,13.76Z"/><path d="M36.86,171.11a8,8,0,0,1-5.68-13.74L157.45,31.25a8,8,0,1,1,11.37,11.38L42.55,168.76A8.06,8.06,0,0,1,36.86,171.11Z"/></svg>
diff --git a/browser/fxr/content/assets/icon-toggle-off.png b/browser/fxr/content/assets/icon-toggle-off.png
new file mode 100644
index 0000000000..398a42c9bf
--- /dev/null
+++ b/browser/fxr/content/assets/icon-toggle-off.png
Binary files differ
diff --git a/browser/fxr/content/assets/icon-toggle-on.png b/browser/fxr/content/assets/icon-toggle-on.png
new file mode 100644
index 0000000000..f22f231628
--- /dev/null
+++ b/browser/fxr/content/assets/icon-toggle-on.png
Binary files differ
diff --git a/browser/fxr/content/common.css b/browser/fxr/content/common.css
new file mode 100644
index 0000000000..512be5aee7
--- /dev/null
+++ b/browser/fxr/content/common.css
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ * {
+ margin: 0;
+ padding: 0;
+ user-select: none;
+
+ font-family: 'Open Sans', sans-serif;
+}
+
+.modal_mask:not([hidden]) {
+ background-color: #00CC00;
+
+ height: 100%;
+ width: 100%;
+
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.modal_container:not([hidden]) {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ height: 100%;
+ width: 100%;
+
+ position: absolute;
+ top: 0;
+ left :0;
+}
+
+.modal_hide {
+ display: none;
+}
+
+.modal_content {
+ position: absolute;
+}
diff --git a/browser/fxr/content/common.js b/browser/fxr/content/common.js
new file mode 100644
index 0000000000..292c0a916a
--- /dev/null
+++ b/browser/fxr/content/common.js
@@ -0,0 +1,48 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Creates a modal container, if it doesn't exist, and adds the provided
+// content element to it
+function showModalContainer(content) {
+ var container = document.getElementById("eModalContainer");
+ if (container == null) {
+ container = document.createElement("div");
+ container.id = "eModalContainer";
+ container.classList.add("modal_container");
+
+ var mask = document.createElement("div");
+ mask.id = "eModalMask";
+ mask.classList.add("modal_mask");
+
+ document.body.appendChild(mask);
+ document.body.appendChild(container);
+ } else {
+ container.hidden = false;
+ document.getElementById("eModalMask").hidden = false;
+ }
+
+ container.appendChild(content);
+ if (content.classList.contains("modal_hide")) {
+ content.classList.replace("modal_hide", "modal_content");
+ } else {
+ content.classList.add("modal_content");
+ }
+}
+
+// Hides the modal container, and returns the contents back to the caller.
+// The caller can choose to use the return value to move the contents to
+// another part of the DOM, or ignore the return value so that the nodes
+// can be garbage collected.
+function clearModalContainer() {
+ var container = document.getElementById("eModalContainer");
+ container.hidden = true;
+ document.getElementById("eModalMask").hidden = true;
+
+ var content = container.firstElementChild;
+ container.removeChild(content);
+ content.classList.replace("modal_content", "modal_hide");
+
+ return content;
+}
diff --git a/browser/fxr/content/fxr-fullScreen.js b/browser/fxr/content/fxr-fullScreen.js
new file mode 100644
index 0000000000..dd7a933d89
--- /dev/null
+++ b/browser/fxr/content/fxr-fullScreen.js
@@ -0,0 +1,64 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This file is loaded into the browser window scope.
+/* eslint-env mozilla/browser-window */
+
+// fxr-fullScreen.js is a provisional, stripped-down clone of
+// browser\base\content\browser-fullScreenAndPointerLock.js
+// that is adapted for Firefox Reality on Desktop.
+// The bug to track its removal is
+// Bug 1587946 - Rationalize the fork of browser-fullScreenAndPointerLock.js
+
+var FullScreen = {
+ init() {
+ // Called when the Firefox window go into fullscreen.
+ addEventListener("fullscreen", this, true);
+
+ if (window.fullScreen) {
+ this.toggle();
+ }
+ },
+
+ toggle() {
+ var enterFS = window.fullScreen;
+ if (enterFS) {
+ document.documentElement.setAttribute("inFullscreen", true);
+ } else {
+ document.documentElement.removeAttribute("inFullscreen");
+ }
+ },
+
+ handleEvent(event) {
+ if (event.type === "fullscreen") {
+ this.toggle();
+ }
+ },
+
+ enterDomFullscreen(aBrowser, aActor) {
+ if (!document.fullscreenElement) {
+ return;
+ }
+
+ // If it is a remote browser, send a message to ask the content
+ // to enter fullscreen state. We don't need to do so if it is an
+ // in-process browser, since all related document should have
+ // entered fullscreen state at this point.
+ // This should be done before the active tab check below to ensure
+ // that the content document handles the pending request. Doing so
+ // before the check is fine since we also check the activeness of
+ // the requesting document in content-side handling code.
+ if (aBrowser.isRemoteBrowser) {
+ aActor.sendAsyncMessage("DOMFullscreen:Entered", {});
+ }
+
+ document.documentElement.setAttribute("inDOMFullscreen", true);
+ },
+
+ cleanupDomFullscreen(aActor) {
+ aActor.sendAsyncMessage("DOMFullscreen:CleanUp", {});
+ document.documentElement.removeAttribute("inDOMFullscreen");
+ },
+};
diff --git a/browser/fxr/content/fxrui.css b/browser/fxr/content/fxrui.css
new file mode 100644
index 0000000000..42eee7f5ab
--- /dev/null
+++ b/browser/fxr/content/fxrui.css
@@ -0,0 +1,146 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+html, body {
+ height: 100%;
+}
+
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+
+.navbar_container {
+ width: 100%;
+
+ margin-block: 15px;
+
+ display: flex;
+ flex-direction: row;
+}
+
+/* Sizing and positioning properties for all icons
+ Color is determined by enabled/disabled classes below
+ */
+.icon_container {
+ width: 44px;
+ height: 44px;
+ margin: 5px;
+
+ border-radius: 22px;
+ border-width: 2px;
+ border-style: solid;
+
+ background-size: 22px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: inherit;
+
+ -moz-context-properties: fill;
+
+ transition-property: transform;
+ transition-duration: 200ms;
+}
+
+.icon_container:hover {
+ transform: scale(1.25);
+}
+
+.icon_container:disabled {
+ transform: unset;
+}
+
+.icon_disabled_hide:disabled {
+ display:none;
+}
+.icon_backward {
+ background-image: url("assets/icon-backward.svg");
+ margin-inline-start: 10px;
+}
+.icon_forward {
+ background-image: url("assets/icon-forward.svg");
+}
+.icon_refresh {
+ background-image: url("assets/icon-refresh.svg");
+}
+.icon_stop {
+ background-image: url("assets/icon-stop-reload.svg");
+}
+.icon_home {
+ background-image: url("assets/icon-home.svg");
+}
+.icon_prefs {
+ background-image: url("assets/icon-settings.svg");
+ margin-inline-end: 10px;
+}
+
+.urlbar_container {
+ height: 40px;
+ flex-grow: 1;
+
+ padding: 0;
+ margin: 5px;
+
+ border-radius: 22px;
+ border: 2px solid transparent;
+
+ vertical-align: top;
+
+ display: flex;
+ flex-direction: row;
+}
+
+.urlbar_secure_icon {
+ -moz-context-properties: fill;
+
+ height: 32px;
+ padding: 2px;
+
+ visibility: hidden;
+
+ display: inline-block;
+}
+
+.urlbar_input {
+ background-color: transparent;
+
+ flex-grow: 1;
+
+ border: none;
+
+ font-size: 18px;
+ font-family: 'Open Sans', sans-serif;
+
+ mask-image: linear-gradient(to left, transparent, black 8ch);
+}
+
+.browser_container {
+ width: 100%;
+ flex-grow: 1;
+}
+
+.browser_instance {
+ width: 100%;
+ height: 100%;
+}
+
+/* Hide the navbar when in fullscreen so that <browser> can
+ * fill the entire viewport
+ */
+:root[inFullScreen] .navbar_container {
+ display:none;
+}
+
+.browser_settings {
+ width: 600px;
+ height: 400px;
+ border-radius: 20px;
+}
+
+.modal_mask:not([hidden]) {
+ background-color: var(--num13_alpha);
+}
diff --git a/browser/fxr/content/fxrui.html b/browser/fxr/content/fxrui.html
new file mode 100644
index 0000000000..17273d8e77
--- /dev/null
+++ b/browser/fxr/content/fxrui.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--
+ This file contains the HTML UI for the 2D window of Firefox Reality on Desktop
+-->
+
+<!-- 1280x720 chosen for default 16:9 ratio -->
+<html width="1280" height="720">
+ <head>
+ <title>Firefox Reality</title>
+ <link rel="stylesheet" href="common.css" />
+ <link rel="stylesheet" href="fxrui.css" />
+ <link rel="stylesheet" href="fxrui_blue.css" />
+ <script src="common.js"></script>
+ <script src="permissions.js"></script>
+ <script src="fxrui.js"></script>
+ </head>
+
+ <body>
+ <div id="eBrowserContainer" class="browser_container"></div>
+
+ <div class="navbar_container">
+ <button id="eBack" class="icon_container icon_backward"></button>
+ <button id="eForward" class="icon_container icon_forward"></button>
+ <button
+ id="eRefresh"
+ class="icon_container icon_refresh icon_disabled_hide"
+ ></button>
+ <button
+ id="eStop"
+ class="icon_container icon_stop icon_disabled_hide"
+ disabled
+ ></button>
+ <button id="eHome" class="icon_container icon_home"></button>
+
+ <div
+ class="urlbar_container urlbar_container_normal"
+ id="eUrlBarContainer"
+ >
+ <img
+ class="urlbar_secure_icon"
+ id="eUrlSecure"
+ src="assets/icon-secure.svg"
+ alt="Secure"
+ />
+ <input class="urlbar_input" id="eUrlInput" type="text" value="" />
+ </div>
+ <button id="ePrefs" class="icon_container icon_prefs"></button>
+ </div>
+ </body>
+</html>
diff --git a/browser/fxr/content/fxrui.js b/browser/fxr/content/fxrui.js
new file mode 100644
index 0000000000..dd0f55767a
--- /dev/null
+++ b/browser/fxr/content/fxrui.js
@@ -0,0 +1,288 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* import-globals-from common.js */
+/* import-globals-from permissions.js */
+
+// Configuration vars
+let homeURL = "https://webxr.today/";
+// Bug 1586294 - Localize the privacy policy URL (Services.urlFormatter?)
+let privacyPolicyURL = "https://www.mozilla.org/en-US/privacy/firefox/";
+let reportIssueURL = "https://mzl.la/fxr";
+let licenseURL =
+ "https://mixedreality.mozilla.org/FirefoxRealityPC/license.html";
+
+// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/browser
+let browser = null;
+// Keep track of the current Permissions request to only allow one outstanding
+// request/prompt at a time.
+let currentPermissionRequest = null;
+// And, keep a queue of pending Permissions requests to resolve when the
+// current request finishes
+let pendingPermissionRequests = [];
+// The following variable map to UI elements whose behavior changes depending
+// on some state from the browser control
+let urlInput = null;
+let secureIcon = null;
+let backButton = null;
+let forwardButton = null;
+let refreshButton = null;
+let stopButton = null;
+
+const { PrivateBrowsingUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/PrivateBrowsingUtils.sys.mjs"
+);
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+
+// Note: FxR UI uses a fork of browser-fullScreenAndPointerLock.js which removes
+// the dependencies on browser.js.
+// Bug 1587946 - Rationalize the fork of browser-fullScreenAndPointerLock.js
+XPCOMUtils.defineLazyScriptGetter(
+ this,
+ "FullScreen",
+ "chrome://fxr/content/fxr-fullScreen.js"
+);
+ChromeUtils.defineLazyGetter(this, "gSystemPrincipal", () =>
+ Services.scriptSecurityManager.getSystemPrincipal()
+);
+
+window.addEventListener(
+ "DOMContentLoaded",
+ () => {
+ urlInput = document.getElementById("eUrlInput");
+ secureIcon = document.getElementById("eUrlSecure");
+ backButton = document.getElementById("eBack");
+ forwardButton = document.getElementById("eForward");
+ refreshButton = document.getElementById("eRefresh");
+ stopButton = document.getElementById("eStop");
+
+ setupBrowser();
+ setupNavButtons();
+ setupUrlBar();
+ },
+ { once: true }
+);
+
+// Create XUL browser object
+function setupBrowser() {
+ // Note: createXULElement is undefined when this page is not loaded
+ // via chrome protocol
+ if (document.createXULElement) {
+ browser = document.createXULElement("browser");
+ browser.setAttribute("type", "content");
+ browser.setAttribute("remote", "true");
+ browser.classList.add("browser_instance");
+ document.getElementById("eBrowserContainer").appendChild(browser);
+
+ browser.loadUrlWithSystemPrincipal = function (url) {
+ this.loadURI(url, { triggeringPrincipal: gSystemPrincipal });
+ };
+
+ // Expose this function for Permissions to be used on this browser element
+ // in other parts of the frontend
+ browser.fxrPermissionPrompt = permissionPrompt;
+
+ urlInput.value = homeURL;
+ browser.loadUrlWithSystemPrincipal(homeURL);
+
+ browser.addProgressListener(
+ {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIWebProgressListener",
+ "nsISupportsWeakReference",
+ ]),
+ onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
+ // When URL changes, update the URL in the URL bar and update
+ // whether the back/forward buttons are enabled.
+ urlInput.value = browser.currentURI.spec;
+
+ backButton.disabled = !browser.canGoBack;
+ forwardButton.disabled = !browser.canGoForward;
+ },
+ onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
+ if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
+ // Network requests are complete. Disable (hide) the stop button
+ // and enable (show) the refresh button
+ refreshButton.disabled = false;
+ stopButton.disabled = true;
+ } else {
+ // Network requests are outstanding. Disable (hide) the refresh
+ // button and enable (show) the stop button
+ refreshButton.disabled = true;
+ stopButton.disabled = false;
+ }
+ },
+ onSecurityChange(aWebProgress, aRequest, aState) {
+ // Update the Secure Icon when the security status of the
+ // content changes
+ if (aState & Ci.nsIWebProgressListener.STATE_IS_SECURE) {
+ secureIcon.style.visibility = "visible";
+ } else {
+ secureIcon.style.visibility = "hidden";
+ }
+ },
+ },
+ Ci.nsIWebProgress.NOTIFY_LOCATION |
+ Ci.nsIWebProgress.NOTIFY_SECURITY |
+ Ci.nsIWebProgress.NOTIFY_STATE_REQUEST
+ );
+
+ FullScreen.init();
+
+ // Send this notification to start and allow background scripts for
+ // WebExtensions, since this FxR UI doesn't participate in typical
+ // startup activities
+ Services.obs.notifyObservers(window, "extensions-late-startup");
+ }
+}
+
+function setupNavButtons() {
+ let aryNavButtons = [
+ "eBack",
+ "eForward",
+ "eRefresh",
+ "eStop",
+ "eHome",
+ "ePrefs",
+ ];
+
+ function navButtonHandler(e) {
+ if (!this.disabled) {
+ switch (this.id) {
+ case "eBack":
+ browser.goBack();
+ break;
+
+ case "eForward":
+ browser.goForward();
+ break;
+
+ case "eRefresh":
+ browser.reload();
+ break;
+
+ case "eStop":
+ browser.stop();
+ break;
+
+ case "eHome":
+ browser.loadUrlWithSystemPrincipal(homeURL);
+ break;
+
+ case "ePrefs":
+ openSettings();
+ break;
+ }
+ }
+ }
+
+ for (let btnName of aryNavButtons) {
+ let elem = document.getElementById(btnName);
+ elem.addEventListener("click", navButtonHandler);
+ }
+}
+
+function setupUrlBar() {
+ // Navigate to new value when the user presses "Enter"
+ urlInput.addEventListener("keypress", async function (e) {
+ if (e.key == "Enter") {
+ // Use the URL Fixup Service in case the user wants to search instead
+ // of directly navigating to a location.
+ await Services.search.init();
+
+ let valueToFixUp = urlInput.value;
+ let flags =
+ Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS |
+ Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
+ if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+ flags |= Services.uriFixup.FIXUP_FLAG_PRIVATE_CONTEXT;
+ }
+ let { preferredURI } = Services.uriFixup.getFixupURIInfo(
+ valueToFixUp,
+ flags
+ );
+
+ browser.loadUrlWithSystemPrincipal(preferredURI.spec);
+ browser.focus();
+ }
+ });
+
+ // Upon focus, highlight the whole URL
+ urlInput.addEventListener("focus", function () {
+ urlInput.select();
+ });
+}
+
+//
+// Code to manage Settings UI
+//
+
+function openSettings() {
+ let browserSettingsUI = document.createXULElement("browser");
+ browserSettingsUI.setAttribute("type", "chrome");
+ browserSettingsUI.classList.add("browser_settings");
+
+ showModalContainer(browserSettingsUI);
+
+ browserSettingsUI.loadURI("chrome://fxr/content/prefs.html", {
+ triggeringPrincipal: gSystemPrincipal,
+ });
+}
+
+function closeSettings() {
+ clearModalContainer();
+}
+
+function showPrivacyPolicy() {
+ closeSettings();
+ browser.loadUrlWithSystemPrincipal(privacyPolicyURL);
+}
+
+function showLicenseInfo() {
+ closeSettings();
+ browser.loadUrlWithSystemPrincipal(licenseURL);
+}
+
+function showReportIssue() {
+ closeSettings();
+ browser.loadUrlWithSystemPrincipal(reportIssueURL);
+}
+
+//
+// Code to manage Permissions UI
+//
+
+function permissionPrompt(aRequest) {
+ let newPrompt;
+ if (aRequest instanceof Ci.nsIContentPermissionRequest) {
+ newPrompt = new FxrContentPrompt(aRequest, this, finishPrompt);
+ } else {
+ newPrompt = new FxrWebRTCPrompt(aRequest, this, finishPrompt);
+ }
+
+ if (currentPermissionRequest) {
+ // There is already an outstanding request running. Cache this new request
+ // to be prompted later
+ pendingPermissionRequests.push(newPrompt);
+ } else {
+ currentPermissionRequest = newPrompt;
+ currentPermissionRequest.showPrompt();
+ }
+}
+
+function finishPrompt() {
+ if (pendingPermissionRequests.length) {
+ // Prompt the next request
+ currentPermissionRequest = pendingPermissionRequests.shift();
+ currentPermissionRequest.showPrompt();
+ } else {
+ currentPermissionRequest = null;
+ }
+}
diff --git a/browser/fxr/content/fxrui_blue.css b/browser/fxr/content/fxrui_blue.css
new file mode 100644
index 0000000000..c65e7e7919
--- /dev/null
+++ b/browser/fxr/content/fxrui_blue.css
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ /* These not-very-descriptive variable names for colors come
+ * from the design documents and are maintained to make it
+ * easier to map between the stylesheet and the design doc.
+ */
+:root {
+ --num01: #1D2E3B;
+ --num02: #4C495C;
+ --num03: #7D8896;
+ --num04: #B3BECC;
+ --num06: #FFFFFF;
+ --num07: #00B3E3;
+ --num08: #56D9F6;
+ --num09: #0968B6;
+ --num13: #2C3A50;
+ --num13_alpha: #2C3A5080;
+ --num14: #596677;
+ --num14_alpha: #59667780;
+ --num16: #E7EAF0;
+ --num19: #FFFFFF;
+
+ --secure: #f7ce4d;
+}
+
+body {
+ background-color: var(--num01);
+ color: var(--num06);
+}
+
+.icon_container {
+ background-color: var(--num02);
+ border-color: transparent;
+ fill: var(--num06);
+}
+.icon_container:hover {
+ background-color: var(--num01);
+ fill: var(--num06);
+}
+.icon_container:active {
+ background-color: var(--num04);
+ fill: var(--num06);
+}
+.icon_container:disabled {
+ background-color: var(--num16);
+ fill: var(--num14);
+}
+
+.urlbar_container {
+ border-color: transparent;
+ background-color: var(--num02);
+}
+.urlbar_container:hover {
+ border-color:var(--num04);
+}
+.urlbar_container:focus-within {
+ border-color:var(--num08);
+ background-color: var(--num01);
+}
+
+.urlbar_secure_icon {
+ fill: var(--secure);
+}
+
+.urlbar_input {
+ color: var(--num06);
+}
+.urlbar_input::selection {
+ background-color: var(--num08);
+}
diff --git a/browser/fxr/content/permissions.js b/browser/fxr/content/permissions.js
new file mode 100644
index 0000000000..a8f7ece131
--- /dev/null
+++ b/browser/fxr/content/permissions.js
@@ -0,0 +1,146 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* import-globals-from fxrui.js */
+
+/**
+ * Code to manage Permissions UI
+ *
+ * FxR on Desktop only supports granting permission for
+ * - Location
+ * - Camera
+ * - Microphone
+ * Any other permissions are automatically denied.
+ *
+ */
+
+// Base class for managing permissions in FxR on PC
+class FxrPermissionPromptPrototype {
+ constructor(aRequest, aBrowser, aCallback) {
+ this.request = aRequest;
+ this.targetBrowser = aBrowser;
+ this.responseCallback = aCallback;
+ }
+
+ showPrompt() {
+ // For now, all permissions default to denied. Testing for allow must be
+ // done manually until UI is finished:
+ // Bug 1594840 - Add UI for Web Permissions in FxR for Desktop
+ this.defaultDeny();
+ }
+
+ defaultDeny() {
+ this.handleResponse(false);
+ }
+
+ handleResponse(allowed) {
+ if (allowed) {
+ this.allow();
+ } else {
+ this.deny();
+ }
+
+ this.responseCallback();
+ }
+}
+
+// WebRTC-specific class implementation
+class FxrWebRTCPrompt extends FxrPermissionPromptPrototype {
+ showPrompt() {
+ for (let typeName of this.request.requestTypes) {
+ if (typeName !== "Microphone" && typeName !== "Camera") {
+ // Only Microphone and Camera requests are allowed. Automatically deny
+ // any other request.
+ this.defaultDeny();
+ return;
+ }
+ }
+
+ super.showPrompt();
+ }
+
+ allow() {
+ let { audioDevices, videoDevices } = this.request;
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ this.request.origin
+ );
+
+ // For now, collect the first audio and video device by default. User
+ // selection will be enabled later:
+ // Bug 1594841 - Add UI to select device for WebRTC in FxR for Desktop
+ let allowedDevices = [];
+
+ if (audioDevices.length) {
+ allowedDevices.push(audioDevices[0].deviceIndex);
+ }
+
+ if (videoDevices.length) {
+ Services.perms.addFromPrincipal(
+ principal,
+ "MediaManagerVideo",
+ Services.perms.ALLOW_ACTION,
+ Services.perms.EXPIRE_SESSION
+ );
+ allowedDevices.push(videoDevices[0].deviceIndex);
+ }
+
+ // WebRTCChild doesn't currently care which actor
+ // this is sent to and just uses the windowID.
+ this.targetBrowser.sendMessageToActor(
+ "webrtc:Allow",
+ {
+ callID: this.request.callID,
+ windowID: this.request.windowID,
+ devices: allowedDevices,
+ },
+ "WebRTC"
+ );
+ }
+
+ deny() {
+ this.targetBrowser.sendMessageToActor(
+ "webrtc:Deny",
+ {
+ callID: this.request.callID,
+ windowID: this.request.windowID,
+ },
+ "WebRTC"
+ );
+ }
+}
+
+// Implementation for other, non-WebRTC web permission prompts
+class FxrContentPrompt extends FxrPermissionPromptPrototype {
+ showPrompt() {
+ // Only allow exactly one permission request here.
+ let types = this.request.types.QueryInterface(Ci.nsIArray);
+ if (types.length != 1) {
+ this.defaultDeny();
+ return;
+ }
+
+ // Only Location is supported from this type of request
+ let type = types.queryElementAt(0, Ci.nsIContentPermissionType).type;
+ if (type !== "geolocation") {
+ this.defaultDeny();
+ return;
+ }
+
+ // Override type so that it can be more easily interpreted by the code
+ // for the prompt.
+ type = "Location";
+ super.showPrompt();
+ }
+
+ allow() {
+ this.request.allow();
+ }
+
+ deny() {
+ this.request.cancel();
+ }
+}
diff --git a/browser/fxr/content/prefs.css b/browser/fxr/content/prefs.css
new file mode 100644
index 0000000000..dd7099df24
--- /dev/null
+++ b/browser/fxr/content/prefs.css
@@ -0,0 +1,185 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+body {
+ margin: 10px 50px;
+ background-color: var(--num06);
+ color: var(--num13);
+}
+
+.plain_button {
+ border: none;
+ background-color: transparent;
+}
+
+.settings_header{
+ display: flex;
+ flex-direction: row;
+}
+
+.icon_backward {
+ height: 30px;
+ width: 30px;
+
+ margin: 20px 70px 70px 20px;
+
+ background-image: url("assets/icon-backward.svg");
+ -moz-context-properties: fill;
+ fill: var(--num14);
+}
+.icon_backward:hover {
+ height: 40px;
+ width: 40px;
+ margin: 15px 65px 65px 15px;
+
+ fill: var(--num07);
+}
+.icon_backward:active {
+ height: 40px;
+ width: 40px;
+ margin: 15px 65px 65px 15px;
+
+ fill: var(--num09);
+}
+
+.about_container {
+ flex-grow: 1;
+ text-align: center;
+}
+
+.fxr_logo {
+ width: 72px;
+ height: 72px;
+}
+
+.version_text {
+ font-size: 10px;
+ color: var(--num14);
+}
+
+.button_report_issue {
+ height: 50px;
+ width: 110px;
+ margin: 20px 0px 70px 10px;
+
+ font-size: 10px;
+ text-align: start;
+
+ -moz-context-properties: fill;
+ fill: var(--num14);
+}
+.button_report_issue:hover {
+ fill: var(--num07);
+}
+.button_report_issue:active {
+ fill: var(--num09);
+}
+
+.button_report_issue_icon {
+ float:left;
+ height: 30px;
+ margin: 5px;
+}
+
+.button_report_text {
+ color: var(--num13);
+}
+
+.button_report_url {
+ color: var(--num14);
+}
+
+.settings_title {
+ font-size: 22px;
+ font-weight: bold;
+ color: var(--num13);
+ text-align: center;
+
+ flex-grow: 1;
+}
+
+.divider {
+ border-style: solid;
+ border-width: 1px;
+ border-color: var(--num04);
+ margin: 10px;
+}
+
+.setting_container {
+ display: flex;
+ flex-direction: row;
+
+ margin: 10px 5px;
+}
+
+.setting_name {
+ font-size: 14px;
+ color: var(--num13);
+
+ flex-grow: 1;
+}
+
+.setting_description {
+ font-size: 10px;
+ color: var(--num14);
+ margin: 0 10px;
+}
+
+.setting_control {
+ min-width: 120px;
+ margin: 5px 0px;
+}
+
+button.setting_control {
+ height: 30px;
+
+ font-size: 14px;
+ font-weight: bold;
+
+ border: 2px solid var(--num08);
+ border-radius: 5px;
+
+ background-color: var(--num06);
+}
+button.setting_control:hover {
+ background-color: var(--num07);
+ border-color: var(--num07);
+}
+button.setting_control:active {
+ background-color: var(--num09);
+ border-color: var(--num09);
+ color: var(--num19);
+}
+button.setting_control:disabled {
+ background-color: var(--num06);
+ border-color: var(--num08);
+ color: var(--num03);
+}
+
+.clear_confirmation {
+ padding: 20px;
+ background-color: var(--num19);
+ border-radius: 20px;
+}
+
+.setting_control_chk {
+ opacity: 0;
+}
+.setting_control_chk + label {
+ background-position: right;
+ background-size: contain;
+ background-repeat: no-repeat;
+
+ background-image: url("assets/icon-toggle-off.png");
+}
+.setting_control_chk:checked + label {
+ background-image: url("assets/icon-toggle-on.png");
+}
+.setting_control_chk:disabled + label {
+ filter: grayscale(1);
+}
+
+.modal_mask:not([hidden]) {
+ background-color: var(--num14_alpha);
+}
diff --git a/browser/fxr/content/prefs.html b/browser/fxr/content/prefs.html
new file mode 100644
index 0000000000..d536219901
--- /dev/null
+++ b/browser/fxr/content/prefs.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--
+ This file contains the Settings UI for Firefox Reality on Desktop
+-->
+
+<html width="800" height="400">
+ <head>
+ <title>Firefox Reality Settings</title>
+ <link rel="stylesheet" href="common.css" />
+ <link rel="stylesheet" href="fxrui_blue.css" />
+ <link rel="stylesheet" href="prefs.css" />
+ <script src="prefs.js"></script>
+ <script src="common.js"></script>
+ </head>
+
+ <body>
+ <div class="settings_header">
+ <button id="eCloseSettings" class="plain_button icon_backward"></button>
+ <div class="about_container">
+ <img class="fxr_logo" src="assets/icon-logo-settings-preview.png" />
+ <div class="version_text" id="eFxrVersion"></div>
+ <div class="version_text" id="eFxrDate"></div>
+ <div class="version_text" id="eFxVersion"></div>
+ </div>
+ <button id="eReportIssue" class="plain_button button_report_issue">
+ <img
+ class="button_report_issue_icon"
+ src="assets/icon-reportissue.svg"
+ />
+ <span class="button_report_text">Report an issue</span>
+ <br />
+ <span class="button_report_url">mzl.la/fxr</span>
+ </button>
+ </div>
+
+ <div class="settings_title">Settings</div>
+ <hr class="divider" />
+
+ <div class="setting_container">
+ <div class="setting_name">Mozilla's Privacy Policy Page</div>
+ <button id="ePrivacyPolicy" class="setting_control">Open</button>
+ </div>
+
+ <div class="setting_container">
+ <div class="setting_name">Firefox Reality Licensing Information</div>
+ <button id="eLicenseInfo" class="setting_control">Open</button>
+ </div>
+
+ <div class="setting_container">
+ <div class="setting_name">
+ Cookies, Site Data, and Cached Web Content
+ <div class="setting_description">
+ Clearing may sign you out of websites and will require websites to
+ reload images and data.
+ </div>
+ </div>
+ <button class="setting_control" id="eClearTry">Clear Data</button>
+ </div>
+ <div class="clear_confirmation modal_hide" id="eClearPrompt">
+ Are you sure you want to clear all data?
+ <div>
+ <button id="eClearCancel" class="setting_control">Cancel</button>
+ <button id="eClearConfirm" class="setting_control">Clear</button>
+ </div>
+ </div>
+
+ <div class="setting_container">
+ <div class="setting_name">
+ Allow Firefox to Anonymously Collect and Use Technical and Interaction
+ Data
+ </div>
+ <input id="eCrashConfig" type="checkbox" class="setting_control_chk" />
+ <label class="setting_control" for="eCrashConfig"></label>
+ </div>
+ </body>
+</html>
diff --git a/browser/fxr/content/prefs.js b/browser/fxr/content/prefs.js
new file mode 100644
index 0000000000..a5a8c954d9
--- /dev/null
+++ b/browser/fxr/content/prefs.js
@@ -0,0 +1,118 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* import-globals-from common.js */
+
+var { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
+
+window.addEventListener(
+ "DOMContentLoaded",
+ () => {
+ initAboutInfo();
+ initClearAllData();
+ initSubmitHealthReport();
+ initParentDependencies();
+ },
+ { once: true }
+);
+
+function initAboutInfo() {
+ // Bug 1586294 - Update FxR Desktop Settings to use Fluent
+ document.getElementById("eFxrVersion").textContent = "version 0.9";
+ document.getElementById("eFxrDate").textContent = "(2019-12-17)";
+ document.getElementById("eFxVersion").textContent =
+ "Firefox version " + Services.appinfo.version;
+}
+
+function initClearAllData() {
+ let eClearPrompt = document.getElementById("eClearPrompt");
+
+ let eClearTry = document.getElementById("eClearTry");
+ eClearTry.addEventListener("click", () => {
+ showModalContainer(eClearPrompt);
+ });
+
+ // Note: the calls to clearModalContainer below return eClearPrompt
+ // back to <body> to be reused later, because it is moved into anothe
+ // element in showModalContainer.
+
+ let eClearCancel = document.getElementById("eClearCancel");
+ eClearCancel.addEventListener("click", () => {
+ document.body.appendChild(clearModalContainer());
+ });
+
+ // When the confirm option is visible, do the work to actually clear the data
+ document.getElementById("eClearConfirm").addEventListener("click", () => {
+ Services.clearData.deleteData(
+ Ci.nsIClearDataService.CLEAR_ALL,
+ function (aFailedFlags) {
+ if (aFailedFlags == 0) {
+ eClearTry.textContent = "Data cleared";
+ eClearTry.disabled = true;
+ document.body.appendChild(clearModalContainer());
+ } else {
+ eClearTry.textContent = "Error";
+ }
+ }
+ );
+ });
+}
+
+// Based on https://searchfox.org/mozilla-central/source/browser/components/preferences/privacy.js
+function initSubmitHealthReport() {
+ let checkbox = document.getElementById("eCrashConfig");
+
+ // Telemetry is only sending data if MOZ_TELEMETRY_REPORTING is defined.
+ // We still want to display the preferences panel if that's not the case, but
+ // we want it to be disabled and unchecked.
+ if (
+ Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED) ||
+ !AppConstants.MOZ_TELEMETRY_REPORTING
+ ) {
+ checkbox.disabled = true;
+ } else {
+ checkbox.addEventListener("change", updateSubmitHealthReport);
+
+ checkbox.checked =
+ Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED) &&
+ AppConstants.MOZ_TELEMETRY_REPORTING;
+ }
+}
+
+/**
+ * Update the health report preference with state from checkbox.
+ */
+function updateSubmitHealthReport() {
+ let checkbox = document.getElementById("eCrashConfig");
+ Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked);
+}
+
+// prefs.html can be loaded as another <browser> from fxrui.html. In this
+// scenario, some actions are propogated to the parent
+function initParentDependencies() {
+ if (window.parent != window) {
+ // Close the <browser> instance that loaded this page
+ document.getElementById("eCloseSettings").addEventListener("click", () => {
+ window.parent.closeSettings();
+ });
+
+ // Load the relevant URLs into the top UI's <browser>
+ document.getElementById("ePrivacyPolicy").addEventListener("click", () => {
+ window.parent.showPrivacyPolicy();
+ });
+
+ document.getElementById("eLicenseInfo").addEventListener("click", () => {
+ window.parent.showLicenseInfo();
+ });
+
+ document.getElementById("eReportIssue").addEventListener("click", () => {
+ window.parent.showReportIssue();
+ });
+ }
+}
diff --git a/browser/fxr/jar.mn b/browser/fxr/jar.mn
new file mode 100644
index 0000000000..89f4da5702
--- /dev/null
+++ b/browser/fxr/jar.mn
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if defined(NIGHTLY_BUILD)
+browser.jar:
+% content fxr %content/browser/fxr/
+ content/browser/fxr/common.css (content/common.css)
+ content/browser/fxr/common.js (content/common.js)
+ content/browser/fxr/fxrui.html (content/fxrui.html)
+ content/browser/fxr/fxrui.css (content/fxrui.css)
+ content/browser/fxr/fxrui_blue.css (content/fxrui_blue.css)
+ content/browser/fxr/fxrui.js (content/fxrui.js)
+ content/browser/fxr/fxr-fullScreen.js (content/fxr-fullScreen.js)
+ content/browser/fxr/permissions.js (content/permissions.js)
+ content/browser/fxr/prefs.html (content/prefs.html)
+ content/browser/fxr/prefs.css (content/prefs.css)
+ content/browser/fxr/prefs.js (content/prefs.js)
+
+ content/browser/fxr/assets/icon-backward.svg (content/assets/icon-backward.svg)
+ content/browser/fxr/assets/icon-forward.svg (content/assets/icon-forward.svg)
+ content/browser/fxr/assets/icon-home.svg (content/assets/icon-home.svg)
+ content/browser/fxr/assets/icon-logo-settings-preview.png (content/assets/icon-logo-settings-preview.png)
+ content/browser/fxr/assets/icon-refresh.svg (content/assets/icon-refresh.svg)
+ content/browser/fxr/assets/icon-reportissue.svg (content/assets/icon-reportissue.svg)
+ content/browser/fxr/assets/icon-secure.svg (content/assets/icon-secure.svg)
+ content/browser/fxr/assets/icon-settings.svg (content/assets/icon-settings.svg)
+ content/browser/fxr/assets/icon-stop-reload.svg (content/assets/icon-stop-reload.svg)
+ content/browser/fxr/assets/icon-toggle-off.png (content/assets/icon-toggle-off.png)
+ content/browser/fxr/assets/icon-toggle-on.png (content/assets/icon-toggle-on.png)
+#endif
diff --git a/browser/fxr/moz.build b/browser/fxr/moz.build
new file mode 100644
index 0000000000..d988c0ff9b
--- /dev/null
+++ b/browser/fxr/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+JAR_MANIFESTS += ["jar.mn"]