Bug 1901520 - Part 2: Add styles and scripts to the single file archive. r=backup-reviewers,frontend-codestyle-reviewers,kpatenio

Differential Revision: https://phabricator.services.mozilla.com/D213975
This commit is contained in:
Mike Conley
2024-06-25 00:35:43 +00:00
parent c6adb68ed0
commit f28634d0f8
7 changed files with 150 additions and 1 deletions

View File

@@ -40,6 +40,8 @@ browser/branding/**/firefox-branding.js
# Gzipped test file.
browser/base/content/test/general/gZipOfflineChild.html
browser/base/content/test/urlbar/file_blank_but_not_blank.html
# Pre-processed template file
browser/components/backup/content/archive.template.html
# Test files that are really json not js, and don't need to be linted.
browser/components/sessionstore/test/unit/data/sessionstore_valid.js
browser/components/sessionstore/test/unit/data/sessionstore_invalid.js

View File

@@ -1194,6 +1194,10 @@ export class BackupService extends EventTarget {
* @returns {Promise<string>}
*/
async renderTemplate(templateURI, isEncrypted, backupMetadata) {
const ARCHIVE_STYLES = "chrome://browser/content/backup/archive.css";
const ARCHIVE_SCRIPT = "chrome://browser/content/backup/archive.js";
const LOGO = "chrome://branding/content/icon128.png";
let templateResponse = await fetch(templateURI);
let templateString = await templateResponse.text();
let templateDOM = new DOMParser().parseFromString(
@@ -1214,6 +1218,20 @@ export class BackupService extends EventTarget {
let supportLink = templateDOM.querySelector("#support-link");
supportLink.href = supportLinkHref;
// Now insert the logo as a dataURL, since we want the single-file backup
// archive to be entirely self-contained.
let logoResponse = await fetch(LOGO);
let logoBlob = await logoResponse.blob();
let logoDataURL = await new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("load", () => resolve(reader.result));
reader.addEventListener("error", reject);
reader.readAsDataURL(logoBlob);
});
let logoNode = templateDOM.querySelector("#logo");
logoNode.src = logoDataURL;
let encStateNode = templateDOM.querySelector("#encryption-state");
lazy.gDOMLocalization.setAttributes(
encStateNode,
@@ -1244,8 +1262,33 @@ export class BackupService extends EventTarget {
// cause backup creation to fail.
}
// We have to insert styles and scripts after we serialize to XML, otherwise
// the XMLSerializer will escape things like descendent selectors in CSS
// with &gt;.
let stylesResponse = await fetch(ARCHIVE_STYLES);
let scriptResponse = await fetch(ARCHIVE_SCRIPT);
// These days, we don't really support CSS preprocessor directives, so we
// can't ifdef out the MPL license header in styles before writing it into
// the archive file. Instead, we'll ensure that the license header is there,
// and then manually remove it here at runtime.
let stylesText = await stylesResponse.text();
const MPL_LICENSE = `/**
* 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/.
*/`;
if (!stylesText.includes(MPL_LICENSE)) {
throw new Error("Expected the MPL license block within archive.css");
}
stylesText = stylesText.replace(MPL_LICENSE, "");
let serializer = new XMLSerializer();
return serializer.serializeToString(templateDOM);
return serializer
.serializeToString(templateDOM)
.replace("{{styles}}", stylesText)
.replace("{{script}}", await scriptResponse.text());
}
/**

View File

@@ -0,0 +1,74 @@
/**
* 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/.
*/
body[is-moz-browser] .other-browser,
body:not([is-moz-browser]) .moz-browser {
display: none;
}
body {
display: flex;
flex-direction: column;
font: message-box;
font-size: 14px;
width: 28rem;
height: 100vh;
justify-content: center;
margin: auto;
}
img {
width: 80px;
height: 80px;
align-self: center;
}
h1 {
text-align: center;
}
a {
color: #0060DF;
}
ul {
padding-inline-start: 0;
}
ul > li {
list-style-type: none;
margin-block: 0.35rem;
}
hr {
border-color: #F0F0F4;
border-style: solid;
border-width: 1px 0px 0px 0px;
margin: 0;
}
ol > li {
margin-block: 1.5rem;
}
button {
appearance: none;
color: #fbfbfe;
border: 1px solid transparent;
border-radius: 4px;
background-color: #0060df;
padding: calc(2 * 0.267rem) calc(4 * 0.267rem);
font-size: inherit;
margin-inline-start: 18px;
}
button:hover {
background-color: #0250bb;
}
button:active {
background-color: #073072;
}

View File

@@ -0,0 +1,20 @@
/**
#if 0
#
# 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/.
#
# This file is used to construct the single-file archive of a backup. This
# file is part of our source code, and so this is why we include the license
# header above. We do not, however, want to apply the header to backup files
# that are generated via this template. This is why we use the pre-processor
# mechanism to remove this comment block at build time.
#
#endif
*/
const UA = navigator.userAgent;
const isMozBrowser = /Firefox/.test(UA);
document.body.toggleAttribute("is-moz-browser", isMozBrowser);

View File

@@ -20,8 +20,12 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title data-l10n-id="backup-file-title"></title>
<style>
{{styles}}
</style>
</head>
<body>
<img id="logo" role="presentation" />
<h1 data-l10n-id="backup-file-header"></h1>
<p data-l10n-id="backup-file-intro">
<a data-l10n-name="backup-file-support-link" id="support-link" target="_blank"></a>
@@ -47,4 +51,7 @@
</ol>
</section>
</body>
<script>
{{script}}
</script>
</html>

View File

@@ -20,3 +20,5 @@ browser.jar:
content/browser/backup/restore-from-backup.css (content/restore-from-backup.css)
content/browser/backup/restore-from-backup.mjs (content/restore-from-backup.mjs)
* content/browser/backup/archive.template.html (content/archive.template.html)
content/browser/backup/archive.css (content/archive.css)
* content/browser/backup/archive.js (content/archive.js)

View File

@@ -7,6 +7,7 @@
<title data-l10n-id="backup-file-title"></title>
</head>
<body>
<img id="logo" role="presentation" />
<h1 data-l10n-id="backup-file-header"></h1>
<p data-l10n-id="backup-file-intro">
<a data-l10n-name="backup-file-support-link" id="support-link"></a>