Bug 1526715 - avoid repeatedly calling Services.intl.DateTimeFormat when displaying chat messages or the list of previous conversations, r=clokep.
Differential Revision: https://phabricator.services.mozilla.com/D19275 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
663c920e35
Коммит
cc892d2a90
|
@ -9,151 +9,152 @@ this.EXPORTED_SYMBOLS = ["ToLocaleFormat"];
|
|||
// JS implementation of the deprecated Date.toLocaleFormat.
|
||||
// aFormat follows strftime syntax,
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html
|
||||
|
||||
function Day(t) {
|
||||
return Math.floor(t.valueOf() / 86400000);
|
||||
}
|
||||
function DayFromYear(y) {
|
||||
return 365 * (y - 1970) +
|
||||
Math.floor((y - 1969) / 4) -
|
||||
Math.floor((y - 1901) / 100) +
|
||||
Math.floor((y - 1601) / 400);
|
||||
}
|
||||
function DayWithinYear(t) {
|
||||
return Day(t) - DayFromYear(t.getFullYear());
|
||||
}
|
||||
function weekday(aDate, option) {
|
||||
return aDate.toLocaleString(undefined, {weekday: option});
|
||||
}
|
||||
function month(aDate, option) {
|
||||
return aDate.toLocaleString(undefined, {month: option});
|
||||
}
|
||||
function hourMinSecTwoDigits(aDate) {
|
||||
return aDate.toLocaleString(undefined, {
|
||||
hour: "2-digit", minute: "2-digit", second: "2-digit"
|
||||
});
|
||||
}
|
||||
function dayPeriod(aDate) {
|
||||
let dtf = Intl.DateTimeFormat(undefined, {hour: "2-digit"});
|
||||
let dayPeriodPart =
|
||||
dtf.resolvedOptions().hour12 &&
|
||||
dtf.formatToParts(aDate).find(part => part.type === "dayPeriod");
|
||||
return dayPeriodPart ? dayPeriodPart.value : "";
|
||||
}
|
||||
function weekNumber(aDate, weekStart) {
|
||||
let day = aDate.getDay();
|
||||
if (weekStart) {
|
||||
day = (day || 7) - weekStart;
|
||||
}
|
||||
return Math.max(Math.floor((DayWithinYear(t) + 7 - day) / 7), 0);
|
||||
}
|
||||
function weekNumberISO(t) {
|
||||
let thisWeek = weekNumber(1, t);
|
||||
let firstDayOfYear =
|
||||
(new Date(t.getFullYear(), 0, 1).getDay() || 7) - 1;
|
||||
if (thisWeek === 0 && firstDayOfYear >= 4)
|
||||
return weekNumberISO(new Date(t.getFullYear() - 1, 11, 31));
|
||||
if (t.getMonth() === 11 &&
|
||||
(t.getDate() - ((t.getDay() || 7) - 1)) >= 29)
|
||||
return 1;
|
||||
return thisWeek + (firstDayOfYear > 0 && firstDayOfYear < 4);
|
||||
}
|
||||
function weekYearISO(aDate) {
|
||||
let thisWeek = weekNumber(1, aDate);
|
||||
let firstDayOfYear =
|
||||
(new Date(aDate.getFullYear(), 0, 1).getDay() || 7) - 1;
|
||||
if (thisWeek === 0 && firstDayOfYear >= 4)
|
||||
return aDate.getFullYear() - 1;
|
||||
if (aDate.getMonth() === 11 &&
|
||||
(aDate.getDate() - ((aDate.getDay() || 7) - 1)) >= 29)
|
||||
return aDate.getFullYear() + 1;
|
||||
return aDate.getFullYear();
|
||||
}
|
||||
function timeZoneOffset(aDate) {
|
||||
let offset = aDate.getTimezoneOffset();
|
||||
let tzoff =
|
||||
Math.floor(Math.abs(offset) / 60) * 100 + Math.abs(offset) % 60;
|
||||
return (offset < 0 ? "+" : "-") + String(tzoff).padStart(4, "0");
|
||||
}
|
||||
function timeZone(aDate) {
|
||||
let dtf = Intl.DateTimeFormat(undefined, {timeZoneName: "short"});
|
||||
let timeZoneNamePart = dtf.formatToParts(aDate)
|
||||
.find(part => part.type === "timeZoneName");
|
||||
return timeZoneNamePart ? timeZoneNamePart.value : "";
|
||||
}
|
||||
|
||||
const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "full", timeStyle: "long"
|
||||
});
|
||||
const dateFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "full"
|
||||
});
|
||||
const timeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
timeStyle: "long"
|
||||
});
|
||||
|
||||
const formatFunctions = {
|
||||
a: aDate => weekday(aDate, "short"),
|
||||
A: aDate => weekday(aDate, "long"),
|
||||
b: aDate => month(aDate, "short"),
|
||||
B: aDate => month(aDate, "long"),
|
||||
c: aDate => dateTimeFormatter.format(aDate),
|
||||
C: aDate => String(Math.trunc(aDate.getFullYear() / 100)),
|
||||
d: aDate => String(aDate.getDate()),
|
||||
D: aDate => ToLocaleFormat("%m/%d/%y", aDate),
|
||||
e: aDate => String(aDate.getDate()),
|
||||
F: aDate => ToLocaleFormat("%Y-%m-%d", aDate),
|
||||
g: aDate => String(weekYearISO(aDate) % 100),
|
||||
G: aDate => String(weekYearISO(aDate)),
|
||||
h: aDate => month(aDate, "short"),
|
||||
H: aDate => String(aDate.getHours()),
|
||||
I: aDate => String(aDate.getHours() % 12 || 12),
|
||||
j: aDate => String(DayWithinYear(aDate) + 1),
|
||||
k: aDate => String(aDate.getHours()),
|
||||
l: aDate => String(aDate.getHours() % 12 || 12),
|
||||
m: aDate => String(aDate.getMonth() + 1),
|
||||
M: aDate => String(aDate.getMinutes()),
|
||||
n: () => "\n",
|
||||
p: aDate => dayPeriod(aDate).toLocaleUpperCase(),
|
||||
P: aDate => dayPeriod(aDate).toLocaleLowerCase(),
|
||||
r: aDate => hourMinSecTwoDigits(aDate),
|
||||
R: aDate => ToLocaleFormat("%H:%M", aDate),
|
||||
s: aDate => String(Math.trunc(aDate.getTime() / 1000)),
|
||||
S: aDate => String(aDate.getSeconds()),
|
||||
t: () => "\t",
|
||||
T: aDate => ToLocaleFormat("%H:%M:%S", aDate),
|
||||
u: aDate => String(aDate.getDay() || 7),
|
||||
U: aDate => String(weekNumber(aDate, 0)),
|
||||
V: aDate => String(weekNumberISO(aDate)),
|
||||
w: aDate => String(aDate.getDay()),
|
||||
W: aDate => String(weekNumber(aDate, 1)),
|
||||
x: aDate => dateFormatter.format(aDate),
|
||||
X: aDate => timeFormatter.format(aDate),
|
||||
y: aDate => String(aDate.getFullYear() % 100),
|
||||
Y: aDate => String(aDate.getFullYear()),
|
||||
z: aDate => timeZoneOffset(aDate),
|
||||
Z: aDate => timeZone(aDate),
|
||||
"%": () => "%",
|
||||
};
|
||||
const padding = {
|
||||
C: {fill: "0", width: 2},
|
||||
d: {fill: "0", width: 2},
|
||||
e: {fill: " ", width: 2},
|
||||
g: {fill: "0", width: 2},
|
||||
H: {fill: "0", width: 2},
|
||||
I: {fill: "0", width: 2},
|
||||
j: {fill: "0", width: 3},
|
||||
k: {fill: " ", width: 2},
|
||||
l: {fill: " ", width: 2},
|
||||
m: {fill: "0", width: 2},
|
||||
M: {fill: "0", width: 2},
|
||||
S: {fill: "0", width: 2},
|
||||
U: {fill: "0", width: 2},
|
||||
V: {fill: "0", width: 2},
|
||||
W: {fill: "0", width: 2},
|
||||
y: {fill: "0", width: 2},
|
||||
};
|
||||
|
||||
function ToLocaleFormat(aFormat, aDate) {
|
||||
function Day(t) {
|
||||
return Math.floor(t.valueOf() / 86400000);
|
||||
}
|
||||
function DayFromYear(y) {
|
||||
return 365 * (y - 1970) +
|
||||
Math.floor((y - 1969) / 4) -
|
||||
Math.floor((y - 1901) / 100) +
|
||||
Math.floor((y - 1601) / 400);
|
||||
}
|
||||
function DayWithinYear(t) {
|
||||
return Day(t) - DayFromYear(t.getFullYear());
|
||||
}
|
||||
function weekday(option) {
|
||||
return aDate.toLocaleString(undefined, {weekday: option});
|
||||
}
|
||||
function month(option) {
|
||||
return aDate.toLocaleString(undefined, {month: option});
|
||||
}
|
||||
function hourMinSecTwoDigits() {
|
||||
return aDate.toLocaleString(undefined, {
|
||||
hour: "2-digit", minute: "2-digit", second: "2-digit"
|
||||
});
|
||||
}
|
||||
function dayPeriod() {
|
||||
let dtf = Intl.DateTimeFormat(undefined, {hour: "2-digit"});
|
||||
let dayPeriodPart =
|
||||
dtf.resolvedOptions().hour12 &&
|
||||
dtf.formatToParts(aDate).find(part => part.type === "dayPeriod");
|
||||
return dayPeriodPart ? dayPeriodPart.value : "";
|
||||
}
|
||||
function weekNumber(weekStart, t = aDate) {
|
||||
let day = t.getDay();
|
||||
if (weekStart) {
|
||||
day = (day || 7) - weekStart;
|
||||
}
|
||||
return Math.max(Math.floor((DayWithinYear(t) + 7 - day) / 7), 0);
|
||||
}
|
||||
function weekNumberISO(t = aDate) {
|
||||
let thisWeek = weekNumber(1, t);
|
||||
let firstDayOfYear =
|
||||
(new Date(t.getFullYear(), 0, 1).getDay() || 7) - 1;
|
||||
if (thisWeek === 0 && firstDayOfYear >= 4)
|
||||
return weekNumberISO(new Date(t.getFullYear() - 1, 11, 31));
|
||||
if (t.getMonth() === 11 &&
|
||||
(t.getDate() - ((t.getDay() || 7) - 1)) >= 29)
|
||||
return 1;
|
||||
return thisWeek + (firstDayOfYear > 0 && firstDayOfYear < 4);
|
||||
}
|
||||
function weekYearISO() {
|
||||
let thisWeek = weekNumber(1, aDate);
|
||||
let firstDayOfYear =
|
||||
(new Date(aDate.getFullYear(), 0, 1).getDay() || 7) - 1;
|
||||
if (thisWeek === 0 && firstDayOfYear >= 4)
|
||||
return aDate.getFullYear() - 1;
|
||||
if (aDate.getMonth() === 11 &&
|
||||
(aDate.getDate() - ((aDate.getDay() || 7) - 1)) >= 29)
|
||||
return aDate.getFullYear() + 1;
|
||||
return aDate.getFullYear();
|
||||
}
|
||||
function timeZoneOffset() {
|
||||
let offset = aDate.getTimezoneOffset();
|
||||
let tzoff =
|
||||
Math.floor(Math.abs(offset) / 60) * 100 + Math.abs(offset) % 60;
|
||||
return (offset < 0 ? "+" : "-") + String(tzoff).padStart(4, "0");
|
||||
}
|
||||
function timeZone() {
|
||||
let dtf = Intl.DateTimeFormat(undefined, {timeZoneName: "short"});
|
||||
let timeZoneNamePart = dtf.formatToParts(aDate)
|
||||
.find(part => part.type === "timeZoneName");
|
||||
return timeZoneNamePart ? timeZoneNamePart.value : "";
|
||||
}
|
||||
|
||||
let dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "full", timeStyle: "long"
|
||||
});
|
||||
let dateFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "full"
|
||||
});
|
||||
let timeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
timeStyle: "long"
|
||||
});
|
||||
|
||||
let formatFunctions = {
|
||||
a: () => weekday("short"),
|
||||
A: () => weekday("long"),
|
||||
b: () => month("short"),
|
||||
B: () => month("long"),
|
||||
c: () => dateTimeFormatter.format(aDate),
|
||||
C: () => String(Math.trunc(aDate.getFullYear() / 100)),
|
||||
d: () => String(aDate.getDate()),
|
||||
D: () => ToLocaleFormat("%m/%d/%y", aDate),
|
||||
e: () => String(aDate.getDate()),
|
||||
F: () => ToLocaleFormat("%Y-%m-%d", aDate),
|
||||
g: () => String(weekYearISO() % 100),
|
||||
G: () => String(weekYearISO()),
|
||||
h: () => month("short"),
|
||||
H: () => String(aDate.getHours()),
|
||||
I: () => String(aDate.getHours() % 12 || 12),
|
||||
j: () => String(DayWithinYear(aDate) + 1),
|
||||
k: () => String(aDate.getHours()),
|
||||
l: () => String(aDate.getHours() % 12 || 12),
|
||||
m: () => String(aDate.getMonth() + 1),
|
||||
M: () => String(aDate.getMinutes()),
|
||||
n: () => "\n",
|
||||
p: () => dayPeriod().toLocaleUpperCase(),
|
||||
P: () => dayPeriod().toLocaleLowerCase(),
|
||||
r: () => hourMinSecTwoDigits(),
|
||||
R: () => ToLocaleFormat("%H:%M", aDate),
|
||||
s: () => String(Math.trunc(aDate.getTime() / 1000)),
|
||||
S: () => String(aDate.getSeconds()),
|
||||
t: () => "\t",
|
||||
T: () => ToLocaleFormat("%H:%M:%S", aDate),
|
||||
u: () => String(aDate.getDay() || 7),
|
||||
U: () => String(weekNumber(0)),
|
||||
V: () => String(weekNumberISO()),
|
||||
w: () => String(aDate.getDay()),
|
||||
W: () => String(weekNumber(1)),
|
||||
x: () => dateFormatter.format(aDate),
|
||||
X: () => timeFormatter.format(aDate),
|
||||
y: () => String(aDate.getFullYear() % 100),
|
||||
Y: () => String(aDate.getFullYear()),
|
||||
z: () => timeZoneOffset(),
|
||||
Z: () => timeZone(),
|
||||
"%": () => "%",
|
||||
};
|
||||
let padding = {
|
||||
C: {fill: "0", width: 2},
|
||||
d: {fill: "0", width: 2},
|
||||
e: {fill: " ", width: 2},
|
||||
g: {fill: "0", width: 2},
|
||||
H: {fill: "0", width: 2},
|
||||
I: {fill: "0", width: 2},
|
||||
j: {fill: "0", width: 3},
|
||||
k: {fill: " ", width: 2},
|
||||
l: {fill: " ", width: 2},
|
||||
m: {fill: "0", width: 2},
|
||||
M: {fill: "0", width: 2},
|
||||
S: {fill: "0", width: 2},
|
||||
U: {fill: "0", width: 2},
|
||||
V: {fill: "0", width: 2},
|
||||
W: {fill: "0", width: 2},
|
||||
y: {fill: "0", width: 2},
|
||||
};
|
||||
|
||||
// Modified conversion specifiers E and O are ignored.
|
||||
let specifiers = Object.keys(formatFunctions).join("");
|
||||
let pattern =
|
||||
|
@ -161,7 +162,7 @@ function ToLocaleFormat(aFormat, aDate) {
|
|||
|
||||
return aFormat.replace(pattern,
|
||||
(matched, upperCaseFlag, fillWidthFlags, specifier) => {
|
||||
let result = formatFunctions[specifier]();
|
||||
let result = formatFunctions[specifier](aDate);
|
||||
if (upperCaseFlag)
|
||||
result = result.toLocaleUpperCase();
|
||||
let fill = (specifier in padding) ? padding[specifier].fill : "";
|
||||
|
|
|
@ -1248,16 +1248,16 @@ chatLogTreeView.prototype = {
|
|||
let chatBundle = document.getElementById("chatBundle");
|
||||
let dateFormatBundle = document.getElementById("bundle_dateformat");
|
||||
let placesBundle = document.getElementById("bundle_places");
|
||||
const dateFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short",
|
||||
});
|
||||
let formatDate = function(aDate) {
|
||||
const dateFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short",
|
||||
});
|
||||
return dateFormatter.format(aDate);
|
||||
};
|
||||
const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short", timeStyle: "short",
|
||||
});
|
||||
let formatDateTime = function(aDate) {
|
||||
const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short", timeStyle: "short",
|
||||
});
|
||||
return dateTimeFormatter.format(aDate);
|
||||
};
|
||||
let formatMonthYear = function(aDate) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче