favicon: Catch exceptions in update_favicon.

We’re getting unexplained exceptions from URL.createObjectURL in
Firefox 88 (#18374); contain them to this function.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-05-12 14:37:27 -07:00 committed by Tim Abbott
parent 66a232e303
commit 879ca4543b
1 changed files with 46 additions and 40 deletions

View File

@ -2,6 +2,8 @@ import $ from "jquery";
import render_favicon_svg from "../templates/favicon.svg.hbs"; import render_favicon_svg from "../templates/favicon.svg.hbs";
import * as blueslip from "./blueslip";
import favicon_font_url from "!url-loader!font-subset-loader2?glyphs=0123456789KMGT∞!source-sans/TTF/SourceSans3-Bold.ttf"; import favicon_font_url from "!url-loader!font-subset-loader2?glyphs=0123456789KMGT∞!source-sans/TTF/SourceSans3-Bold.ttf";
let favicon_state; let favicon_state;
@ -11,47 +13,51 @@ function set_favicon() {
} }
export function update_favicon(new_message_count, pm_count) { export function update_favicon(new_message_count, pm_count) {
if (favicon_state !== undefined) { try {
favicon_state.image.removeEventListener("load", set_favicon); if (favicon_state !== undefined) {
favicon_state.image.removeEventListener("load", set_favicon);
// We need to remove this src so revokeObjectURL doesn't cause a // We need to remove this src so revokeObjectURL doesn't cause a
// net::ERR_FILE_NOT_FOUND error in Chrome. This seems to be the // net::ERR_FILE_NOT_FOUND error in Chrome. This seems to be the
// simplest way to do that without triggering an expensive network // simplest way to do that without triggering an expensive network
// request or spewing a different console error. // request or spewing a different console error.
favicon_state.image.src = "data:,"; favicon_state.image.src = "data:,";
URL.revokeObjectURL(favicon_state.url); URL.revokeObjectURL(favicon_state.url);
favicon_state = undefined; favicon_state = undefined;
}
if (new_message_count === 0 && pm_count === 0) {
$("#favicon").attr("href", "/static/images/favicon.svg?v=4");
return;
}
const pow = Math.floor(Math.log10(new_message_count) / 3);
const suffix = ["", "K", "M", "G", "T"][pow];
const count =
new_message_count === 0
? ""
: pow < 5
? `${Math.floor(new_message_count / 1e3 ** pow)}${suffix}`
: "∞";
const count_long = count.length > 2;
const rendered_favicon = render_favicon_svg({
count,
count_long,
have_pm: pm_count !== 0,
favicon_font_url,
});
favicon_state = {
url: URL.createObjectURL(new Blob([rendered_favicon], {type: "image/svg+xml"})),
image: new Image(),
};
// Without loading the SVG in an Image first, Chrome mysteriously fails to
// render the webfont (https://crbug.com/1140920).
favicon_state.image.src = favicon_state.url;
favicon_state.image.addEventListener("load", set_favicon);
} catch (error) {
blueslip.error("Failed to update favicon", undefined, error.stack);
} }
if (new_message_count === 0 && pm_count === 0) {
$("#favicon").attr("href", "/static/images/favicon.svg?v=4");
return;
}
const pow = Math.floor(Math.log10(new_message_count) / 3);
const suffix = ["", "K", "M", "G", "T"][pow];
const count =
new_message_count === 0
? ""
: pow < 5
? `${Math.floor(new_message_count / 1e3 ** pow)}${suffix}`
: "∞";
const count_long = count.length > 2;
const rendered_favicon = render_favicon_svg({
count,
count_long,
have_pm: pm_count !== 0,
favicon_font_url,
});
favicon_state = {
url: URL.createObjectURL(new Blob([rendered_favicon], {type: "image/svg+xml"})),
image: new Image(),
};
// Without loading the SVG in an Image first, Chrome mysteriously fails to
// render the webfont (https://crbug.com/1140920).
favicon_state.image.src = favicon_state.url;
favicon_state.image.addEventListener("load", set_favicon);
} }