Bug 1893758 - Calendar Fluent Migrations - Properties Part A. r=mkmelin

Differential Revision: https://phabricator.services.mozilla.com/D209074

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Joe Crawford 2024-06-19 22:05:56 +00:00
Родитель 94da6c42b9
Коммит 7e7c3c22fb
86 изменённых файлов: 3087 добавлений и 1517 удалений

Просмотреть файл

@ -8,6 +8,9 @@
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/* exported cutToClipboard, pasteFromClipboard */
/* eslint-enable valid-jsdoc */
@ -216,18 +219,18 @@ function pasteFromClipboard() {
let pasteText = "paste";
if (withAttendees.length) {
if (withAttendees.every(item => item.isEvent())) {
pasteText += "Event";
pasteText = `${pasteText}-event`;
} else if (withAttendees.every(item => item.isTodo())) {
pasteText += "Task";
pasteText = `${pasteText}-task`;
} else {
pasteText += "Item";
pasteText = `${pasteText}-item`;
}
if (withAttendees.length > 1) {
pasteText += "s";
pasteText = `${pasteText}s`;
}
}
const validPasteText = pasteText != "paste" && !pasteText.endsWith("Item");
pasteText += items.length == withAttendees.length ? "Only" : "Also";
const validPasteText = pasteText != "paste" && !pasteText.endsWith("-item");
pasteText += items.length == withAttendees.length ? "-only" : "-also";
const calendars = cal.manager
.getCalendars()
@ -240,19 +243,19 @@ function pasteFromClipboard() {
if (calendars.length > 1) {
const args = {};
args.calendars = calendars;
args.promptText = cal.l10n.getCalString("pastePrompt");
args.promptText = lazy.l10n.formatValueSync("paste-prompt");
if (validPasteText) {
pasteText = cal.l10n.getCalString(pasteText);
const note = cal.l10n.getCalString("pasteNotifyAbout", [pasteText]);
pasteText = lazy.l10n.formatValueSync(pasteText);
const note = lazy.l10n.formatValueSync("paste-notify-about", { pasteItem: pasteText });
args.promptNotify = note;
args.labelExtra1 = cal.l10n.getCalString("pasteDontNotifyLabel");
args.labelExtra1 = lazy.l10n.formatValueSync("paste-dont-notify-label");
args.onExtra1 = aCal => {
destCal = aCal;
notify = Ci.calIItipItem.NONE;
};
args.labelOk = cal.l10n.getCalString("pasteAndNotifyLabel");
args.labelOk = lazy.l10n.formatValueSync("paste-and-notify-label");
args.onOk = aCal => {
destCal = aCal;
notify = Ci.calIItipItem.AUTO;

Просмотреть файл

@ -731,22 +731,21 @@ function setupContextItemType(aEvent, aItems) {
function adaptModificationMenuItem(aMenuItemId, aItemType) {
const menuItem = document.getElementById(aMenuItemId);
if (menuItem) {
menuItem.setAttribute("label", cal.l10n.getCalString(`delete${aItemType}Label`));
menuItem.setAttribute("accesskey", cal.l10n.getCalString(`delete${aItemType}Accesskey`));
document.l10n.setAttributes(menuItem, `delete-${aItemType}`);
}
}
if (aItems.some(item => item.isEvent()) && aItems.some(item => item.isTodo())) {
aEvent.target.setAttribute("type", "mixed");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "item");
} else if (aItems.length && aItems[0].isEvent()) {
aEvent.target.setAttribute("type", "event");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Event");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "event");
} else if (aItems.length && aItems[0].isTodo()) {
aEvent.target.setAttribute("type", "todo");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Task");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "task");
} else {
aEvent.target.removeAttribute("type");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "item");
}
const menu = document.getElementById("calendar-item-context-menu-attendance-menu");

Просмотреть файл

@ -7,7 +7,6 @@
// Wrap in a block to prevent leaking to window scope.
{
const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
class MozCalendarDayLabel extends MozXULElement {
static get observedAttributes() {
return ["selected", "relation"];
@ -37,6 +36,8 @@
this.mDate = null;
MozXULElement.insertFTLIfNeeded("calendar/calendar.ftl");
this._updateAttributes();
}
@ -79,16 +80,24 @@
set date(val) {
this.mDate = val;
const dateFormatter = cal.dtz.formatter;
let label = cal.l10n.getCalString("dayHeaderLabel", [
dateFormatter.shortDayName(val.weekday),
dateFormatter.formatDateWithoutYear(val),
]);
this.shortWeekdayName.setAttribute("value", label);
label = cal.l10n.getCalString("dayHeaderLabel", [
dateFormatter.dayName(val.weekday),
dateFormatter.formatDateWithoutYear(val),
]);
this.longWeekdayName.setAttribute("value", label);
document.l10n.setAttributes(this.shortWeekdayName, "day-header-elem", {
day: dateFormatter.shortDayName(val.weekday),
date: dateFormatter.formatDateWithoutYear(val),
});
document.l10n.setAttributes(this.longWeekdayName, "day-header-elem", {
day: dateFormatter.dayName(val.weekday),
date: dateFormatter.formatDateWithoutYear(val),
});
const shortLabel = document.l10n.formatValueSync("day-header", {
dayName: dateFormatter.shortDayName(val.weekday),
dayIndex: dateFormatter.formatDateWithoutYear(val),
});
const longLabel = document.l10n.formatValueSync("day-header", {
dayName: dateFormatter.dayName(val.weekday),
dayIndex: dateFormatter.formatDateWithoutYear(val),
});
this.shortWeekdayName.setAttribute("value", shortLabel);
this.longWeekdayName.setAttribute("value", longLabel);
}
get date() {

Просмотреть файл

@ -9,6 +9,13 @@
// Wrap in a block to prevent leaking to window scope.
{
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
/**
* The MozCalendarEditableItem widget is used as a full day event item in the
* Day and Week views of the calendar. It displays the event name, alarm icon
@ -127,6 +134,8 @@
if (this.delayConnectedCallback() || this.hasChildNodes()) {
return;
}
MozXULElement.insertFTLIfNeeded("calendar/calendar.ftl");
this.appendChild(
MozXULElement.parseXULToFragment(`
<html:div class="calendar-item-flex">
@ -134,7 +143,7 @@
<html:div class="event-name-label"></html:div>
<html:input class="plain event-name-input"
hidden="hidden"
placeholder='${cal.l10n.getCalString("newEvent")}'/>
data-l10n-id="new-event"/>
<html:div class="alarm-icons-box"></html:div>
<html:img class="item-classification-icon" />
<html:img class="item-recurrence-icon" />
@ -245,9 +254,12 @@
setEditableLabel() {
const label = this.eventNameLabel;
const item = this.mOccurrence;
label.textContent = item.title
? item.title.replace(/\n/g, " ")
: cal.l10n.getCalString("eventUntitled");
if (item.title) {
delete label.dataset.l10nId;
label.textContent = item.title.replace(/\n/g, " ");
} else {
document.l10n.setAttributes(label, "event-untitled");
}
}
setLocationLabel() {
@ -444,7 +456,7 @@
this.mOccurrence,
null,
null,
this.eventNameTextbox.value || cal.l10n.getCalString("eventUntitled")
this.eventNameTextbox.value || lazy.l10n.formatValueSync("event-untitled")
);
// Note that as soon as we do the modifyItem, this element ceases to exist,

Просмотреть файл

@ -41,9 +41,12 @@ var calendarExtract = {
// If no language name is found that is ok, keep the technical term
}
let label = cal.l10n.getCalString("extractUsing", [langName]);
let label = calendarExtract.l10n.formatValueSync("extract-using", { languageName: langName });
if (localeParts[3] != "") {
label = cal.l10n.getCalString("extractUsingRegion", [langName, localeParts[3]]);
label = calendarExtract.l10n.formatValueSync("extract-using-region", {
languageName: langName,
region: localeParts[3],
});
}
langs.push([label, localeParts[1]]);
@ -264,3 +267,8 @@ var calendarExtract = {
);
},
};
ChromeUtils.defineLazyGetter(
calendarExtract,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);

Просмотреть файл

@ -12,6 +12,9 @@
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* Get this window's currently selected calendar.
*
@ -36,7 +39,7 @@ function promptDeleteCalendar(aCalendar) {
}
const modes = new Set(aCalendar.getProperty("capabilities.removeModes") || ["unsubscribe"]);
const title = cal.l10n.getCalString("removeCalendarTitle");
const title = lazy.l10n.formatValueSync("remove-calendar-title");
let textKey, b0text, b2text;
let removeFlags = 0;
@ -45,23 +48,23 @@ function promptDeleteCalendar(aCalendar) {
Ci.nsIPromptService.BUTTON_POS_1 * Ci.nsIPromptService.BUTTON_TITLE_CANCEL;
if (modes.has("delete") && !modes.has("unsubscribe")) {
textKey = "removeCalendarMessageDelete";
textKey = "remove-calendar-message-delete";
promptFlags += Ci.nsIPromptService.BUTTON_DELAY_ENABLE;
b0text = cal.l10n.getCalString("removeCalendarButtonDelete");
b0text = lazy.l10n.formatValueSync("remove-calendar-button-delete");
} else if (modes.has("delete")) {
textKey = "removeCalendarMessageDeleteOrUnsubscribe";
textKey = "remove-calendar-message-delete-or-unsubscribe";
promptFlags += Ci.nsIPromptService.BUTTON_POS_2 * Ci.nsIPromptService.BUTTON_TITLE_IS_STRING;
b0text = cal.l10n.getCalString("removeCalendarButtonUnsubscribe");
b2text = cal.l10n.getCalString("removeCalendarButtonDelete");
b0text = lazy.l10n.formatValueSync("remove-calendar-button-unsubscribe");
b2text = lazy.l10n.formatValueSync("remove-calendar-button-delete");
} else if (modes.has("unsubscribe")) {
textKey = "removeCalendarMessageUnsubscribe";
textKey = "remove-calendar-message-unsubscribe";
removeFlags |= Ci.calICalendarManager.REMOVE_NO_DELETE;
b0text = cal.l10n.getCalString("removeCalendarButtonUnsubscribe");
b0text = lazy.l10n.formatValueSync("remove-calendar-button-unsubscribe");
} else {
return;
}
const text = cal.l10n.getCalString(textKey, [aCalendar.name]);
const text = lazy.l10n.formatValueSync(textKey, { name: aCalendar.name });
const res = Services.prompt.confirmEx(
window,
title,
@ -76,7 +79,7 @@ function promptDeleteCalendar(aCalendar) {
if (res != 1) {
// Not canceled
if (textKey == "removeCalendarMessageDeleteOrUnsubscribe" && res == 0) {
if (textKey == "remove-calendar-message-delete-or-unsubscribe" && res == 0) {
// Both unsubscribing and deleting is possible, but unsubscribing was
// requested. Make sure no delete is executed.
removeFlags |= Ci.calICalendarManager.REMOVE_NO_DELETE;
@ -97,14 +100,13 @@ function updateCalendarStatusIndicators(item) {
const image = item.querySelector("img.calendar-readstatus");
if (item.hasAttribute("calendar-readfailed")) {
image.setAttribute("src", "chrome://messenger/skin/icons/new/compact/warning.svg");
const tooltip = cal.l10n.getCalString("tooltipCalendarDisabled", [calendarName]);
image.setAttribute("title", tooltip);
document.l10n.setAttributes(item, "tooltip-calendar-disabled", { name: calendarName });
} else if (item.hasAttribute("calendar-readonly")) {
image.setAttribute("src", "chrome://messenger/skin/icons/new/compact/lock.svg");
const tooltip = cal.l10n.getCalString("tooltipCalendarReadOnly", [calendarName]);
image.setAttribute("title", tooltip);
document.l10n.setAttributes(item, "tooltip-calendar-read-only", { name: calendarName });
} else {
image.removeAttribute("src");
delete item.dataset.l10nId;
image.removeAttribute("title");
}
}
@ -192,9 +194,9 @@ async function loadCalendarManager() {
displayedCheckbox.checked = calendar.getProperty("calendar-main-in-composite");
displayedCheckbox.hidden = calendar.getProperty("disabled");
const stringName = cal.view.getCompositeCalendar(window).getCalendarById(calendar.id)
? "hideCalendar"
: "showCalendar";
displayedCheckbox.setAttribute("title", cal.l10n.getCalString(stringName, [calendar.name]));
? "hide-calendar-title"
: "show-calendar-title";
document.l10n.setAttributes(displayedCheckbox, stringName, { name: calendar.name });
calendarList.appendChild(item);
if (calendar.getProperty("calendar-main-default")) {
@ -239,8 +241,8 @@ async function loadCalendarManager() {
compositeCalendar.removeCalendar(calendar);
}
const stringName = event.target.checked ? "hideCalendar" : "showCalendar";
event.target.setAttribute("title", cal.l10n.getCalString(stringName, [calendar.name]));
const stringName = event.target.checked ? "hide-calendar-title" : "show-calendar-title";
document.l10n.setAttributes(event.target, stringName, { name: calendar.name });
calendarList.focus();
});
@ -283,11 +285,11 @@ async function loadCalendarManager() {
compositeCalendar.addCalendar(calendar);
}
const stringName = item.querySelector(".calendar-displayed").checked
? "hideCalendar"
: "showCalendar";
item
.querySelector(".calendar-displayed")
.setAttribute("title", cal.l10n.getCalString(stringName, [calendar.name]));
? "hide-calendar-title"
: "show-calendar-title";
document.l10n.setAttributes(item.querySelector(".calendar-displayed"), stringName, {
name: calendar.name,
});
break;
}
}
@ -397,7 +399,7 @@ function initHomeCalendar() {
const composite = cal.view.getCompositeCalendar(window);
const url = Services.io.newURI("moz-storage-calendar://");
const homeCalendar = cal.manager.createCalendar("storage", url);
homeCalendar.name = cal.l10n.getCalString("homeCalendarName");
homeCalendar.name = lazy.l10n.formatValueSync("home-calendar-name");
homeCalendar.setProperty("disabled", true);
cal.manager.registerCalendar(homeCalendar);
@ -458,18 +460,23 @@ function calendarListSetupContextMenu(event) {
elem.hidden = !calendar;
}
if (calendar) {
const stringName = composite.getCalendarById(calendar.id) ? "hideCalendar" : "showCalendar";
document.getElementById("list-calendars-context-togglevisible").label = cal.l10n.getCalString(
const stringName = composite.getCalendarById(calendar.id)
? "hide-calendar-label"
: "show-calendar-label";
document.l10n.setAttributes(
document.getElementById("list-calendars-context-togglevisible"),
stringName,
[calendar.name]
{ name: calendar.name }
);
const accessKey = document
.getElementById("list-calendars-context-togglevisible")
.getAttribute(composite.getCalendarById(calendar.id) ? "accesskeyhide" : "accesskeyshow");
document.getElementById("list-calendars-context-togglevisible").accessKey = accessKey;
document.getElementById("list-calendars-context-showonly").label = cal.l10n.getCalString(
"showOnlyCalendar",
[calendar.name]
document.l10n.setAttributes(
document.getElementById("list-calendars-context-showonly"),
"show-only-calendar",
{ name: calendar.name }
);
setupDeleteMenuitem("list-calendars-context-delete", calendar);
document.getElementById("list-calendar-context-reload").hidden = !calendar.canRefresh;
@ -641,9 +648,9 @@ var compositeObserver = {
*/
function openLocalCalendar() {
const picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
picker.init(window.browsingContext, cal.l10n.getCalString("Open"), Ci.nsIFilePicker.modeOpen);
picker.init(window.browsingContext, lazy.l10n.formatValueSync("open"), Ci.nsIFilePicker.modeOpen);
const wildmat = "*.ics";
const description = cal.l10n.getCalString("filterIcs", [wildmat]);
const description = lazy.l10n.formatValueSync("filter-ics", { wildmat });
picker.appendFilter(description, wildmat);
picker.appendFilters(Ci.nsIFilePicker.filterAll);
@ -662,7 +669,7 @@ function openLocalCalendar() {
if (prettyName) {
calendar.name = decodeURIComponent(prettyName[1]);
} else {
calendar.name = cal.l10n.getCalString("untitledCalendarName");
calendar.name = lazy.l10n.formatValueSync("untitled-calendar-name");
}
cal.manager.registerCalendar(calendar);

Просмотреть файл

@ -6,7 +6,8 @@
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { AppConstants } = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/* eslint-enable valid-jsdoc */
/**
@ -277,10 +278,16 @@ var gDataMigrator = {
} catch (ex) {
switch (ex.result) {
case Ci.calIErrors.INVALID_TIMEZONE:
cal.showError(cal.l10n.getCalString("timezoneError", [icsFile.path]), window);
cal.showError(
lazy.l10n.formatValueSync("timezone-error", { filePath: icsFile.path }),
window
);
break;
default:
cal.showError(cal.l10n.getCalString("unableToRead") + icsFile.path + "\n" + ex, window);
cal.showError(
lazy.l10n.formatValueSync("unable-to-read") + icsFile.path + "\n" + ex,
window
);
}
} finally {
inputStream.close();
@ -302,15 +309,18 @@ var gDataMigrator = {
onEnd() {
if (this.failedCount) {
cal.showError(
cal.l10n.getCalString("importItemsFailed", [
this.failedCount,
this.lastError.toString(),
]),
lazy.l10n.formatValueSync("import-items-failed", {
count: this.failedCount,
error: this.lastError.toString(),
}),
window
);
} else if (this.duplicateCount) {
cal.showError(
cal.l10n.getCalString("duplicateError", [this.duplicateCount, icsFile.path]),
lazy.l10n.formatValueSync("duplicate-error", {
count: this.duplicateCount,
filePath: icsFile.path,
}),
window
);
}

Просмотреть файл

@ -13,7 +13,6 @@
// Wrap in a block to prevent leaking to window scope.
{
const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
/**
* Implements the Drag and Drop class for the Month Day Box view.
*
@ -304,6 +303,7 @@
if (this.delayConnectedCallback() || this.hasChildNodes()) {
return;
}
MozXULElement.insertFTLIfNeeded("calendar/calendar.ftl");
// NOTE: This is the same structure as EditableItem, except this has a
// time label and we are missing the location-desc.
this.appendChild(
@ -313,7 +313,7 @@
<html:div class="event-name-label"></html:div>
<html:input class="plain event-name-input"
hidden="hidden"
placeholder='${cal.l10n.getCalString("newEvent")}' />
data-l10n-id="new-event" />
<html:div class="alarm-icons-box"></html:div>
<html:img class="item-classification-icon" />
<html:img class="item-recurrence-icon" />
@ -921,8 +921,7 @@
if (j == weekLabelColumnPos) {
weekLabel.removeAttribute("hidden");
const weekNumber = cal.weekInfoService.getWeekTitle(date);
const weekString = cal.l10n.getCalString("multiweekViewWeek", [weekNumber]);
weekLabel.textContent = weekString;
document.l10n.setAttributes(weekLabel, "multiweek-view-week", { number: weekNumber });
} else {
weekLabel.hidden = true;
}

Просмотреть файл

@ -16,7 +16,12 @@
{
const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
const MINUTES_IN_DAY = 24 * 60;
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
/**
* Get the nearest or next snap point for the given minute. The set of snap
* points is given by `n * snapInterval`, where `n` is some integer.
@ -816,9 +821,9 @@
const item = this.mDragState.dragOccurrence;
if (item?.isTodo()) {
if (!item.dueDate) {
startStr = cal.l10n.getCalString("dragLabelTasksWithOnlyEntryDate");
startStr = lazy.l10n.formatValueSync("drag-label-tasks-with-only-entry-date");
} else if (!item.entryDate) {
startStr = cal.l10n.getCalString("dragLabelTasksWithOnlyDueDate");
startStr = lazy.l10n.formatValueSync("drag-label-tasks-with-only-due-date");
}
}
@ -1755,6 +1760,7 @@
if (this.delayConnectedCallback() || this.hasChildNodes()) {
return;
}
MozXULElement.insertFTLIfNeeded("calendar/calendar.ftl");
this.appendChild(
MozXULElement.parseXULToFragment(`
@ -1765,7 +1771,7 @@
<html:div class="event-name-label"></html:div>
<html:input class="plain event-name-input"
hidden="hidden"
placeholder='${cal.l10n.getCalString("newEvent")}'/>
data-l10n-id="new-event"/>
<html:div class="alarm-icons-box"></html:div>
<html:img class="item-classification-icon" />
<html:img class="item-recurrence-icon" />
@ -3056,14 +3062,14 @@
dayCol.date.makeImmutable();
/* Set up day of the week headings. */
dayCol.shortHeading.textContent = cal.l10n.getCalString("dayHeaderLabel", [
dateFormatter.shortDayName(dayDate.weekday),
dateFormatter.formatDateWithoutYear(dayDate),
]);
dayCol.longHeading.textContent = cal.l10n.getCalString("dayHeaderLabel", [
dateFormatter.dayName(dayDate.weekday),
dateFormatter.formatDateWithoutYear(dayDate),
]);
document.l10n.setAttributes(dayCol.shortHeading, "day-header", {
dayName: dateFormatter.shortDayName(dayDate.weekday),
dayIndex: dateFormatter.formatDateWithoutYear(dayDate),
});
document.l10n.setAttributes(dayCol.longHeading, "day-header", {
dayName: dateFormatter.dayName(dayDate.weekday),
dayIndex: dateFormatter.formatDateWithoutYear(dayDate),
});
/* Set up all-day header. */
dayCol.header.date = dayDate;

Просмотреть файл

@ -77,7 +77,7 @@ const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtil
for (let i = 0; i < 12; i++) {
const option = document.createElement("option");
option.value = i;
option.label = cal.l10n.formatMonth(i + 1, "calendar", "monthInYear");
option.label = cal.l10n.formatMonth(i + 1, "calendar", "month-in-year");
fromMonth.appendChild(option.cloneNode(false));
toMonth.appendChild(option);
}

Просмотреть файл

@ -36,8 +36,18 @@ var gCalendarStatusFeedback = {
}
},
showStatusString(status) {
this.mStatusText.setAttribute("label", status);
/**
* @param {string} status - Fluent string ID to show in the status bar. An
* empty string clears the status bar.
* @param {?object} args - Arguments to pass to the fluent string.
*/
showStatusString(status, args) {
if (status) {
document.l10n.setAttributes(this.mStatusText, status, args);
} else {
delete this.mStatusText.dataset.l10nId;
this.mStatusText.setAttribute("label", "");
}
},
get spinning() {
@ -60,8 +70,7 @@ var gCalendarStatusFeedback = {
this.mStatusProgressPanel.removeAttribute("collapsed");
if (this.mProgressMode == Ci.calIStatusObserver.DETERMINED_PROGRESS) {
this.mStatusBar.value = 0;
const commonStatus = cal.l10n.getCalString("gettingCalendarInfoCommon");
this.showStatusString(commonStatus);
this.showStatusString("getting-calendar-info-common");
}
if (this.mThrobber) {
this.mThrobber.setAttribute("busy", true);
@ -95,11 +104,10 @@ var gCalendarStatusFeedback = {
this.mCalendars[aCalendar.id] = true;
this.mStatusBar.value = parseInt(this.mStatusBar.value, 10) + this.mCalendarStep;
this.mCurIndex++;
const curStatus = cal.l10n.getCalString("gettingCalendarInfoDetail", [
this.mCurIndex,
this.mCalendarCount,
]);
this.showStatusString(curStatus);
this.showStatusString("getting-calendar-info-detail", {
index: this.mCurIndex,
total: this.mCalendarCount,
});
}
}
if (this.mThrobber) {

Просмотреть файл

@ -71,6 +71,11 @@ var calendarTabMonitor = {
},
};
ChromeUtils.defineLazyGetter(
calendarTabMonitor,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
var calendarTabType = {
name: "calendar",
panelId: "calendarTabPanel",
@ -206,16 +211,16 @@ var calendarItemTabType = {
// Generate and set the tab title.
let strName;
if (aTab.mode.type == "calendarEvent") {
strName = aArgs.calendarEvent.title ? "editEventDialog" : "newEventDialog";
strName = aArgs.calendarEvent.title ? "edit-event-dialog" : "new-event-dialog";
aTab.tabNode.setIcon("chrome://messenger/skin/icons/new/compact/calendar.svg");
} else if (aTab.mode.type == "calendarTask") {
strName = aArgs.calendarEvent.title ? "editTaskDialog" : "newTaskDialog";
strName = aArgs.calendarEvent.title ? "edit-task-dialog" : "new-task-dialog";
aTab.tabNode.setIcon("chrome://messenger/skin/icons/new/compact/tasks.svg");
} else {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
// name is "New Event", "Edit Task", etc.
const name = cal.l10n.getCalString(strName);
const name = calendarTabMonitor.l10n.formatValueSync(strName);
aTab.title = name + ": " + (aArgs.calendarEvent.title || name);
// allowTabClose prevents the tab from being closed until we ask

Просмотреть файл

@ -297,7 +297,9 @@ class CalendarTaskTreeView {
switch (property) {
case "title":
// Return title, or "Untitled" if empty/null.
return task.title ? task.title.replace(/\n/g, " ") : cal.l10n.getCalString("eventUntitled");
return task.title
? task.title.replace(/\n/g, " ")
: CalendarTaskTreeView.l10n.formatValueSync("event-untitled");
case "entryDate":
case "dueDate":
case "completedDate":
@ -490,3 +492,9 @@ class CalendarTaskTreeView {
: "";
}
}
ChromeUtils.defineLazyGetter(
CalendarTaskTreeView,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);

Просмотреть файл

@ -8,7 +8,14 @@
// Wrap in a block to prevent leaking to window scope.
{
const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
const { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
if (!lazy) {
var lazy = {};
}
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
/**
* An observer for the calendar event data source. This keeps the unifinder
@ -435,18 +442,13 @@
// { weeks: 1, days: 0 }
// { weeks: 0, days: 8 }
const days = dur.days + dur.weeks * 7;
return (
prefix + PluralForm.get(days, cal.l10n.getCalString("dueInDays")).replace("#1", days)
);
return prefix + lazy.l10n.formatValueSync("due-in-days", { count: days });
} else if (absMinutes >= 60) {
// 1 hour or more.
return (
prefix +
PluralForm.get(dur.hours, cal.l10n.getCalString("dueInHours")).replace("#1", dur.hours)
);
return prefix + lazy.l10n.formatValueSync("due-in-hours", { count: dur.hours });
}
// Less than one hour.
return cal.l10n.getCalString("dueInLessThanOneHour");
return lazy.l10n.formatValueSync("due-in-less-than-one-hour");
}
/**
@ -581,7 +583,7 @@
}
getInitialDate() {
return currentView().selectedDay || cal.dtz.now();
return this.selectedDay || cal.dtz.now();
}
doUpdateFilter(filter) {

Просмотреть файл

@ -10,6 +10,7 @@
/* import-globals-from calendar-ui-utils.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { recurrenceRule2String } = ChromeUtils.importESModule(
"resource:///modules/calendar/calRecurrenceUtils.sys.mjs"
);
@ -86,7 +87,7 @@ var taskDetailsView = {
const statusDetails = document.getElementById("calendar-task-details-status");
switch (status) {
case "NEEDS-ACTION": {
statusDetails.textContent = cal.l10n.getCalString("taskDetailsStatusNeedsAction");
document.l10n.setAttributes(statusDetails, "task-details-status-needs-action");
break;
}
case "IN-PROCESS": {
@ -95,22 +96,22 @@ var taskDetailsView = {
if (property != null) {
percent = parseInt(property, 10);
}
statusDetails.textContent = cal.l10n.getCalString("taskDetailsStatusInProgress", [
document.l10n.setAttributes(statusDetails, "task-details-status-in-progress", {
percent,
]);
});
break;
}
case "COMPLETED": {
if (item.completedDate) {
const completedDate = item.completedDate.getInTimezone(cal.dtz.defaultTimezone);
statusDetails.textContent = cal.l10n.getCalString("taskDetailsStatusCompletedOn", [
dateFormatter.formatDateTime(completedDate),
]);
document.l10n.setAttributes(statusDetails, "task-details-status-completed-on", {
datetime: dateFormatter.formatDateTime(completedDate),
});
}
break;
}
case "CANCELLED": {
statusDetails.textContent = cal.l10n.getCalString("taskDetailsStatusCancelled");
document.l10n.setAttributes(statusDetails, "task-details-status-cancelled");
break;
}
default: {
@ -235,7 +236,7 @@ var taskDetailsView = {
if (maxCount == 1) {
const menuitem = document.createXULElement("menuitem");
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("label", cal.l10n.getCalString("None"));
document.l10n.setAttributes(menuitem, "calendar-none");
menuitem.setAttribute("type", "radio");
if (itemCategories.length === 0) {
menuitem.setAttribute("checked", "true");

Просмотреть файл

@ -15,8 +15,9 @@
/* import-globals-from ../../../mail/base/content/utilityOverlay.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* This function unconditionally disables the element for
@ -197,15 +198,16 @@ function addMenuItem(aParent, aLabel, aValue, aCommand) {
function unitPluralForm(aLength, aUnit, aIncludeLength = true) {
const unitProp =
{
minutes: "unitMinutes",
hours: "unitHours",
days: "unitDays",
weeks: "unitWeeks",
}[aUnit] || "unitMinutes";
return PluralForm.get(aLength, cal.l10n.getCalString(unitProp))
.replace("#1", aIncludeLength ? aLength : "")
.trim();
minutes: "unit-minutes",
hours: "unit-hours",
days: "unit-days",
weeks: "unit-weeks",
}[aUnit] || "unit-minutes";
const unitString = lazy.l10n.formatValueSync(unitProp, { count: aLength });
if (aIncludeLength) {
return unitString;
}
return unitString.replace(aLength, "").trim();
}
/**

Просмотреть файл

@ -589,17 +589,14 @@ var calendarNavigationBar = {
secondWeekNo = cal.weekInfoService.getWeekTitle(endDate);
}
if (secondWeekNo == firstWeekNo) {
weekLabel.textContent = cal.l10n.getCalString("singleShortCalendarWeek", [firstWeekNo]);
weekLabel.tooltipText = cal.l10n.getCalString("singleLongCalendarWeek", [firstWeekNo]);
document.l10n.setAttributes(weekLabel, "single-calendar-week", {
index: firstWeekNo,
});
} else {
weekLabel.textContent = cal.l10n.getCalString("severalShortCalendarWeeks", [
firstWeekNo,
secondWeekNo,
]);
weekLabel.tooltipText = cal.l10n.getCalString("severalLongCalendarWeeks", [
firstWeekNo,
secondWeekNo,
]);
document.l10n.setAttributes(weekLabel, "several-calendar-weeks", {
startIndex: firstWeekNo,
endIndex: secondWeekNo,
});
}
docTitle = intervalLabel.textContent;
}

Просмотреть файл

@ -19,6 +19,12 @@
// Wrap in a block to prevent leaking to window scope.
{
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
/**
* The calendar view for viewing a single day.
@ -235,10 +241,13 @@
const monthName = cal.l10n.formatMonth(
this.rangeStartDate.month + 1,
"calendar",
"monthInYear"
"month-in-year"
);
return cal.l10n.getCalString("monthInYear", [monthName, this.rangeStartDate.year]);
return lazy.l10n.formatValueSync("month-in-year", {
month: monthName,
year: this.rangeStartDate.year,
});
}
moveView(number) {

Просмотреть файл

@ -10,9 +10,14 @@
/* import-globals-from ../item-editing/calendar-item-editing.js */
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl", "calendar/calendar-alarms.ftl"], true)
);
window.addEventListener("load", () => {
setupWindow();
@ -291,8 +296,8 @@ function aboveSnoozeLimit(aDuration) {
const durationUntilLimit = limitTime.subtractDate(currentTime);
if (aDuration.compare(durationUntilLimit) > 0) {
const msg = PluralForm.get(LIMIT, cal.l10n.getCalString("alarmSnoozeLimitExceeded"));
cal.showError(msg.replace("#1", LIMIT), window);
const msg = lazy.l10n.formatValueSync("alarm-snooze-limit-exceeded", { count: LIMIT });
cal.showError(msg, window);
return true;
}
return false;
@ -305,8 +310,7 @@ function setupTitle() {
const alarmRichlist = document.getElementById("alarm-richlist");
const reminders = alarmRichlist.children.length;
const title = PluralForm.get(reminders, cal.l10n.getCalString("alarmWindowTitle.label"));
document.title = title.replace("#1", reminders);
document.title = lazy.l10n.formatValueSync("alarm-window-title-label", { count: reminders });
}
/**
@ -426,7 +430,7 @@ async function doReadOnlyChecks() {
const snoozeAllButton = document.getElementById("alarm-snooze-all-button");
snoozeAllButton.disabled = countRO && countRO == alarmRichlist.children.length;
if (snoozeAllButton.disabled) {
const tooltip = cal.l10n.getString("calendar-alarms", "reminderDisabledSnoozeButtonTooltip");
const tooltip = lazy.l10n.formatValueSync("reminder-disabled-snooze-button-tooltip");
snoozeAllButton.setAttribute("tooltiptext", tooltip);
} else {
snoozeAllButton.removeAttribute("tooltiptext");
@ -434,13 +438,13 @@ async function doReadOnlyChecks() {
const notification = gReadOnlyNotification.getNotificationWithValue("calendar-readonly");
if (countRO && !notification) {
const message = cal.l10n.getString("calendar-alarms", "reminderReadonlyNotification", [
snoozeAllButton.label,
]);
await gReadOnlyNotification.appendNotification(
"calendar-readonly",
{
label: message,
label: {
"l10n-id": "reminder-readonly-notification",
"l10n-args": { label: snoozeAllButton.label },
},
priority: gReadOnlyNotification.PRIORITY_WARNING_MEDIUM,
},
null

Просмотреть файл

@ -25,6 +25,8 @@
<link rel="stylesheet" href="chrome://messenger/skin/colors.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="stylesheet" href="chrome://calendar/skin/calendar-alarm-dialog.css" />
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-alarms.ftl" />
<script defer="defer" src="chrome://calendar/content/calendar-item-editing.js"></script>
<script defer="defer" src="chrome://calendar/content/widgets/calendar-alarm-widget.js"></script>
<script defer="defer" src="chrome://calendar/content/calApplicationUtils.js"></script>

Просмотреть файл

@ -5,7 +5,8 @@
/* globals getPreviewForItem */ // From mouseoverPreviews.js
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
window.addEventListener("DOMContentLoaded", onLoad);
function onLoad() {
@ -18,20 +19,16 @@ function onLoad() {
const descr = document.getElementById("conflicts-description");
// TODO These strings should move to Fluent.
// For that matter, this dialog should be reworked!
document.title = cal.l10n.getCalString("itemModifiedOnServerTitle");
descr.textContent = cal.l10n.getCalString("itemModifiedOnServer");
// TODO This dialog should be reworked!
descr.textContent = lazy.l10n.formatValueSync("item-modified-on-server");
if (window.arguments[0].mode == "modify") {
descr.textContent += cal.l10n.getCalString("modifyWillLoseData");
dialog.getButton("accept").setAttribute("label", cal.l10n.getCalString("proceedModify"));
descr.textContent += lazy.l10n.formatValueSync("modify-will-lose-data");
document.l10n.setAttributes(dialog.getButton("accept"), "proceed-modify");
} else {
descr.textContent += cal.l10n.getCalString("deleteWillLoseData");
dialog.getButton("accept").setAttribute("label", cal.l10n.getCalString("proceedDelete"));
descr.textContent += lazy.l10n.formatValueSync("delete-will-lose-data");
document.l10n.setAttributes(dialog.getButton("accept"), "proceed-delete");
}
dialog.getButton("cancel").setAttribute("label", cal.l10n.getCalString("updateFromServer"));
}
document.addEventListener("dialogaccept", () => {

Просмотреть файл

@ -20,12 +20,14 @@
<link rel="stylesheet" href="chrome://messenger/skin/colors.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="localization" href="branding/brand.ftl" />
<link rel="localization" href="calendar/calendar.ftl" />
<script defer="defer" src="chrome://calendar/content/widgets/mouseoverPreviews.js"></script>
<script defer="defer" src="chrome://messenger/content/dialogShadowDom.js"></script>
<script defer="defer" src="chrome://calendar/content/calendar-conflicts-dialog.js"></script>
<title data-l10n-id="item-modified-on-server-title"></title>
</head>
<body>
<xul:dialog>
<xul:dialog data-l10n-attrs="buttonlabelcancel" data-l10n-id="calendar-conflicts-dialog">
<div id="conflicts-vbox">
<div id="item-box"></div>
</div>

Просмотреть файл

@ -9,7 +9,16 @@ var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.
var { MailServices } = ChromeUtils.importESModule("resource:///modules/MailServices.sys.mjs");
var { MailUtils } = ChromeUtils.importESModule("resource:///modules/MailUtils.sys.mjs");
var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() =>
new Localization(
["calendar/calendar.ftl", "calendar/calendar-event-dialog-attendees.ftl"],
true
)
);
ChromeUtils.defineESModuleGetters(this, {
CalAttendee: "resource:///modules/CalAttendee.sys.mjs",
});
@ -791,7 +800,11 @@ function checkDate() {
} else {
// Don't allow for negative durations.
const callback = function () {
Services.prompt.alert(null, document.title, cal.l10n.getCalString("warningEndBeforeStart"));
Services.prompt.alert(
null,
document.title,
lazy.l10n.formatValueSync("warning-end-before-start")
);
};
setTimeout(callback, 1);
dateTimePickerUI.endValue = previousEndTime;
@ -1422,28 +1435,22 @@ function updateRange() {
#updateRoleIcon() {
const role = this.#attendee.role ?? EventAttendee.#DEFAULT_ROLE;
const roleValueToStringKeyMap = {
"REQ-PARTICIPANT": "event.attendee.role.required",
"OPT-PARTICIPANT": "event.attendee.role.optional",
"NON-PARTICIPANT": "event.attendee.role.nonparticipant",
CHAIR: "event.attendee.role.chair",
"REQ-PARTICIPANT": "event-attendee-role-required",
"OPT-PARTICIPANT": "event-attendee-role-optional",
"NON-PARTICIPANT": "event-attendee-role-nonparticipant",
CHAIR: "event-attendee-role-chair",
};
let tooltip;
let tooltipArgs = undefined;
if (role in roleValueToStringKeyMap) {
tooltip = cal.l10n.getString(
"calendar-event-dialog-attendees",
roleValueToStringKeyMap[role]
);
tooltip = roleValueToStringKeyMap[role];
} else {
tooltip = cal.l10n.getString(
"calendar-event-dialog-attendees",
"event.attendee.role.unknown",
[role]
);
tooltip = "event-attendee-role-unknown";
tooltipArgs = { role };
}
this.#roleIcon.setAttribute("attendeerole", role);
this.#roleIcon.setAttribute("title", tooltip);
document.l10n.setAttributes(this.#roleIcon, tooltip, tooltipArgs);
}
/**
@ -1453,29 +1460,23 @@ function updateRange() {
#updateUserTypeIcon() {
const userType = this.#attendee.userType ?? EventAttendee.#DEFAULT_USER_TYPE;
const userTypeValueToStringKeyMap = {
INDIVIDUAL: "event.attendee.usertype.individual",
GROUP: "event.attendee.usertype.group",
RESOURCE: "event.attendee.usertype.resource",
ROOM: "event.attendee.usertype.room",
INDIVIDUAL: "event-attendee-usertype-individual",
GROUP: "event-attendee-usertype-group",
RESOURCE: "event-attendee-usertype-resource",
ROOM: "event-attendee-usertype-room",
// UNKNOWN and any unrecognized user types are handled below.
};
let tooltip;
let tooltipArgs = undefined;
if (userType in userTypeValueToStringKeyMap) {
tooltip = cal.l10n.getString(
"calendar-event-dialog-attendees",
userTypeValueToStringKeyMap[userType]
);
tooltip = userTypeValueToStringKeyMap[userType];
} else {
tooltip = cal.l10n.getString(
"calendar-event-dialog-attendees",
"event.attendee.usertype.unknown",
[userType]
);
tooltip = "event-attendee-usertype-unknown";
tooltipArgs = { userType };
}
this.#userTypeIcon.setAttribute("usertype", userType);
this.#userTypeIcon.setAttribute("title", tooltip);
document.l10n.setAttributes(this.#userTypeIcon, tooltip, tooltipArgs);
}
}
customElements.define("event-attendee", EventAttendee);

Просмотреть файл

@ -32,6 +32,8 @@
<link rel="stylesheet" href="chrome://calendar/skin/shared/datetimepickers.css" />
<link rel="stylesheet" href="chrome://messenger/skin/shared/input-fields.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-event-dialog-attendees.ftl" />
<script defer="defer" src="chrome://messenger/content/globalOverlay.js"></script>
<script defer="defer" src="chrome://global/content/editMenuOverlay.js"></script>
<script defer="defer" src="chrome://messenger/content/dialogShadowDom.js"></script>

Просмотреть файл

@ -11,7 +11,8 @@ var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUti
ChromeUtils.defineESModuleGetters(this, {
CalRecurrenceInfo: "resource:///modules/CalRecurrenceInfo.sys.mjs",
});
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
var gIsReadOnly = false;
var gStartTime = null;
var gEndTime = null;
@ -1043,7 +1044,7 @@ function checkUntilDate() {
Services.prompt.alert(
null,
document.title,
cal.l10n.getCalString("warningUntilDateBeforeStart")
lazy.l10n.formatValueSync("warning-until-date-before-start")
);
checkUntilDate.warning = false;
};

Просмотреть файл

@ -27,7 +27,7 @@
<link rel="stylesheet" href="chrome://messenger/skin/contextMenu.css" />
<link rel="stylesheet" href="chrome://messenger/skin/input-fields.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-recurrence-dialog.ftl" />
<script defer="defer" src="chrome://messenger/content/dialogShadowDom.js"></script>
<script defer="defer" src="chrome://calendar/content/calendar-dialog-utils.js"></script>

Просмотреть файл

@ -6,10 +6,8 @@
/* import-globals-from ../calendar-ui-utils.js */
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
ChromeUtils.defineESModuleGetters(this, {
CalAlarm: "resource:///modules/CalAlarm.sys.mjs",
});
@ -22,6 +20,11 @@ ChromeUtils.defineLazyGetter(this, "gReminderNotification", () => {
document.getElementById("reminder-notifications").append(element);
});
});
ChromeUtils.defineLazyGetter(
this,
"l10n",
() => new Localization(["calendar/calendar-alarms.ftl"], true)
);
window.addEventListener("load", onLoad);
@ -33,24 +36,25 @@ function onLoad() {
// Make sure the origin menulist uses the right labels, depending on if the
// dialog is showing an event or task.
function _sn(x) {
return cal.l10n.getString("calendar-alarms", getItemBundleStringName(x));
}
document.getElementById("reminder-before-start-menuitem").label = _sn(
"reminderCustomOriginBeginBefore"
document.l10n.setAttributes(
document.getElementById("reminder-before-start-menuitem"),
getItemBundleStringName("reminder-custom-origin-begin-before")
);
document.getElementById("reminder-after-start-menuitem").label = _sn(
"reminderCustomOriginBeginAfter"
document.l10n.setAttributes(
document.getElementById("reminder-after-start-menuitem"),
getItemBundleStringName("reminder-custom-origin-begin-after")
);
document.getElementById("reminder-before-end-menuitem").label = _sn(
"reminderCustomOriginEndBefore"
document.l10n.setAttributes(
document.getElementById("reminder-before-end-menuitem"),
getItemBundleStringName("reminder-custom-origin-end-before")
);
document.getElementById("reminder-after-end-menuitem").label = _sn(
"reminderCustomOriginEndAfter"
document.l10n.setAttributes(
document.getElementById("reminder-after-end-menuitem"),
getItemBundleStringName("reminder-custom-origin-end-after")
);
// Set up the action map
@ -177,21 +181,20 @@ async function setupMaxReminders() {
// disable the new button.
document.getElementById("reminder-new-button").disabled = hitMaxReminders;
const localeErrorString = cal.l10n.getString(
"calendar-alarms",
getItemBundleStringName("reminderErrorMaxCountReached"),
[maxReminders]
);
const pluralErrorLabel = PluralForm.get(maxReminders, localeErrorString).replace(
"#1",
maxReminders
);
// const localeErrorString = this.l10n.formatValueSync("reminder-error-max-count-reached", {
// count: maxReminders,
// });
if (hitMaxReminders) {
const notification = await gReminderNotification.appendNotification(
"reminderNotification",
{
label: pluralErrorLabel,
label: {
"l10n-id": "reminder-error-max-count-reached",
"l10n-args": {
count: maxReminders,
},
},
priority: gReminderNotification.PRIORITY_WARNING_MEDIUM,
},
null
@ -409,9 +412,9 @@ function updateReminder(event) {
*/
function getItemBundleStringName(aPrefix) {
if (window.arguments[0].item.isEvent()) {
return aPrefix + "Event";
return `${aPrefix}-event`;
}
return aPrefix + "Task";
return `${aPrefix}-task`;
}
/**

Просмотреть файл

@ -6,35 +6,35 @@
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
// Wrap in a block to prevent leaking to window scope.
{
class MozCalendarInvitationsRichlistitem extends MozElements.MozRichlistitem {
constructor() {
super();
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar-invitations-dialog.ftl"], true)
);
// Wrap in a block to prevent leaking to window scope.
{
class MozCalendarInvitationsRichlistitem extends MozElements.MozRichlistitem {
constructor() {
super();
this.mCalendarItem = null;
this.mInitialParticipationStatus = null;
this.mParticipationStatus = null;
this.calInvitationsProps = Services.strings.createBundle(
"chrome://calendar/locale/calendar-invitations-dialog.properties"
);
}
getString(propName) {
return this.calInvitationsProps.GetStringFromName(propName);
}
connectedCallback() {
if (this.delayConnectedCallback() || this.hasChildNodes()) {
return;
this.mCalendarItem = null;
this.mInitialParticipationStatus = null;
this.mParticipationStatus = null;
}
this.setAttribute("is", "calendar-invitations-richlistitem");
this.classList.add("calendar-invitations-richlistitem");
connectedCallback() {
if (this.delayConnectedCallback() || this.hasChildNodes()) {
return;
}
this.appendChild(
MozXULElement.parseXULToFragment(
`
this.setAttribute("is", "calendar-invitations-richlistitem");
this.classList.add("calendar-invitations-richlistitem");
this.appendChild(
MozXULElement.parseXULToFragment(
`
<hbox align="start" flex="1">
<!-- Note: The wrapper div is only here because the XUL box does not
- properly crop img elements with CSS object-fit and
@ -69,142 +69,141 @@ var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.
</vbox>
</hbox>
`,
["chrome://calendar/locale/calendar-invitations-dialog.dtd"]
)
);
}
set calendarItem(val) {
this.setCalendarItem(val);
}
get calendarItem() {
return this.mCalendarItem;
}
set initialParticipationStatus(val) {
this.mInitialParticipationStatus = val;
}
get initialParticipationStatus() {
return this.mInitialParticipationStatus;
}
set participationStatus(val) {
this.mParticipationStatus = val;
const icon = this.querySelector(".calendar-invitations-richlistitem-icon");
// Status attribute changes the image region in CSS.
icon.setAttribute("status", val);
document.l10n.setAttributes(
icon,
`calendar-invitation-current-participation-status-icon-${val.toLowerCase()}`
);
}
get participationStatus() {
return this.mParticipationStatus;
}
setCalendarItem(item) {
this.mCalendarItem = item;
this.mInitialParticipationStatus = this.getCalendarItemParticipationStatus(item);
this.participationStatus = this.mInitialParticipationStatus;
const titleLabel = this.querySelector(".calendar-invitations-richlistitem-title");
titleLabel.setAttribute("value", item.title);
const dateLabel = this.querySelector(".calendar-invitations-richlistitem-date");
let dateString = cal.dtz.formatter.formatItemInterval(item);
if (item.startDate.isDate) {
dateString += ", " + this.getString("allday-event");
}
dateLabel.setAttribute("value", dateString);
const recurrenceLabel = this.querySelector(".calendar-invitations-richlistitem-recurrence");
if (item.recurrenceInfo) {
recurrenceLabel.setAttribute("value", this.getString("recurrent-event"));
} else {
recurrenceLabel.setAttribute("hidden", "true");
const spacer = this.querySelector(".calendar-invitations-richlistitem-spacer");
spacer.removeAttribute("hidden");
["chrome://calendar/locale/calendar-invitations-dialog.dtd"]
)
);
}
const locationLabel = this.querySelector(".calendar-invitations-richlistitem-location");
const locationProperty = item.getProperty("LOCATION") || this.getString("none");
const locationString = this.calInvitationsProps.formatStringFromName("location", [
locationProperty,
]);
set calendarItem(val) {
this.setCalendarItem(val);
}
locationLabel.setAttribute("value", locationString);
get calendarItem() {
return this.mCalendarItem;
}
const organizerLabel = this.querySelector(".calendar-invitations-richlistitem-organizer");
const org = item.organizer;
let organizerProperty = "";
if (org) {
if (org.commonName && org.commonName.length > 0) {
organizerProperty = org.commonName;
} else if (org.id) {
organizerProperty = org.id.replace(/^mailto:/i, "");
set initialParticipationStatus(val) {
this.mInitialParticipationStatus = val;
}
get initialParticipationStatus() {
return this.mInitialParticipationStatus;
}
set participationStatus(val) {
this.mParticipationStatus = val;
const icon = this.querySelector(".calendar-invitations-richlistitem-icon");
// Status attribute changes the image region in CSS.
icon.setAttribute("status", val);
document.l10n.setAttributes(
icon,
`calendar-invitation-current-participation-status-icon-${val.toLowerCase()}`
);
}
get participationStatus() {
return this.mParticipationStatus;
}
setCalendarItem(item) {
this.mCalendarItem = item;
this.mInitialParticipationStatus = this.getCalendarItemParticipationStatus(item);
this.participationStatus = this.mInitialParticipationStatus;
const titleLabel = this.querySelector(".calendar-invitations-richlistitem-title");
titleLabel.setAttribute("value", item.title);
const dateLabel = this.querySelector(".calendar-invitations-richlistitem-date");
let dateString = cal.dtz.formatter.formatItemInterval(item);
if (item.startDate.isDate) {
dateString += ", " + lazy.l10n.formatValueSync("allday-event");
}
}
const organizerString = this.calInvitationsProps.formatStringFromName("organizer", [
organizerProperty,
]);
organizerLabel.setAttribute("value", organizerString);
dateLabel.setAttribute("value", dateString);
const attendeeLabel = this.querySelector(".calendar-invitations-richlistitem-attendee");
const att = cal.itip.getInvitedAttendee(item);
let attendeeProperty = "";
if (att) {
if (att.commonName && att.commonName.length > 0) {
attendeeProperty = att.commonName;
} else if (att.id) {
attendeeProperty = att.id.replace(/^mailto:/i, "");
const recurrenceLabel = this.querySelector(".calendar-invitations-richlistitem-recurrence");
if (item.recurrenceInfo) {
document.l10n.setAttributes(recurrenceLabel, "recurrent-event");
} else {
recurrenceLabel.setAttribute("hidden", "true");
const spacer = this.querySelector(".calendar-invitations-richlistitem-spacer");
spacer.removeAttribute("hidden");
}
}
const attendeeString = this.calInvitationsProps.formatStringFromName("attendee", [
attendeeProperty,
]);
attendeeLabel.setAttribute("value", attendeeString);
Array.from(this.querySelectorAll("button")).map(button =>
button.setAttribute("group", item.hashId)
);
}
getCalendarItemParticipationStatus(item) {
const att = cal.itip.getInvitedAttendee(item);
return att ? att.participationStatus : null;
}
const locationLabel = this.querySelector(".calendar-invitations-richlistitem-location");
const locationProperty =
item.getProperty("LOCATION") || lazy.l10n.formatValueSync("calendar-invitations-none");
setCalendarItemParticipationStatus(item, status) {
if (item.calendar?.supportsScheduling) {
const att = item.calendar.getSchedulingSupport().getInvitedAttendee(item);
document.l10n.setAttributes(locationLabel, "calendar-invitations-location", {
locationProperty,
});
const organizerLabel = this.querySelector(".calendar-invitations-richlistitem-organizer");
const org = item.organizer;
let organizerProperty = "";
if (org) {
if (org.commonName && org.commonName.length > 0) {
organizerProperty = org.commonName;
} else if (org.id) {
organizerProperty = org.id.replace(/^mailto:/i, "");
}
}
document.l10n.setAttributes(organizerLabel, "organizer", {
organizerProperty,
});
const attendeeLabel = this.querySelector(".calendar-invitations-richlistitem-attendee");
const att = cal.itip.getInvitedAttendee(item);
let attendeeProperty = "";
if (att) {
const att_ = att.clone();
att_.participationStatus = status;
// Update attendee
item.removeAttendee(att);
item.addAttendee(att_);
return true;
if (att.commonName && att.commonName.length > 0) {
attendeeProperty = att.commonName;
} else if (att.id) {
attendeeProperty = att.id.replace(/^mailto:/i, "");
}
}
document.l10n.setAttributes(attendeeLabel, "calendar-invitations-attendee", {
attendeeProperty,
});
Array.from(this.querySelectorAll("button")).map(button =>
button.setAttribute("group", item.hashId)
);
}
getCalendarItemParticipationStatus(item) {
const att = cal.itip.getInvitedAttendee(item);
return att ? att.participationStatus : null;
}
setCalendarItemParticipationStatus(item, status) {
if (item.calendar?.supportsScheduling) {
const att = item.calendar.getSchedulingSupport().getInvitedAttendee(item);
if (att) {
const att_ = att.clone();
att_.participationStatus = status;
// Update attendee
item.removeAttendee(att);
item.addAttendee(att_);
return true;
}
}
return false;
}
accept() {
this.participationStatus = "ACCEPTED";
}
decline() {
this.participationStatus = "DECLINED";
}
return false;
}
accept() {
this.participationStatus = "ACCEPTED";
}
decline() {
this.participationStatus = "DECLINED";
}
customElements.define("calendar-invitations-richlistitem", MozCalendarInvitationsRichlistitem, {
extends: "richlistitem",
});
}
customElements.define("calendar-invitations-richlistitem", MozCalendarInvitationsRichlistitem, {
extends: "richlistitem",
});
}
window.addEventListener("DOMContentLoaded", onLoad);
window.addEventListener("unload", onUnload);

Просмотреть файл

@ -14,10 +14,6 @@ function exitOccurrenceDialog(aReturnValue) {
window.close();
}
function getDString(aKey) {
return cal.l10n.getString("calendar-occurrence-prompt", aKey);
}
function onLoad() {
const action = window.arguments[0].action || "edit";
// the calling code prevents sending no items
@ -31,17 +27,22 @@ function onLoad() {
}
// Set up title and type label
document.title = getDString(`windowtitle.${itemType}.${action}`);
document.l10n.setAttributes(
document.head.querySelector("title"),
`windowtitle-${itemType}-${action}`
);
const title = document.getElementById("title-label");
if (multiple == "multiple") {
title.value = getDString("windowtitle.multipleitems");
document.getElementById("isrepeating-label").value = getDString(
`header.containsrepeating.${itemType}.label`
document.l10n.setAttributes(title, "windowtitle-multipleitems");
document.l10n.setAttributes(
document.getElementById("isrepeating-label"),
`header-containsrepeating-${itemType}`
);
} else {
title.value = window.arguments[0].items[0].title;
document.getElementById("isrepeating-label").value = getDString(
`header.isrepeating.${itemType}.label`
document.l10n.setAttributes(
document.getElementById("isrepeating-label"),
`header-isrepeating-${itemType}`
);
}
@ -49,14 +50,16 @@ function onLoad() {
document.getElementById("accept-buttons-box").setAttribute("action", action);
document.getElementById("accept-buttons-box").setAttribute("type", itemType);
document.getElementById("accept-occurrence-button").label = getDString(
`buttons.${multiple}.occurrence.${action}.label`
document.l10n.setAttributes(
document.getElementById("accept-occurrence-button"),
`buttons-${multiple}-occurrence-${action}`
);
document.getElementById("accept-allfollowing-button").label = getDString(
`buttons.${multiple}.allfollowing.${action}.label`
document.l10n.setAttributes(
document.getElementById("accept-allfollowing-button"),
`buttons-${multiple}-allfollowing-${action}`
);
document.getElementById("accept-parent-button").label = getDString(
`buttons.${multiple}.parent.${action}.label`
document.l10n.setAttributes(
document.getElementById("accept-parent-button"),
`buttons-${multiple}-parent-${action}`
);
}

Просмотреть файл

@ -18,6 +18,8 @@
<link rel="stylesheet" href="chrome://messenger/skin/colors.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="stylesheet" href="chrome://calendar/skin/shared/calendar-occurrence-prompt.css" />
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-occurence-prompt.ftl" />
<script defer="defer" src="chrome://messenger/content/dialogShadowDom.js"></script>
<script defer="defer" src="chrome://calendar/content/calendar-occurrence-prompt.js"></script>
</head>

Просмотреть файл

@ -9,8 +9,6 @@
/* import-globals-from calendar-identity-utils.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
/**
* The calendar to modify, is retrieved from window.arguments[0].calendar
*/
@ -199,9 +197,9 @@ function initRefreshInterval() {
const menuitem = document.createXULElement("menuitem");
menuitem.setAttribute("value", minutes);
const everyMinuteString = cal.l10n.getCalString("calendarPropertiesEveryMinute");
const label = PluralForm.get(minutes, everyMinuteString).replace("#1", minutes);
menuitem.setAttribute("label", label);
document.l10n.setAttributes(menuitem, "calendar-properties-every-minute", {
count: minutes,
});
return menuitem;
}

Просмотреть файл

@ -30,6 +30,7 @@
<link rel="stylesheet" href="chrome://messenger/skin/colors.css" />
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="stylesheet" href="chrome://calendar/skin/shared/calendar-properties-dialog.css" />
<link rel="localization" href="calendar/calendar-alarms.ftl" />
<script defer="defer" src="chrome://messenger/content/globalOverlay.js"></script>
<script defer="defer" src="chrome://global/content/editMenuOverlay.js"></script>
<script defer="defer" src="chrome://messenger/content/dialogShadowDom.js"></script>

Просмотреть файл

@ -5,6 +5,7 @@
/* import-globals-from item-editing/calendar-item-editing.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/* exported getItemsFromIcsFile, putItemsIntoCal, exportEntireCalendar */
@ -36,10 +37,10 @@ function getItemsFromIcsFile(file) {
exception = ex;
switch (ex.result) {
case Ci.calIErrors.INVALID_TIMEZONE:
cal.showError(cal.l10n.getCalString("timezoneError", [file.path]), window);
cal.showError(lazy.l10n.formatValueSync("timezone-error", { filePath: file.path }), window);
break;
default:
cal.showError(cal.l10n.getCalString("unableToRead") + file.path + "\n" + ex, window);
cal.showError(lazy.l10n.formatValueSync("unable-to-read") + file.path + "\n" + ex, window);
}
} finally {
inputStream.close();
@ -48,7 +49,10 @@ function getItemsFromIcsFile(file) {
if (!items.length && !exception) {
// The ics did not contain any events, so we should
// notify the user about it, if we haven't before.
cal.showError(cal.l10n.getCalString("noItemsInCalendarFile2", [file.path]), window);
cal.showError(
lazy.l10n.formatValueSync("no-items-in-calendar-file2", { filePath: file.path }),
window
);
}
return items;
@ -139,7 +143,7 @@ function saveEventsToFile(calendarEventArray, aDefaultFileName) {
const picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
picker.init(
window.browsingContext,
cal.l10n.getCalString("filepickerTitleExport"),
lazy.l10n.formatValueSync("filepicker-title-export"),
Ci.nsIFilePicker.modeSave
);
@ -149,7 +153,7 @@ function saveEventsToFile(calendarEventArray, aDefaultFileName) {
} else if (calendarEventArray.length == 1 && calendarEventArray[0].title) {
filename = calendarEventArray[0].title;
} else {
filename = cal.l10n.getCalString("defaultFileName");
filename = lazy.l10n.formatValueSync("default-file-name");
}
// Remove characters usually illegal on the file system.
picker.defaultString = filename.replace(/[/\\?%*:|"<>]/g, "-");
@ -219,7 +223,7 @@ function saveEventsToFile(calendarEventArray, aDefaultFileName) {
exporter.exportToStream(outputStream, calendarEventArray, null);
outputStream.close();
} catch (ex) {
cal.showError(cal.l10n.getCalString("unableToWrite") + filePath, window);
cal.showError(lazy.l10n.formatValueSync("unable-to-write", { filePath }), window);
}
});
}
@ -249,7 +253,7 @@ function exportEntireCalendar(aCalendar) {
// Ask what calendar to import into
const args = {};
args.onOk = getItemsFromCal;
args.promptText = cal.l10n.getCalString("exportPrompt");
args.promptText = lazy.l10n.formatValueSync("export-prompt");
openDialog(
"chrome://calendar/content/chooseCalendarDialog.xhtml",
"_blank",

Просмотреть файл

@ -86,6 +86,7 @@ ChromeUtils.defineLazyGetter(this, "gEventNotification", () => {
document.getElementById("event-dialog-notifications").append(element);
});
});
ChromeUtils.defineLazyGetter(this, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
var eventDialogRequestObserver = {
QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
@ -138,10 +139,10 @@ var eventDialogCalendarObserver = {
// The item has been modified outside the dialog. We only need to
// prompt if there have been local changes also.
if (isItemChanged()) {
const promptTitle = cal.l10n.getCalString("modifyConflictPromptTitle");
const promptMessage = cal.l10n.getCalString("modifyConflictPromptMessage");
const promptButton1 = cal.l10n.getCalString("modifyConflictPromptButton1");
const promptButton2 = cal.l10n.getCalString("modifyConflictPromptButton2");
const promptTitle = this.l10n.formatValueSync("modify-conflict-prompt-title");
const promptMessage = this.l10n.formatValueSync("modify-conflict-prompt-message");
const promptButton1 = this.l10n.formatValueSync("modify-conflict-prompt-button1");
const promptButton2 = this.l10n.formatValueSync("modify-conflict-prompt-button2");
const flags =
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 +
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1;
@ -488,11 +489,11 @@ function onCommandCancel() {
gTabmail.switchToTab(gTabInfoObject);
}
const promptTitle = cal.l10n.getCalString(
window.calendarItem.isEvent() ? "askSaveTitleEvent" : "askSaveTitleTask"
const promptTitle = this.l10n.formatValueSync(
window.calendarItem.isEvent() ? "ask-save-title-event" : "ask-save-title-task"
);
const promptMessage = cal.l10n.getCalString(
window.calendarItem.isEvent() ? "askSaveMessageEvent" : "askSaveMessageTask"
const promptMessage = this.l10n.formatValueSync(
window.calendarItem.isEvent() ? "ask-save-message-event" : "ask-save-message-task"
);
const flags =
@ -516,7 +517,7 @@ function onCommandCancel() {
// Save
const itemTitle = document.getElementById("item-title");
if (!itemTitle.value) {
itemTitle.value = cal.l10n.getCalString("eventUntitled");
itemTitle.value = this.l10n.formatValueSync("event-untitled");
}
onCommandSave(true);
return true;
@ -815,7 +816,7 @@ function loadCategories(aItem) {
if (maxCount == 1) {
const item = document.createXULElement("menuitem");
item.setAttribute("class", "menuitem-iconic");
item.setAttribute("label", cal.l10n.getCalString("None"));
document.l10n.setAttributes(item, "calendar-none");
item.setAttribute("type", "radio");
if (itemCategories.length === 0) {
item.setAttribute("checked", "true");
@ -855,16 +856,15 @@ function updateCategoryMenulist() {
// supported
document.getElementById("event-grid-category-row").toggleAttribute("hidden", maxCount === 0);
let label;
const categoryList = categoryPopup.querySelectorAll("menuitem.calendar-category[checked]");
if (categoryList.length > 1) {
label = cal.l10n.getCalString("multipleCategories");
document.l10n.setAttributes(categoryMenulist, "multiple-categories");
} else if (categoryList.length == 1) {
label = categoryList[0].getAttribute("label");
categoryMenulist.removeAttribute("data-l10n-id");
categoryMenulist.setAttribute("label", categoryList[0].getAttribute("label"));
} else {
label = cal.l10n.getCalString("None");
document.l10n.setAttributes(categoryMenulist, "calendar-none");
}
categoryMenulist.setAttribute("label", label);
const labelBox = categoryMenulist.shadowRoot.querySelector("#label-box");
const labelLabel = labelBox.querySelector("#label");
@ -1176,7 +1176,7 @@ function dateTimeControls2State(aStartDatepicker) {
gStartTime = saveStartTime;
gEndTime = saveEndTime;
warning = true;
stringWarning = cal.l10n.getCalString("warningEndBeforeStart");
stringWarning = this.l10n.formatValueSync("warning-end-before-start");
}
}
@ -1214,7 +1214,7 @@ function dateTimeControls2State(aStartDatepicker) {
}
warning = true;
stringWarning = cal.l10n.getCalString("warningUntilDateBeforeStart");
stringWarning = this.l10n.formatValueSync("warning-until-date-before-start");
}
}
@ -1686,15 +1686,15 @@ function untilDateCompensation(aItem) {
function updateTitle() {
let strName;
if (window.calendarItem.isEvent()) {
strName = window.mode == "new" ? "newEventDialog" : "editEventDialog";
strName = window.mode == "new" ? "new-event-dialog" : "edit-event-dialog";
} else if (window.calendarItem.isTodo()) {
strName = window.mode == "new" ? "newTaskDialog" : "editTaskDialog";
strName = window.mode == "new" ? "new-task-dialog" : "edit-task-dialog";
} else {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
sendMessage({
command: "updateTitle",
prefix: cal.l10n.getCalString(strName),
prefix: this.l10n.formatValueSync(strName),
title: document.getElementById("item-title").value,
});
}
@ -4048,7 +4048,7 @@ function checkUntilDate() {
Services.prompt.alert(
null,
document.title,
cal.l10n.getCalString("warningUntilDateBeforeStart")
this.l10n.formatValueSync("warning-until-date-before-start")
);
enableAcceptCommand(true);
gWarning = false;

Просмотреть файл

@ -33,6 +33,7 @@
<link rel="stylesheet" href="chrome://messenger/skin/themeableDialog.css" />
<link rel="localization" href="toolkit/global/textActions.ftl" />
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-editable-item.ftl" />
<link rel="localization" href="calendar/calendar-widgets.ftl" />
<script defer="defer" src="chrome://messenger/content/globalOverlay.js"></script>

Просмотреть файл

@ -7,7 +7,6 @@
/* import-globals-from calendar-item-editing.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
ChromeUtils.defineESModuleGetters(this, {
@ -48,12 +47,20 @@ var taskEdit = {
edit.showsInstructions = true;
if (calendar.getProperty("capabilities.tasks.supported") === false) {
taskEdit.setupTaskField(edit, true, cal.l10n.getCalString("taskEditInstructionsCapability"));
taskEdit.setupTaskField(
edit,
true,
taskEdit.l10n.formatValueSync("task-edit-instructions-capability")
);
} else if (cal.acl.isCalendarWritable(calendar)) {
edit.showsInstructions = false;
taskEdit.setupTaskField(edit, false, edit.savedValue || "");
} else {
taskEdit.setupTaskField(edit, true, cal.l10n.getCalString("taskEditInstructionsReadonly"));
taskEdit.setupTaskField(
edit,
true,
taskEdit.l10n.formatValueSync("task-edit-instructions-readonly")
);
}
},
@ -71,14 +78,22 @@ var taskEdit = {
}
if (calendar.getProperty("capabilities.tasks.supported") === false) {
taskEdit.setupTaskField(edit, true, cal.l10n.getCalString("taskEditInstructionsCapability"));
taskEdit.setupTaskField(
edit,
true,
taskEdit.l10n.formatValueSync("task-edit-instructions-capability")
);
} else if (cal.acl.isCalendarWritable(calendar)) {
if (!edit.showsInstructions) {
edit.savedValue = edit.value || "";
}
taskEdit.setupTaskField(edit, false, cal.l10n.getCalString("taskEditInstructions"));
taskEdit.setupTaskField(edit, false, taskEdit.l10n.formatValueSync("task-edit-instructions"));
} else {
taskEdit.setupTaskField(edit, true, cal.l10n.getCalString("taskEditInstructionsReadonly"));
taskEdit.setupTaskField(
edit,
true,
taskEdit.l10n.formatValueSync("task-edit-instructions-readonly")
);
}
edit.showsInstructions = true;
@ -179,3 +194,9 @@ var taskEdit = {
},
},
};
ChromeUtils.defineLazyGetter(
taskEdit,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);

Просмотреть файл

@ -9,6 +9,8 @@
/* import-globals-from ../../base/content/calendar-views-utils.js */
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* Show publish dialog, ask for URL and publish all selected items.
@ -58,7 +60,7 @@ function publishEntireCalendar(aCalendar) {
// Therefore return after openDialog().
const args = {};
args.onOk = publishEntireCalendar;
args.promptText = cal.l10n.getCalString("publishPrompt");
args.promptText = lazy.l10n.formatValueSync("publish-prompt");
openDialog(
"chrome://calendar/content/chooseCalendarDialog.xhtml",
"_blank",
@ -167,8 +169,8 @@ function publishItemArray(aItemArray, aPath, aProgressDialog) {
} catch (e) {
Services.prompt.alert(
null,
cal.l10n.getCalString("genericErrorTitle"),
cal.l10n.getCalString("otherPutError", [e.message])
lazy.l10n.formatValueSync("generic-error-title"),
lazy.l10n.formatValueSync("other-put-error", { statusCode: e.message })
);
}
}
@ -212,16 +214,18 @@ class PublishingListener {
if (channel && !requestSucceeded) {
this.progressDialog.wrappedJSObject.onStopUpload(0);
const body = cal.l10n.getCalString("httpPutError", [
channel.responseStatus,
channel.responseStatusText,
]);
Services.prompt.alert(null, cal.l10n.getCalString("genericErrorTitle"), body);
const body = lazy.l10n.formatValueSync("http-put-error", {
statusCode: channel.responseStatus,
statusCodeInfo: channel.responseStatusText,
});
Services.prompt.alert(null, lazy.l10n.formatValueSync("generic-error-title"), body);
} else if (!channel && !Components.isSuccessCode(request.status)) {
this.progressDialog.wrappedJSObject.onStopUpload(0);
// XXX this should be made human-readable.
const body = cal.l10n.getCalString("otherPutError", [request.status.toString(16)]);
Services.prompt.alert(null, cal.l10n.getCalString("genericErrorTitle"), body);
const body = lazy.l10n.formatValueSync("other-put-error", {
statusCode: request.status.toString(16),
});
Services.prompt.alert(null, lazy.l10n.formatValueSync("generic-error-title"), body);
} else {
this.progressDialog.wrappedJSObject.onStopUpload(100);
}

Просмотреть файл

@ -10,7 +10,6 @@
const { CalMetronome } = ChromeUtils.importESModule("resource:///modules/CalMetronome.sys.mjs");
const { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
const { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
customElements.whenDefined("tree-listbox").then(() => {
class Agenda extends CalendarFilteredViewMixin(customElements.get("tree-listbox")) {
_showsToday = false;
@ -410,14 +409,15 @@
tomorrow.day++;
if (date.year == today.year && date.month == today.month && date.day == today.day) {
this.dateHeaderElement.textContent = cal.l10n.getCalString("today");
document.l10n.setAttributes(this.dateHeaderElement, "calendar-today");
} else if (
date.year == tomorrow.year &&
date.month == tomorrow.month &&
date.day == tomorrow.day
) {
this.dateHeaderElement.textContent = cal.l10n.getCalString("tomorrow");
document.l10n.setAttributes(this.dateHeaderElement, "calendar-tomorrow");
} else {
delete this.dateHeaderElement.dataset.l10nId;
this.dateHeaderElement.textContent = cal.dtz.formatter.formatDateLongWithoutYear(date);
}
}

Просмотреть файл

@ -33,9 +33,9 @@ var TodayPane = {
this.isLoaded = true;
TodayPane.paneViews = [
cal.l10n.getCalString("eventsandtasks"),
cal.l10n.getCalString("tasksonly"),
cal.l10n.getCalString("eventsonly"),
TodayPane.l10n.formatValueSync("events-and-tasks"),
TodayPane.l10n.formatValueSync("tasks-only"),
TodayPane.l10n.formatValueSync("events-only"),
];
this.agenda = document.getElementById("agenda");
@ -421,7 +421,7 @@ var TodayPane = {
const currentweeklabel = document.getElementById("currentWeek-label");
currentweeklabel.value =
cal.l10n.getCalString("shortcalendarweek") +
TodayPane.l10n.formatValueSync("short-calendar-week") +
" " +
cal.weekInfoService.getWeekTitle(this.start);
@ -550,4 +550,10 @@ var TodayPane = {
},
};
ChromeUtils.defineLazyGetter(
TodayPane,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
window.addEventListener("unload", TodayPane.onUnload, { capture: false, once: true });

Просмотреть файл

@ -4,11 +4,17 @@
"use strict";
/* global Cr MozElements MozXULElement PluralForm Services */
/* global Cr MozElements MozXULElement Services */
// Wrap in a block to prevent leaking to window scope.
{
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl", "calendar/calendar-alarms.ftl"], true)
);
/**
* Represents an alarm in the alarms dialog. It appears there when an alarm is fired, and
* allows the alarm to be snoozed, dismissed, etc.
@ -104,9 +110,9 @@
if (startDate) {
// A task with a start or due date, show with label.
startDate = startDate.getInTimezone(cal.dtz.defaultTimezone);
dateLabel.value = cal.l10n.getCalString("alarmStarts", [
formatter.formatDateTime(startDate),
]);
document.l10n.setAttributes(dateLabel, "alarm-starts", {
datetime: formatter.formatDateTime(startDate),
});
} else {
// If the task has no start date, then format the alarm date.
dateLabel.value = formatter.formatDateTime(this.mAlarm.alarmDate);
@ -145,11 +151,11 @@
!cal.acl.isCalendarWritable(this.mItem.calendar) ||
!cal.acl.userCanModifyItem(this.mItem)
) {
const tooltip = "reminderDisabledSnoozeButtonTooltip";
snoozeButton.disabled = true;
snoozeButton.setAttribute("tooltiptext", cal.l10n.getString("calendar-alarms", tooltip));
document.l10n.setAttributes(snoozeButton, "reminder-disabled-snooze-button-tooltip");
} else {
snoozeButton.disabled = false;
snoozeButton.removeAttribute("data-l10n-id");
snoozeButton.removeAttribute("tooltiptext");
}
}
@ -179,19 +185,19 @@
if (this.mAlarmToday) {
// The alarm is today.
relativeDateString = cal.l10n.getCalString("alarmTodayAt", [
formatter.formatTime(startDate),
]);
relativeDateString = lazy.l10n.formatValueSync("alarm-today-at", {
datetime: formatter.formatTime(startDate),
});
} else if (sinceAlarm <= sinceDayStart - 86400 && sinceAlarm > sinceDayStart - 172800) {
// The alarm is tomorrow.
relativeDateString = cal.l10n.getCalString("alarmTomorrowAt", [
formatter.formatTime(startDate),
]);
relativeDateString = lazy.l10n.formatValueSync("alarm-tomorrow-at", {
datetime: formatter.formatTime(startDate),
});
} else if (sinceAlarm < sinceDayStart + 86400 && sinceAlarm > sinceDayStart) {
// The alarm is yesterday.
relativeDateString = cal.l10n.getCalString("alarmYesterdayAt", [
formatter.formatTime(startDate),
]);
relativeDateString = lazy.l10n.formatValueSync("alarm-yesterday-at", {
datetime: formatter.formatTime(startDate),
});
} else {
// The alarm is way back.
relativeDateString = [formatter.formatDateTime(startDate)];
@ -374,26 +380,20 @@
const okButton = this.querySelector(".snooze-popup-ok-button");
function unitName(list) {
return { 1: "unitMinutes", 60: "unitHours", 1440: "unitDays" }[list.value] || "unitMinutes";
return (
{ 1: "unit-minutes", 60: "unit-hours", 1440: "unit-days" }[list.value] || "unit-minutes"
);
}
let pluralString = cal.l10n.getCalString(unitName(unitList));
const unit = lazy.l10n.formatValueSync(unitName(unitList), { count: unitValue.value });
const unitPlural = PluralForm.get(unitValue.value, pluralString).replace(
"#1",
unitValue.value
);
const okButtonAriaLabel = cal.l10n.getString("calendar-alarms", "reminderSnoozeOkA11y", [
unitPlural,
]);
okButton.setAttribute("aria-label", okButtonAriaLabel);
document.l10n.setAttributes(okButton, "reminder-snooze-ok-a11y", {
unit,
});
const items = unitPopup.getElementsByTagName("menuitem");
for (const menuItem of items) {
pluralString = cal.l10n.getCalString(unitName(menuItem));
menuItem.label = PluralForm.get(unitValue.value, pluralString).replace("#1", "").trim();
menuItem.label = lazy.l10n.formatValueSync(unitName(menuItem), { count: unitValue.value });
}
}
}

Просмотреть файл

@ -9,7 +9,6 @@
// Wrap in a block to prevent leaking to window scope.
{
const { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
CalDateTime: "resource:///modules/CalDateTime.sys.mjs",
@ -659,9 +658,11 @@
if (aDate.getFullYear() == (this.mValue || this.mExtraDate).getFullYear()) {
calbox.setAttribute("aria-label", dateString);
} else {
const monthName = cal.l10n.formatMonth(aDate.getMonth() + 1, "calendar", "monthInYear");
const label = cal.l10n.getCalString("monthInYear", [monthName, aDate.getFullYear()]);
calbox.setAttribute("aria-label", label);
const monthName = cal.l10n.formatMonth(aDate.getMonth() + 1, "calendar", "month-in-year");
document.l10n.setAttributes(calbox, "month-in-year-label", {
month: monthName,
year: aDate.getFullYear(),
});
}
this.dayBoxes.clear();
@ -674,9 +675,8 @@
const weekNumber = cal.weekInfoService.getWeekTitle(
cal.dtz.jsDateToDateTime(date, defaultTz)
);
const weekTitle = cal.l10n.getCalString("WeekTitle", [weekNumber]);
firstElement.textContent = weekNumber;
firstElement.setAttribute("aria-label", weekTitle);
document.l10n.setAttributes(firstElement, "week-title-label", { title: weekNumber });
}
for (let i = 1; i < 8; i++) {
@ -871,13 +871,12 @@
}
updateAccessibleLabel() {
let label;
if (this.mValue) {
label = dateFormatter.format(this.mValue);
this.removeAttribute("data-l10n-id");
this.setAttribute("aria-label", dateFormatter.format(this.mValue));
} else {
label = cal.l10n.getCalString("minimonthNoSelectedDate");
document.l10n.setAttributes(this, "minimonth-no-selected-date");
}
this.setAttribute("aria-label", label);
}
update(aValue) {

Просмотреть файл

@ -9,8 +9,12 @@
// Wrap in a block to prevent leaking to window scope.
{
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
const lazy = {};
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
/**
* A calendar-notifications-setting provides controls to config notifications
* times of a calendar.
@ -185,13 +189,13 @@
</menulist>
<menulist class="relation-menu" crop="none" value="${relation}">
<menupopup class="reminder-relation-origin-menupopup">
<menuitem data-id="reminderCustomOriginBeginBeforeEvent"
<menuitem data-l10n-id="reminder-custom-origin-begin-before-event-dom"
value="before-START"/>
<menuitem data-id="reminderCustomOriginBeginAfterEvent"
<menuitem data-l10n-id="reminder-custom-origin-begin-after-event-dom"
value="after-START"/>
<menuitem data-id="reminderCustomOriginEndBeforeEvent"
<menuitem data-l10n-id="reminder-custom-origin-end-before-event-dom"
value="before-END"/>
<menuitem data-id="reminderCustomOriginEndAfterEvent"
<menuitem data-l10n-id="reminder-custom-origin-end-after-event-dom"
value="after-END"/>
</menupopup>
</menulist>
@ -223,9 +227,6 @@
const input = row.querySelector("input");
const menulist = row.querySelector(".unit-menu");
this._updateMenuList(input.value, menulist);
for (const menuItem of row.querySelectorAll(".relation-menu menuitem")) {
menuItem.label = cal.l10n.getString("calendar-alarms", menuItem.dataset.id);
}
}
}
@ -235,14 +236,16 @@
_updateMenuList(length, menu) {
const getUnitEntry = unit =>
({
M: "unitMinutes",
H: "unitHours",
D: "unitDays",
}[unit] || "unitMinutes");
M: "unit-minutes",
H: "unit-hours",
D: "unit-days",
}[unit] || "unit-minutes");
for (const menuItem of menu.getElementsByTagName("menuitem")) {
menuItem.label = PluralForm.get(length, cal.l10n.getCalString(getUnitEntry(menuItem.value)))
.replace("#1", "")
menuItem.label = lazy.l10n
.formatValueSync(getUnitEntry(menuItem.value), {
count: length,
})
.trim();
}
}

Просмотреть файл

@ -23,6 +23,8 @@
*/
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* PUBLIC: Displays a tooltip with details when hovering over an item in the views
@ -88,11 +90,11 @@ function getEventStatusString(aEvent) {
switch (aEvent.status) {
// Event status value keywords are specified in RFC2445sec4.8.1.11
case "TENTATIVE":
return cal.l10n.getCalString("statusTentative");
return lazy.l10n.formatValueSync("status-tentative");
case "CONFIRMED":
return cal.l10n.getCalString("statusConfirmed");
return lazy.l10n.formatValueSync("status-confirmed");
case "CANCELLED":
return cal.l10n.getCalString("eventStatusCancelled");
return lazy.l10n.formatValueSync("event-status-cancelled");
default:
return "";
}
@ -109,13 +111,13 @@ function getToDoStatusString(aToDo) {
switch (aToDo.status) {
// Todo status keywords are specified in RFC2445sec4.8.1.11
case "NEEDS-ACTION":
return cal.l10n.getCalString("statusNeedsAction");
return lazy.l10n.formatValueSync("status-needs-action");
case "IN-PROCESS":
return cal.l10n.getCalString("statusInProcess");
return lazy.l10n.formatValueSync("status-in-process");
case "CANCELLED":
return cal.l10n.getCalString("todoStatusCancelled");
return lazy.l10n.formatValueSync("todo-status-cancelled");
case "COMPLETED":
return cal.l10n.getCalString("statusCompleted");
return lazy.l10n.formatValueSync("status-completed");
default:
return "";
}
@ -144,29 +146,29 @@ function getPreviewForTask(toDoItem, aIsTooltip = true) {
let hasHeader = false;
if (toDoItem.title) {
boxAppendLabeledText(vbox, "tooltipTitle", toDoItem.title);
boxAppendLabeledText(vbox, "tooltip-title", toDoItem.title);
hasHeader = true;
}
const location = toDoItem.getProperty("LOCATION");
if (location) {
boxAppendLabeledText(vbox, "tooltipLocation", location);
boxAppendLabeledText(vbox, "tooltip-location", location);
hasHeader = true;
}
// First try to get calendar name appearing in tooltip
if (toDoItem.calendar.name) {
const calendarNameString = toDoItem.calendar.name;
boxAppendLabeledText(vbox, "tooltipCalName", calendarNameString);
boxAppendLabeledText(vbox, "tooltip-cal-name", calendarNameString);
}
if (toDoItem.entryDate && toDoItem.entryDate.isValid) {
boxAppendLabeledDateTime(vbox, "tooltipStart", toDoItem.entryDate);
boxAppendLabeledDateTime(vbox, "tooltip-start", toDoItem.entryDate);
hasHeader = true;
}
if (toDoItem.dueDate && toDoItem.dueDate.isValid) {
boxAppendLabeledDateTime(vbox, "tooltipDue", toDoItem.dueDate);
boxAppendLabeledDateTime(vbox, "tooltip-due", toDoItem.dueDate);
hasHeader = true;
}
@ -176,19 +178,19 @@ function getPreviewForTask(toDoItem, aIsTooltip = true) {
// These cut-offs should match calendar-event-dialog.js
if (priorityInteger >= 1 && priorityInteger <= 4) {
priorityString = cal.l10n.getCalString("highPriority");
priorityString = lazy.l10n.formatValueSync("high-priority");
} else if (priorityInteger == 5) {
priorityString = cal.l10n.getCalString("normalPriority");
priorityString = lazy.l10n.formatValueSync("normal-priority");
} else {
priorityString = cal.l10n.getCalString("lowPriority");
priorityString = lazy.l10n.formatValueSync("low-priority");
}
boxAppendLabeledText(vbox, "tooltipPriority", priorityString);
boxAppendLabeledText(vbox, "tooltip-priority", priorityString);
hasHeader = true;
}
if (toDoItem.status && toDoItem.status != "NONE") {
const status = getToDoStatusString(toDoItem);
boxAppendLabeledText(vbox, "tooltipStatus", status);
boxAppendLabeledText(vbox, "tooltip-status", status);
hasHeader = true;
}
@ -197,13 +199,13 @@ function getPreviewForTask(toDoItem, aIsTooltip = true) {
toDoItem.percentComplete != 0 &&
toDoItem.percentComplete != 100
) {
boxAppendLabeledText(vbox, "tooltipPercent", String(toDoItem.percentComplete) + "%");
boxAppendLabeledText(vbox, "tooltip-percent", String(toDoItem.percentComplete) + "%");
hasHeader = true;
} else if (toDoItem.percentComplete == 100) {
if (toDoItem.completedDate == null) {
boxAppendLabeledText(vbox, "tooltipPercent", "100%");
boxAppendLabeledText(vbox, "tooltip-percent", "100%");
} else {
boxAppendLabeledDateTime(vbox, "tooltipCompleted", toDoItem.completedDate);
boxAppendLabeledDateTime(vbox, "tooltip-completed", toDoItem.completedDate);
}
hasHeader = true;
}
@ -246,34 +248,34 @@ function getPreviewForEvent(aEvent, aIsTooltip = true) {
if (event) {
if (event.title) {
boxAppendLabeledText(vbox, "tooltipTitle", aEvent.title);
boxAppendLabeledText(vbox, "tooltip-title", aEvent.title);
}
const location = event.getProperty("LOCATION");
if (location) {
boxAppendLabeledText(vbox, "tooltipLocation", location);
boxAppendLabeledText(vbox, "tooltip-location", location);
}
if (!(event.startDate && event.endDate)) {
// Event may be recurrent event. If no displayed instance specified,
// use next instance, or previous instance if no next instance.
event = getCurrentNextOrPreviousRecurrence(event);
}
boxAppendLabeledDateTimeInterval(vbox, "tooltipDate", event);
boxAppendLabeledDateTimeInterval(vbox, "tooltip-date", event);
// First try to get calendar name appearing in tooltip
if (event.calendar.name) {
const calendarNameString = event.calendar.name;
boxAppendLabeledText(vbox, "tooltipCalName", calendarNameString);
boxAppendLabeledText(vbox, "tooltip-cal-name", calendarNameString);
}
if (event.status && event.status != "NONE") {
const statusString = getEventStatusString(event);
boxAppendLabeledText(vbox, "tooltipStatus", statusString);
boxAppendLabeledText(vbox, "tooltip-status", statusString);
}
if (event.organizer && event.getAttendees().length > 0) {
const organizer = event.organizer;
boxAppendLabeledText(vbox, "tooltipOrganizer", organizer);
boxAppendLabeledText(vbox, "tooltip-organizer", organizer);
}
const description = event.descriptionText;
@ -363,11 +365,10 @@ function boxInitializeHeaderTable(box) {
* @param textString value of header field.
*/
function boxAppendLabeledText(box, labelProperty, textString) {
const labelText = cal.l10n.getCalString(labelProperty);
const table = box.querySelector("table");
const row = document.createElement("tr");
row.appendChild(createTooltipHeaderLabel(labelText));
row.appendChild(createTooltipHeaderLabel(labelProperty));
row.appendChild(createTooltipHeaderDescription(textString));
table.appendChild(row);
@ -376,13 +377,13 @@ function boxAppendLabeledText(box, labelProperty, textString) {
/**
* PRIVATE: Creates an element for field label (for header table)
*
* @param {string} text The text to display in the node
* @param {string} text - The string ID for the text to display in the node.
* @returns {Node} The node
*/
function createTooltipHeaderLabel(text) {
const labelCell = document.createElement("th");
labelCell.setAttribute("class", "tooltipHeaderLabel");
labelCell.textContent = text;
document.l10n.setAttributes(labelCell, text);
return labelCell;
}

Просмотреть файл

@ -16,7 +16,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
CalRecurrenceRule: "resource:///modules/CalRecurrenceRule.sys.mjs",
});
// The calendar console instance
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true)); // The calendar console instance
var gCalendarConsole = console.createInstance({
prefix: "Calendar",
consoleID: "calendar",
@ -86,7 +86,7 @@ export var cal = {
* for any window.
*/
showError(aMsg, aWindow = null) {
Services.prompt.alert(aWindow, cal.l10n.getCalString("genericErrorTitle"), aMsg);
Services.prompt.alert(aWindow, lazy.l10n.formatValueSync("generic-error-title"), aMsg);
},
/**

Просмотреть файл

@ -13,6 +13,11 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
cal: "resource:///modules/calendar/calUtils.sys.mjs",
});
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/categories.ftl"], true)
);
export var category = {
/**
@ -24,7 +29,7 @@ export var category = {
const defaultBranch = Services.prefs.getDefaultBranch("");
// First, set up the category names
const categories = lazy.cal.l10n.getString("categories", "categories2");
const categories = lazy.l10n.formatValueSync("categories2");
defaultBranch.setStringPref("calendar.categories.names", categories);
// Now, initialize the category default colors

Просмотреть файл

@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
ChromeUtils.defineLazyGetter(lazy, "gDateStringBundle", () =>
Services.strings.createBundle("chrome://calendar/locale/dateFormat.properties")
);
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
XPCOMUtils.defineLazyPreferenceGetter(lazy, "dateFormat", "calendar.date.format", 0);
XPCOMUtils.defineLazyPreferenceGetter(
@ -184,70 +185,70 @@ export var formatter = {
const format = this.formatIntervalParts(startDate, endDate);
switch (format.type) {
case "task-without-dates":
return lazy.cal.l10n.getCalString("datetimeIntervalTaskWithoutDate");
return lazy.l10n.formatValueSync("datetime-interval-task-without-date");
case "task-without-due-date":
return lazy.cal.l10n.getCalString("datetimeIntervalTaskWithoutDueDate", [
format.startDate,
format.startTime,
]);
return lazy.l10n.formatValueSync("datetime-interval-task-without-due-date", {
date: format.startDate,
time: format.startTime,
});
case "task-without-start-date":
return lazy.cal.l10n.getCalString("datetimeIntervalTaskWithoutStartDate", [
format.endDate,
format.endTime,
]);
return lazy.l10n.formatValueSync("datetime-interval-task-without-start-date", {
date: format.endDate,
time: format.endTime,
});
case "all-day":
return format.startDate;
case "all-day-between-years":
return lazy.cal.l10n.getCalString("daysIntervalBetweenYears", [
format.startMonth,
format.startDay,
format.startYear,
format.endMonth,
format.endDay,
format.endYear,
]);
return lazy.l10n.formatValueSync("days-interval-between-years", {
startMonth: format.startMonth,
startDayIndex: format.startDay,
startYear: format.startYear,
endMonth: format.endMonth,
endDayIndex: format.endDay,
endYear: format.endYear,
});
case "all-day-in-month":
return lazy.cal.l10n.getCalString("daysIntervalInMonth", [
format.month,
format.startDay,
format.endDay,
format.year,
]);
return lazy.l10n.formatValueSync("days-interval-in-month", {
startMonth: format.month,
startDayIndex: format.startDay,
endDayIndex: format.endDay,
year: format.year,
});
case "all-day-between-months":
return lazy.cal.l10n.getCalString("daysIntervalBetweenMonths", [
format.startMonth,
format.startDay,
format.endMonth,
format.endDay,
format.year,
]);
return lazy.l10n.formatValueSync("days-interval-between-months", {
startMonth: format.startMonth,
startDayIndex: format.startDay,
endMonth: format.endMonth,
endDayIndex: format.endDay,
year: format.year,
});
case "same-date-time":
return lazy.cal.l10n.getCalString("datetimeIntervalOnSameDateTime", [
format.startDate,
format.startTime,
]);
return lazy.l10n.formatValueSync("datetime-interval-on-same-date-time", {
startDate: format.startDate,
startTime: format.startTime,
});
case "same-day":
return lazy.cal.l10n.getCalString("datetimeIntervalOnSameDay", [
format.startDate,
format.startTime,
format.endTime,
]);
return lazy.l10n.formatValueSync("datetime-interval-on-same-day", {
startDate: format.startDate,
startTime: format.startTime,
endTime: format.endTime,
});
case "several-days":
return lazy.cal.l10n.getCalString("datetimeIntervalOnSeveralDays", [
format.startDate,
format.startTime,
format.endDate,
format.endTime,
]);
return lazy.l10n.formatValueSync("datetime-interval-on-several-days", {
startDate: format.startDate,
startTime: format.startTime,
endDate: format.endDate,
endTime: format.endTime,
});
default:
return "";
}
@ -345,14 +346,14 @@ export var formatter = {
startMonth: lazy.cal.l10n.formatMonth(
startDate.month + 1,
"calendar",
"daysIntervalBetweenYears"
"days-interval-between-years"
),
startYear,
endDay,
endMonth: lazy.cal.l10n.formatMonth(
originalEndDate.month + 1,
"calendar",
"daysIntervalBetweenYears"
"days-interval-between-years"
),
endYear,
};
@ -362,7 +363,11 @@ export var formatter = {
return {
type: "all-day-in-month",
startDay,
month: lazy.cal.l10n.formatMonth(startDate.month + 1, "calendar", "daysIntervalInMonth"),
month: lazy.cal.l10n.formatMonth(
startDate.month + 1,
"calendar",
"days-interval-in-month"
),
endDay,
year: endYear,
};
@ -374,13 +379,13 @@ export var formatter = {
startMonth: lazy.cal.l10n.formatMonth(
startDate.month + 1,
"calendar",
"daysIntervalBetweenMonths"
"days-interval-between-months"
),
endDay,
endMonth: lazy.cal.l10n.formatMonth(
originalEndDate.month + 1,
"calendar",
"daysIntervalBetweenMonths"
"days-interval-between-months"
),
year: endYear,
};

Просмотреть файл

@ -13,6 +13,7 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
cal: "resource:///modules/calendar/calUtils.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export var dtz = {
/**
@ -413,10 +414,10 @@ export var dtz = {
if (!dateTime.timezone.isFloating && dateTime.timezone.tzid != kDefaultTimezone.tzid) {
// Additionally display the original datetime with timezone.
const originalTime = lazy.cal.l10n.getCalString("datetimeWithTimezone", [
formatter.formatDateTime(dateTime),
dateTime.timezone.tzid,
]);
const originalTime = lazy.l10n.formatValueSync("datetime-with-timezone", {
datetime: formatter.formatDateTime(dateTime),
timezone: dateTime.timezone.tzid,
});
return `${formattedLocalTime} (${originalTime})`;
}
return formattedLocalTime;

Просмотреть файл

@ -21,6 +21,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
CalRelation: "resource:///modules/CalRelation.sys.mjs",
cal: "resource:///modules/calendar/calUtils.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export var itip = {
/**
@ -898,7 +899,7 @@ export var itip = {
args.onOk = aCal => {
targetCalendar = aCal;
};
args.promptText = lazy.cal.l10n.getCalString("importPrompt");
args.promptText = lazy.l10n.formatValueSync("import-prompt");
aWindow.openDialog(
"chrome://calendar/content/chooseCalendarDialog.xhtml",
"_blank",

Просмотреть файл

@ -9,6 +9,9 @@
// NOTE: This module should not be loaded directly, it is available when
// including calUtils.sys.mjs under the cal.l10n namespace.
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* Gets the value of a string in a .properties file.
*
@ -91,15 +94,6 @@ export var l10n = {
*/
getString: _getString.bind(undefined, "calendar"),
/**
* Gets a string from chrome://calendar/locale/calendar.properties bundle
*
* @param {string} aStringName - The name of the string within the properties file
* @param {string[]} aParams - (optional) Parameters to format the string
* @returns {string} The formatted string
*/
getCalString: _getString.bind(undefined, "calendar", "calendar"),
/**
* Gets a string from chrome://lightning/locale/lightning.properties
*
@ -127,7 +121,7 @@ export var l10n = {
* @returns {string} The formatted month name
*/
formatMonth(aMonthNum, aBundleName, aStringBase) {
let monthForm = l10n.getString(aBundleName, aStringBase + ".monthFormat") || "nominative";
let monthForm = lazy.l10n.formatValueSync(`${aStringBase}-month-format`) || "nominative";
if (monthForm == "nominative") {
// Fall back to the default name format

Просмотреть файл

@ -14,11 +14,11 @@
// NOTE: This module should not be loaded directly, it is available when
// including calUtils.sys.mjs under the cal.print namespace.
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
cal: "resource:///modules/calendar/calUtils.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export var print = {
ensureInitialized() {
@ -132,7 +132,7 @@ function addItemToDayboxNodate(document, item) {
if (taskListBox.hasAttribute("hidden")) {
const tasksTitle = document.getElementById("tasks-title");
taskListBox.removeAttribute("hidden");
tasksTitle.textContent = lazy.cal.l10n.getCalString("tasksWithNoDueDate");
tasksTitle.textContent = lazy.l10n.formatValueSync("tasks-with-no-due-date");
}
// Fill in details of the task
@ -259,7 +259,7 @@ const listView = {
const setupTextRow = function (classKey, propValue, prefixKey) {
if (propValue) {
const prefix = lazy.cal.l10n.getCalString(prefixKey);
const prefix = lazy.l10n.formatValueSync(prefixKey);
itemNode.querySelector("." + classKey + "key").textContent = prefix;
itemNode.querySelector("." + classKey).textContent = propValue;
} else {
@ -278,7 +278,7 @@ const listView = {
const itemEndDate = item[lazy.cal.dtz.endDateProp(item)];
if (itemStartDate || itemEndDate) {
// This is a task with a start or due date, format accordingly
const prefixWhen = lazy.cal.l10n.getCalString("htmlPrefixWhen");
const prefixWhen = lazy.l10n.formatValueSync("html-prefix-when");
itemNode.querySelector(".intervalkey").textContent = prefixWhen;
const startNode = itemNode.querySelector(".dtstart");
@ -298,12 +298,12 @@ const listView = {
}
const itemTitle = item.isCompleted
? lazy.cal.l10n.getCalString("htmlTaskCompleted", [item.title])
? lazy.l10n.formatValueSync("html-task-completed", { task: item.title })
: item.title;
setupTextRow("summary", itemTitle, "htmlPrefixTitle");
setupTextRow("summary", itemTitle, "html-prefix-title");
setupTextRow("location", item.getProperty("LOCATION"), "htmlPrefixLocation");
setupTextRow("description", item.getProperty("DESCRIPTION"), "htmlPrefixDescription");
setupTextRow("location", item.getProperty("LOCATION"), "html-prefix-location");
setupTextRow("description", item.getProperty("DESCRIPTION"), "html-prefix-description");
container.appendChild(itemNode);
}
@ -399,8 +399,15 @@ const monthGridView = {
const month = monthTemplate.content.firstElementChild.cloneNode(true);
// Set up the month title
const monthName = lazy.cal.l10n.formatMonth(startOfMonth.month + 1, "calendar", "monthInYear");
const monthTitle = lazy.cal.l10n.getCalString("monthInYear", [monthName, startOfMonth.year]);
const monthName = lazy.cal.l10n.formatMonth(
startOfMonth.month + 1,
"calendar",
"month-in-year"
);
const monthTitle = lazy.l10n.formatValueSync("month-in-year", {
month: monthName,
year: startOfMonth.year,
});
month.rows[0].cells[0].firstElementChild.textContent = monthTitle;
// Set up the weekday titles
@ -531,12 +538,14 @@ const weekPlannerView = {
// Set the page title.
const weeks = container.querySelectorAll("table");
if (weeks.length == 1) {
document.title = lazy.cal.l10n.getCalString("singleLongCalendarWeek", [weeks[0].number]);
document.title = lazy.l10n.formatValueSync("single-long-calendar-week", {
index: weeks[0].number,
});
} else {
document.title = lazy.cal.l10n.getCalString("severalLongCalendarWeeks", [
weeks[0].number,
weeks[weeks.length - 1].number,
]);
document.title = lazy.l10n.formatValueSync("several-long-calendar-weeks", {
startIndex: weeks[0].number,
endIndex: weeks[weeks.length - 1].number,
});
}
},
@ -563,9 +572,9 @@ const weekPlannerView = {
// Set up the week number title
week.number = lazy.cal.weekInfoService.getWeekTitle(monday);
week.querySelector(".week-title").textContent = lazy.cal.l10n.getCalString("WeekTitle", [
week.number,
]);
week.querySelector(".week-title").textContent = lazy.l10n.formatValueSync("week-title", {
title: week.number,
});
// Set up the day boxes
const currentDate = monday.clone();

Просмотреть файл

@ -2,7 +2,6 @@
* 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 { PluralForm } from "resource:///modules/PluralForm.sys.mjs";
import { cal } from "resource:///modules/calendar/calUtils.sys.mjs";
const lazy = {};
@ -13,6 +12,11 @@ ChromeUtils.defineESModuleGetters(lazy, {
CalDateTime: "resource:///modules/CalDateTime.sys.mjs",
CalDuration: "resource:///modules/CalDuration.sys.mjs",
});
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl", "calendar/calendar-alarms.ftl"], true)
);
const ALARM_RELATED_ABSOLUTE = Ci.calIAlarm.ALARM_RELATED_ABSOLUTE;
const ALARM_RELATED_START = Ci.calIAlarm.ALARM_RELATED_START;
@ -435,7 +439,7 @@ CalAlarm.prototype = {
if (this.summary || this.action == "EMAIL") {
const summaryProp = cal.icsService.createIcalProperty("SUMMARY");
// Summary needs to have a non-empty value
summaryProp.value = this.summary || cal.l10n.getCalString("alarmDefaultSummary");
summaryProp.value = this.summary || lazy.l10n.formatValueSync("alarm-default-summary");
comp.addProperty(summaryProp);
}
@ -443,7 +447,8 @@ CalAlarm.prototype = {
if (this.description || this.action == "DISPLAY" || this.action == "EMAIL") {
const descriptionProp = cal.icsService.createIcalProperty("DESCRIPTION");
// description needs to have a non-empty value
descriptionProp.value = this.description || cal.l10n.getCalString("alarmDefaultDescription");
descriptionProp.value =
this.description || lazy.l10n.formatValueSync("alarm-default-description");
comp.addProperty(descriptionProp);
}
@ -621,9 +626,9 @@ CalAlarm.prototype = {
toString(aItem) {
function alarmString(aPrefix) {
if (!aItem || aItem.isEvent()) {
return aPrefix + "Event";
return `${aPrefix}-event`;
} else if (aItem.isTodo()) {
return aPrefix + "Task";
return `${aPrefix}-task`;
}
return aPrefix;
}
@ -640,48 +645,47 @@ CalAlarm.prototype = {
// No need to get the other information if the alarm is at the start
// of the event/task.
if (this.related == ALARM_RELATED_START) {
return cal.l10n.getString("calendar-alarms", alarmString("reminderTitleAtStart"));
return lazy.l10n.formatValueSync(alarmString("reminder-title-at-start"));
} else if (this.related == ALARM_RELATED_END) {
return cal.l10n.getString("calendar-alarms", alarmString("reminderTitleAtEnd"));
return lazy.l10n.formatValueSync(alarmString("reminder-title-at-end"));
}
}
let unit;
if (alarmlen % 1440 == 0) {
// Alarm is in days
unit = "unitDays";
unit = "unit-days";
alarmlen /= 1440;
} else if (alarmlen % 60 == 0) {
unit = "unitHours";
unit = "unit-hours";
alarmlen /= 60;
} else {
unit = "unitMinutes";
unit = "unit-minutes";
}
const localeUnitString = cal.l10n.getCalString(unit);
const unitString = PluralForm.get(alarmlen, localeUnitString).replace("#1", alarmlen);
let originStringName = "reminderCustomOrigin";
const unitString = lazy.l10n.formatValueSync(unit, { count: alarmlen });
let originStringName = "reminder-custom-origin";
// Origin
switch (this.related) {
case ALARM_RELATED_START:
originStringName += "Begin";
originStringName += "-begin";
break;
case ALARM_RELATED_END:
originStringName += "End";
originStringName += "-end";
break;
}
if (this.offset.isNegative) {
originStringName += "Before";
originStringName += "-before";
} else {
originStringName += "After";
originStringName += "-after";
}
const originString = cal.l10n.getString("calendar-alarms", alarmString(originStringName));
return cal.l10n.getString("calendar-alarms", "reminderCustomTitle", [
unitString,
originString,
]);
const originString = lazy.l10n.formatValueSync(alarmString(originStringName));
return lazy.l10n.formatValueSync("reminder-custom-title", {
unit: unitString,
reminderCustomOrigin: originString,
});
}
// This is an incomplete alarm, but then again we should never reach
// this state.

Просмотреть файл

@ -19,6 +19,8 @@ export function CalCalendarManager() {
this.providerImplementations = {};
}
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
var calCalendarManagerClassID = Components.ID("{f42585e7-e736-4600-985d-9624c1c51992}");
var calCalendarManagerInterfaces = [Ci.calICalendarManager, Ci.calIStartupService, Ci.nsIObserver];
@ -168,7 +170,9 @@ CalCalendarManager.prototype = {
rc = ex.result;
}
const uiMessage = cal.l10n.getCalString("unableToCreateProvider", [uri.spec]);
const uiMessage = lazy.l10n.formatValueSync("unable-to-create-provider", {
location: uri.spec,
});
// Log the original exception via error console to provide more debug info
cal.ERROR(ex);
@ -817,18 +821,17 @@ calMgrCalendarObserver.prototype = {
const paramBlock = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(
Ci.nsIDialogParamBlock
);
const props = Services.strings.createBundle("chrome://calendar/locale/calendar.properties");
let errMsg;
paramBlock.SetNumberStrings(3);
if (!this.storedReadOnly && this.calendar.readOnly) {
// Major errors change the calendar to readOnly
errMsg = props.formatStringFromName("readOnlyMode", [this.calendar.name]);
errMsg = lazy.l10n.formatValueSync("read-only-mode", { name: this.calendar.name });
} else if (!this.storedReadOnly && !this.calendar.readOnly) {
// Minor errors don't, but still tell the user something went wrong
errMsg = props.formatStringFromName("minorError", [this.calendar.name]);
errMsg = lazy.l10n.formatValueSync("minor-error", { name: this.calendar.name });
} else {
// The calendar was already in readOnly mode, but still tell the user
errMsg = props.formatStringFromName("stillReadOnlyError", [this.calendar.name]);
errMsg = lazy.l10n.formatValueSync("still-read-only-error", { name: this.calendar.name });
}
// When possible, change the error number into its name, to
@ -847,14 +850,14 @@ calMgrCalendarObserver.prototype = {
let message;
switch (aErrNo) {
case calIErrors.CAL_UTF8_DECODING_FAILED:
message = props.GetStringFromName("utf8DecodeError");
message = lazy.l10n.formatValueSync("utf8-decode-error");
break;
case calIErrors.ICS_MALFORMEDDATA:
message = props.GetStringFromName("icsMalformedError");
message = lazy.l10n.formatValueSync("ics-malformed-error");
break;
case calIErrors.MODIFICATION_FAILED:
errMsg = cal.l10n.getCalString("errorWriting2", [aCalendar.name]);
message = cal.l10n.getCalString("errorWritingDetails");
errMsg = lazy.l10n.formatValueSync("error-writing2", { name: aCalendar.name });
message = lazy.l10n.formatValueSync("error-writing-details");
if (aMessage) {
message = aMessage + "\n" + message;
}
@ -868,8 +871,10 @@ calMgrCalendarObserver.prototype = {
paramBlock.SetString(2, message);
this.storedReadOnly = this.calendar.readOnly;
const errorCode = cal.l10n.getCalString("errorCode", [errCode]);
const errorDescription = cal.l10n.getCalString("errorDescription", [message]);
const errorCode = lazy.l10n.formatValueSync("error-code", { errorCode: errCode });
const errorDescription = lazy.l10n.formatValueSync("error-description", {
errorDescription: message,
});
const summary = errMsg + " " + errorCode + ". " + errorDescription;
// Log warnings in error console.

Просмотреть файл

@ -12,6 +12,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
CalRecurrenceInfo: "resource:///modules/CalRecurrenceInfo.sys.mjs",
CalTodo: "resource:///modules/CalTodo.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export function CalIcsParser() {
this.wrappedJSObject = this;
@ -102,8 +103,8 @@ CalIcsParser.prototype = {
// remote subscribed calendars the user cannot change.
if (Cc["@mozilla.org/alerts-service;1"]) {
const notifier = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
const title = cal.l10n.getCalString("TimezoneErrorsAlertTitle");
const text = cal.l10n.getCalString("TimezoneErrorsSeeConsole");
const title = lazy.l10n.formatValueSync("timezone-errors-alert-title");
const text = lazy.l10n.formatValueSync("timezone-errors-see-console");
try {
const alert = Cc["@mozilla.org/alert-notification;1"].createInstance(
Ci.nsIAlertNotification
@ -231,8 +232,12 @@ parserState.prototype = {
// so this UI code can be removed from the parser, and caller can
// choose whether to alert, or show user the problem items and ask
// for fixes, or something else.
const msgArgs = [tzid, item.title, cal.dtz.formatter.formatDateTime(date)];
const msg = cal.l10n.getCalString("unknownTimezoneInItem", msgArgs);
const msgArgs = {
timezone: tzid,
title: item.title,
datetime: cal.dtz.formatter.formatDateTime(date),
};
const msg = lazy.l10n.formatValueSync("unknown-timezone-in-item", msgArgs);
cal.ERROR(msg + "\n" + item.icalString);
this.tzErrors[hid] = true;

Просмотреть файл

@ -4,6 +4,8 @@
import { cal } from "resource:///modules/calendar/calUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* HTML Export Plugin
*/
@ -17,7 +19,7 @@ CalHtmlExporter.prototype = {
getFileTypes() {
const wildmat = "*.html; *.htm";
const label = cal.l10n.getCalString("filterHtml", [wildmat]);
const label = lazy.l10n.formatValueSync("filter-html", { wildmat });
return [
{
QueryInterface: ChromeUtils.generateQI(["calIFileType"]),
@ -31,7 +33,8 @@ CalHtmlExporter.prototype = {
exportToStream(aStream, aItems, aTitle) {
const document = cal.xml.parseFile("chrome://calendar/content/printing/calHtmlExport.html");
const itemContainer = document.getElementById("item-container");
document.getElementById("title").textContent = aTitle || cal.l10n.getCalString("HTMLTitle");
document.getElementById("title").textContent =
aTitle || lazy.l10n.formatValueSync("html-title");
// Sort aItems
aItems.sort((a, b) => {
@ -52,7 +55,7 @@ CalHtmlExporter.prototype = {
const setupTextRow = function (classKey, propValue, prefixKey) {
if (propValue) {
const prefix = cal.l10n.getCalString(prefixKey);
const prefix = lazy.l10n.formatValueSync(prefixKey);
itemNode.querySelector("." + classKey + "key").textContent = prefix;
itemNode.querySelector("." + classKey).textContent = propValue;
} else {
@ -71,7 +74,7 @@ CalHtmlExporter.prototype = {
const endDate = item[cal.dtz.endDateProp(item)];
if (startDate || endDate) {
// This is a task with a start or due date, format accordingly
const prefixWhen = cal.l10n.getCalString("htmlPrefixWhen");
const prefixWhen = lazy.l10n.formatValueSync("html-prefix-when");
itemNode.querySelector(".intervalkey").textContent = prefixWhen;
const startNode = itemNode.querySelector(".dtstart");
@ -91,12 +94,12 @@ CalHtmlExporter.prototype = {
}
const itemTitle = item.isCompleted
? cal.l10n.getCalString("htmlTaskCompleted", [item.title])
? lazy.l10n.formatValueSync("html-task-completed", { task: item.title })
: item.title;
setupTextRow("summary", itemTitle, "htmlPrefixTitle");
setupTextRow("summary", itemTitle, "html-prefix-title");
setupTextRow("location", item.getProperty("LOCATION"), "htmlPrefixLocation");
setupTextRow("description", item.getProperty("DESCRIPTION"), "htmlPrefixDescription");
setupTextRow("location", item.getProperty("LOCATION"), "html-prefix-location");
setupTextRow("description", item.getProperty("DESCRIPTION"), "html-prefix-description");
itemContainer.appendChild(itemNode);
}

Просмотреть файл

@ -2,7 +2,8 @@
* 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 { cal } from "resource:///modules/calendar/calUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
// Shared functions
function getIcsFileTypes() {
@ -11,7 +12,7 @@ function getIcsFileTypes() {
QueryInterface: ChromeUtils.generateQI(["calIFileType"]),
defaultExtension: "ics",
extensionFilter: "*.ics",
description: cal.l10n.getCalString("filterIcs", ["*.ics"]),
description: lazy.l10n.formatValueSync("filter-ics", { wildmat: "*.ics" }),
},
];
}

Просмотреть файл

@ -0,0 +1,68 @@
# 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/.
# LOCALIZATION NOTE (reminder-custom-title):
# $unit = unit, $reminderCustomOrigin = reminderCustomOrigin
# Example: "3 minutes" "before the task starts"
reminder-custom-title = { $unit } { $reminderCustomOrigin }
reminder-title-at-start-event = The moment the event starts
reminder-title-at-start-task = The moment the task starts
reminder-title-at-end-event = The moment the event ends
reminder-title-at-end-task = The moment the task ends
# LOCALIZATION NOTE (reminder-snooze-ok-a11y)
# This string is not seen in the UI, it is read by screen readers when the user
# focuses the "OK" button in the "Snooze for..." popup of the alarm dialog.
# $unit = any of unit*
reminder-snooze-ok-a11y =
.aria-label = Snooze reminder for { $unit }
reminder-custom-origin-begin-before-event = before the event starts
reminder-custom-origin-begin-after-event = after the event starts
reminder-custom-origin-end-before-event = before the event ends
reminder-custom-origin-end-after-event = after the event ends
reminder-custom-origin-begin-before-task = before the task starts
reminder-custom-origin-begin-after-task = after the task starts
reminder-custom-origin-end-before-task = before the task ends
reminder-custom-origin-end-after-task = after the task ends
reminder-custom-origin-begin-before-event-dom =
.label = { reminder-custom-origin-begin-before-event }
reminder-custom-origin-begin-after-event-dom =
.label = { reminder-custom-origin-begin-after-event }
reminder-custom-origin-end-before-event-dom =
.label = { reminder-custom-origin-end-before-event }
reminder-custom-origin-end-after-event-dom =
.label = { reminder-custom-origin-end-after-event }
reminder-custom-origin-begin-before-task-dom =
.label = { reminder-custom-origin-begin-before-task }
reminder-custom-origin-begin-after-task-dom =
.label = { reminder-custom-origin-begin-after-task }
reminder-custom-origin-end-before-task-dom =
.label = { reminder-custom-origin-end-before-task }
reminder-custom-origin-end-after-task-dom =
.label = { reminder-custom-origin-end-after-task }
# $count max count
reminder-error-max-count-reached-event = {
$count ->
[one] The selected calendar has a limitation of { $count } reminder per event.
*[other] The selected calendar has a limitation of { $count } reminders per event.
}
# $count max count
reminder-error-max-count-reached-task = {
$count ->
[one] The selected calendar has a limitation of { $count } reminder per task.
*[other] The selected calendar has a limitation of { $count } reminders per task.
}
# LOCALIZATION NOTE (reminder-readonly-notification)
# This notification will be presented in the alarm dialog if reminders for not
# writable items/calendars are displayed.
# $label - localized value of calendar.alarm.snoozeallfor.label (defined in calendar.dtd)
reminder-readonly-notification = Reminders for read-only calendars currently cannot be snoozed but only dismissed - the button '{ $label }' will only snooze reminders for writable calendars.
# LOCALIZATION NOTE (reminder-disabled-snooze-button-tooltip)
# This tooltip is only displayed, if the button is disabled
reminder-disabled-snooze-button-tooltip =
.tooltiptext = Snoozing of a reminder is not supported for read-only calendars

Просмотреть файл

@ -0,0 +1,22 @@
# 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/.
event-attendee-role-required =
.title = Required Attendee
event-attendee-role-optional =
.title = Optional Attendee
event-attendee-role-nonparticipant =
.title = Non Participant
event-attendee-role-chair =
.title = Chair
# $role
event-attendee-role-unknown =
.title = Unknown Attendee ({ $role })
event-attendee-usertype-individual = Individual
event-attendee-usertype-group = Group
event-attendee-usertype-resource = Resource
event-attendee-usertype-room = Room
# $userType
event-attendee-usertype-unknown = Unknown Type ({ $userType })

Просмотреть файл

@ -10,3 +10,17 @@ calendar-invitation-current-participation-status-icon-declined =
calendar-invitation-current-participation-status-icon-needs-action =
.alt = Currently undecided
allday-event = All day event
recurrent-event =
.value = Repeating event
# $locationProperty is the location of the event
calendar-invitations-location =
.value = Location: { $locationProperty }
# $organizerProperty is the organizer of the event
organizer =
.value = Organizer: { $organizerProperty }
# $attendeeProperty is the attendee of the event
calendar-invitations-attendee =
.value = Attendee: { $attendeeProperty }
calendar-invitations-none = None

Просмотреть файл

@ -0,0 +1,83 @@
# 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/.
header-isrepeating-event =
.label = is a repeating event
header-isrepeating-task =
.label = is a repeating task
header-containsrepeating-event =
.label = contains repeating events
header-containsrepeating-task =
.label = contains repeating tasks
header-containsrepeating-mixed =
.label = contains repeating items of different type
windowtitle-event-copy = Copy Repeating Event
windowtitle-task-copy = Copy Repeating Task
windowtitle-mixed-copy = Copy Repeating Items
windowtitle-event-cut = Cut Repeating Event
windowtitle-task-cut = Cut Repeating Task
windowtitle-mixed-cut = Cut Repeating Items
windowtitle-event-delete = Delete Repeating Event
windowtitle-task-delete = Delete Repeating Task
windowtitle-mixed-delete = Delete Repeating Items
windowtitle-event-edit = Edit Repeating Event
windowtitle-task-edit = Edit Repeating Task
windowtitle-mixed-edit = Edit Repeating Items
windowtitle-multipleitems =
.value = Selected items
buttons-single-occurrence-copy =
.label = Copy only this occurrence
buttons-single-occurrence-cut =
.label = Cut only this occurrence
buttons-single-occurrence-delete =
.label = Delete only this occurrence
buttons-single-occurrence-edit =
.label = Edit only this occurrence
buttons-multiple-occurrence-copy =
.label = Copy only selected occurrences
buttons-multiple-occurrence-cut =
.label = Cut only selected occurrences
buttons-multiple-occurrence-delete =
.label = Delete only selected occurrences
buttons-multiple-occurrence-edit =
.label = Edit only selected occurrences
buttons-single-allfollowing-copy =
.label = Copy this and all future occurrences
buttons-single-allfollowing-cut =
.label = Cut this and all future occurrences
buttons-single-allfollowing-delete =
.label = Delete this and all future occurrences
buttons-single-allfollowing-edit =
.label = Edit this and all future occurrences
buttons-multiple-allfollowing-copy =
.label = Copy selected and all future occurrences
buttons-multiple-allfollowing-cut =
.label = Cut selected and all future occurrences
buttons-multiple-allfollowing-delete =
.label = Delete selected and all future occurrences
buttons-multiple-allfollowing-edit =
.label = Edit selected and all future occurrences
buttons-single-parent-copy =
.label = Copy all occurrences
buttons-single-parent-cut =
.label = Cut all occurrences
buttons-single-parent-delete =
.label = Delete all occurrences
buttons-single-parent-edit =
.label = Edit all occurrences
buttons-multiple-parent-copy =
.label = Copy all occurrences of selected items
buttons-multiple-parent-cut =
.label = Cut all occurrences of selected items
buttons-multiple-parent-delete =
.label = Delete all occurrences of selected items
buttons-multiple-parent-edit =
.label = Edit all occurrences of selected items

Просмотреть файл

@ -0,0 +1,813 @@
# 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/.
# Default name for new events
new-event =
.placeholder = New Event
# Titles for the event/task dialog
new-event-dialog = New Event
edit-event-dialog = Edit Event
new-task-dialog = New Task
edit-task-dialog = Edit Task
# Do you want to save changes?
ask-save-title-event = Save Event
ask-save-title-task = Save Task
ask-save-message-event = Event has not been saved. Do you want to save the event?
ask-save-message-task = Task has not been saved. Do you want to save the task?
# Event Dialog Warnings
warning-end-before-start = The end date you entered occurs before the start date
warning-until-date-before-start = The until date occurs before the start date
# The name of the calendar provided with the application by default
home-calendar-name = Home
# The name given to a calendar if an opened calendar has an empty filename
untitled-calendar-name = Untitled Calendar
# Event status: Tentative, Confirmed, Cancelled
# ToDo task status: NeedsAction, InProcess, Completed, Cancelled
status-tentative = Tentative
status-confirmed = Confirmed
event-status-cancelled = Canceled
todo-status-cancelled = Canceled
status-needs-action = Needs Action
status-in-process = In Process
status-completed = Completed
# Task priority, these should match the priority.level.* labels in calendar.dtd
high-priority = High
normal-priority = Normal
low-priority = Low
import-prompt = Which calendar do you want to import these items into?
export-prompt = Which calendar do you want to export from?
paste-prompt = Which of your currently writable calendars do you want to paste into?
publish-prompt = Which calendar do you want to publish?
# LOCALIZATION NOTE (paste-event-also): The users pasting operation includes among
# others also a meeting invitation - this is used as a affix in
# paste-notify-about
paste-event-also = Your pasting includes a meeting
# LOCALIZATION NOTE (paste-events-also): The users pasting operation includes among
# others also several meeting invitations - this is used as a affix in
# paste-notify-about
paste-events-also = Your pasting includes meetings
# LOCALIZATION NOTE (paste-task-also): The users pasting operation includes among
# others also an assigned task - this is used as a affix in paste-notify-about
paste-task-also = Your pasting includes an assigned task
# LOCALIZATION NOTE (paste-tasks-also): The users pasting operation include among
# others also several assigned tasks - this is used as a affix in
# paste-notify-about
paste-tasks-also = Your pasting includes assigned tasks
# LOCALIZATION NOTE (paste-items-also): The users pasting operation includes among
# others also assigned task(s) and meeting invitation(s) - this is used as a affix
# in paste-notify-about
paste-items-also = Your pasting includes meetings and assigned tasks
# LOCALIZATION NOTE (paste-event-only): The users is pasting a meeting -
# this is used as a affix in paste-notify-about
paste-event-only = You are pasting a meeting
# LOCALIZATION NOTE (paste-events-only): The users is pasting several meetings -
# this is used as a affix in paste-notify-about
paste-events-only = You are pasting meetings
# LOCALIZATION NOTE (paste-event-only): The users is pasting an assigned task -
# this is used as a affix in paste-notify-about
paste-task-only = You are pasting an assigned task
# LOCALIZATION NOTE (paste-events-only): The users is pasting several assigned
# tasks - this is used as a affix in paste-notify-about
paste-tasks-only = You are pasting assigned tasks
# LOCALIZATION NOTE (paste-events-only): The users is pasting assigned task(s) and
# meeting(s) - this is used as a affix in paste-notify-about
paste-items-only = You are pasting meetings and assigned tasks
# LOCALIZATION NOTE (paste-notify-about): Text displayed if pasting an invitation
# or assigned task
# $pasteItem - pasteEvent* or pasteTask*
paste-notify-about = { $pasteItem } - do you want to send an update to everybody involved?
# LOCALIZATION NOTE (paste-and-notify-label): button label used in calendar prompt
# of the pasted item has attendees
paste-and-notify-label = Paste and send now
# LOCALIZATION NOTE (paste-dont-notify-label): button label used in calendar prompt
# of the pasted item has attendees
paste-dont-notify-label = Paste without sending
# LOCALIZATION NOTE (import-items-failed):
# $count will be replaced with number of failed items
# $error will be replaced with last error code / error string
import-items-failed = { $count } items failed to import. The last error was: { $error }
# LOCALIZATION NOTE (no-items-in-calendar-file2):
# $filePath will be replaced with file path
no-items-in-calendar-file2 = Cannot import from { $filePath }. There are no importable items in this file.
# spaces needed at the end of the following lines
event-description = Description:
unable-to-read = Unable to read from file:
# $filePath
unable-to-write = Unable to write to file: { $filePath }
default-file-name = MozillaCalEvents
html-title = Mozilla Calendar
# LOCALIZATION NOTE (timezone-error):
# used for an error message like 'An unknown and undefined timezone was found while reading c:\Mycalendarfile.ics'
# $filePath will be replaced with the path to a file
timezone-error = An unknown and undefined timezone was found while reading { $filePath }.
# LOCALIZATION NOTE (duplicate-error):
# $count will be replaced with number of duplicate items
# $filePath will be replaced with a file path pointing to a calendar
duplicate-error = {
$count ->
[one] { $count } item(s) were ignored since they exist in both the destination calendar and { $filePath }.
*[other] { $count } item(s) were ignored since they exist in both the destination calendar and { $filePath }.
}
# $location unknown calendar location
unable-to-create-provider = An error was encountered preparing the calendar located at { $location } for use. It will not be available.
# Sample: Unknown timezone "USPacific" in "Dentist Appt". Using the 'floating' local timezone instead: 2008/02/28 14:00:00
# $timezone timezone name, $title item title, $datetime date-time
unknown-timezone-in-item = Unknown timezone "{ $timezone }" in "{ $title }". Treated as 'floating' local timezone instead: { $datetime }
timezone-errors-alert-title = Timezone Errors
timezone-errors-see-console = See Error Console: Unknown timezones are treated as the 'floating' local timezone.
# The following strings are for the prompt to delete/unsubscribe from the calendar
remove-calendar-title = Remove Calendar
remove-calendar-button-delete = Delete Calendar
remove-calendar-button-unsubscribe = Unsubscribe
# LOCALIZATION NOTE (remove-calendar-message-delete-or-unsubscribe): Shown for
# calendar where both deleting and unsubscribing is possible.
# $name: The name of a calendar
remove-calendar-message-delete-or-unsubscribe = Do you want to remove the calendar "{ $name }"? Unsubscribing will remove the calendar from the list, deleting will also permanently purge its data.
# LOCALIZATION NOTE (remove-calendar-message-delete): Shown for calendar where
# deleting is the only option.
# $name: The name of a calendar
remove-calendar-message-delete = Do you want to permanently delete the calendar "{ $name }"?
# LOCALIZATION NOTE (remove-calendar-message-unsubscribe): Shown for calendar
# where unsubscribing is the only option.
# $name: The name of a calendar
remove-calendar-message-unsubscribe = Do you want to unsubscribe from the calendar "{ $name }"?
# $title title
week-title = Week { $title }
week-title-label =
.aria-label = Week { $title }
calendar-none =
.label = None
# Error strings
# @name UID_NOT_FOUND
# @loc none
# LOCALIZATION NOTE (too-new-schema-error-text):
# $hostApplication will be replaced with the name of the host application, e.g. 'Thunderbird'
# $fileName will be replaced with the name of the new copy of the file, e.g. 'local-2020-05-11T21-30-17.sqlite'
too-new-schema-error-text = Your calendar data is not compatible with this version of { $hostApplication }. The calendar data in your profile was updated by a newer version of { $hostApplication }. A backup of the data file has been created, named "{ $fileName }". Continuing with a newly created data file.
# List of events or todos (unifinder)
event-untitled = Untitled
# Tooltips of events or todos
tooltip-title = Title:
tooltip-location = Location:
# event date, usually an interval, such as
# Date: 7:00--8:00 Thu 9 Oct 2011
# Date: Thu 9 Oct 2000 -- Fri 10 Oct 2000
tooltip-date = Date:
# event calendar name
tooltip-cal-name = Calendar Name:
# event status: tentative, confirmed, cancelled
tooltip-status = Status:
# event organizer
tooltip-organizer = Organizer:
# task/todo fields
# start date time, due date time, task priority number, completed date time
tooltip-start = Start:
tooltip-due = Due:
tooltip-priority = Priority:
tooltip-percent = % Complete:
tooltip-completed = Completed:
# File commands and dialogs
calendar-new = New
calendar-open = Open
filepicker-title-import = Import
filepicker-title-export = Export
# Filters for export/import/open file picker. $wildmat will be replaced with
# wildmat used to filter files by extension, such as (*.html; *.htm).
filter-ics = iCalendar ({ $wildmat })
# Filters for export/import/open file picker. $wildmat will be replaced with
# wildmat used to filter files by extension, such as (*.html; *.htm).
filter-html = Web Page ({ $wildmat })
# Remote calendar errors
generic-error-title = An error has occurred
# $statusCode $statusCodeInfo status code info
http-put-error =
Publishing the calendar file failed.
Status code: { $statusCode }: { $statusCodeInfo }
# $statusCode status code
other-put-error =
Publishing the calendar file failed.
Status code: 0x{ $statusCode }
# LOCALIZATION NOTE (read-only-mode):
# used for an message like 'There has been an error reading data for calendar: Home. It has been...'
# $name will be replaced with the name of a calendar
read-only-mode = There has been an error reading data for calendar: { $name }. It has been placed in read-only mode, since changes to this calendar will likely result in data-loss. You may change this setting by choosing 'Edit Calendar'.
# LOCALIZATION NOTE (disabled-mode):
# used for an message like 'There has been an error reading data for calendar: Home. It has been...'
# $name will be replaced with the name of a calendar
disabled-mode = There has been an error reading data for calendar: { $name }. It has been disabled until it is safe to use it.
# LOCALIZATION NOTE (minor-error):
# used for an message like 'There has been an error reading data for calendar: Home. However this...'
# $name will be replaced with the name of a calendar
minor-error = There has been an error reading data for calendar: { $name }. However, this error is believed to be minor, so the program will attempt to continue.
# LOCALIZATION NOTE (still-read-only-error):
# used for an message like 'There has been an error reading data for calendar: Home.'
# $name will be replaced with the name of a calendar
still-read-only-error = There has been an error reading data for calendar: { $name }.
utf8-decode-error = An error occurred while decoding an iCalendar (ics) file as UTF-8. Check that the file, including symbols and accented letters, is encoded using the UTF-8 character encoding.
ics-malformed-error = Parsing an iCalendar (ics) file failed. Check that the file conforms to iCalendar (ics) file syntax.
item-modified-on-server-title = Item changed on server
item-modified-on-server = This item has recently been changed on the server.
modify-will-lose-data = Submitting your changes will overwrite the changes made on the server.
delete-will-lose-data = Deleting this item will cause loss of the changes made on the server.
calendar-conflicts-dialog =
.buttonlabelcancel = Discard my changes and reload
proceed-modify =
.label = Submit my changes anyway
proceed-delete =
.label = Delete anyway
# $name calendar name
dav-not-dav = The resource at { $name } is either not a DAV collection or not available
# $name calendar name
dav-dav-not-cal-dav = The resource at { $name } is a DAV collection but not a CalDAV calendar
item-put-error = There was an error storing the item on the server.
item-delete-error = There was an error deleting the item from the server.
cal-dav-request-error = An error occurred when sending the invitation.
cal-dav-response-error = An error occurred when sending the response.
# $statusCode status code
cal-dav-request-status-code = Status Code: { $statusCode }
cal-dav-request-status-code-string-generic = The request cannot be processed.
cal-dav-request-status-code-string-400 = The request contains bad syntax and cannot be processed.
cal-dav-request-status-code-string-403 = The user lacks the required permission to perform the request.
cal-dav-request-status-code-string-404 = Resource not found.
cal-dav-request-status-code-string-409 = Resource conflict.
cal-dav-request-status-code-string-412 = Precondition failed.
cal-dav-request-status-code-string-500 = Internal server error.
cal-dav-request-status-code-string-502 = Bad gateway (Proxy configuration?).
cal-dav-request-status-code-string-503 = Internal server error (Temporary server outage?).
# $name name of calendar
cal-dav-redirect-title = Update location for calendar { $name }?
# $name name of calendar
cal-dav-redirect-text = The requests for { $name } are being redirected to a new location. Would you like to change the location to the following value?
cal-dav-redirect-disable-calendar = Disable Calendar
# LOCALIZATION NOTE (likely-timezone):
# Translators, please put the most likely timezone(s) where the people using
# your locale will be. Use the Olson ZoneInfo timezone name *in English*,
# ie "Europe/Paris", (continent or ocean)/(largest city in timezone).
# Order does not matter, except if two historically different zones now match,
# such as America/New_York and America/Toronto, will only find first listed.
# (Particularly needed to guess the most relevant timezones if there are
# similar timezones at the same June/December GMT offsets with alphabetically
# earlier ZoneInfo timezone names. Sample explanations for English below.)
# for english-US:
# America/Los_Angeles likelier than America/Dawson
# America/New_York likelier than America/Detroit (NY for US-EasternTime)
# for english:
# Europe/London likelier than Atlantic/Canary
# Europe/Paris likelier than Africa/Ceuta (for WestEuropeanTime)
# America/Halifax likelier than America/Glace_Bay (Canada-AtlanticTime)
# America/Mexico_City likelier than America/Cancun
# America/Argentina/Buenos_Aires likelier than America/Araguaina
# America/Sao_Paolo (may not recognize: summer-time dates change every year)
# Asia/Singapore likelier than Antarctica/Casey
# Asia/Tokyo likelier than Asia/Dili
# Africa/Lagos likelier than Africa/Algiers (for WestAfricanTime)
# Africa/Johannesburg likelier than Africa/Blantyre (for SouthAfricanStdTime)
# Africa/Nairobi likelier than Africa/Addis_Ababa (for EastAfricanTime)
# Australia/Brisbane likelier than Antarctica/DumontDUrville
# Australia/Sydney likelier than Australia/Currie or Australia/Hobart
# Pacific/Auckland likelier than Antarctica/McMurdo
likely-timezone = America/New_York, America/Chicago, America/Denver, America/Phoenix, America/Los_Angeles, America/Anchorage, America/Adak, Pacific/Honolulu, America/Puerto_Rico, America/Halifax, America/Mexico_City, America/Argentina/Buenos_Aires, America/Sao_Paulo, Europe/London, Europe/Paris, Asia/Singapore, Asia/Tokyo, Africa/Lagos, Africa/Johannesburg, Africa/Nairobi, Australia/Brisbane, Australia/Sydney, Pacific/Auckland
# Guessed Timezone errors and warnings.
# Testing note:
# * remove preference for calendar.timezone.default in userprofile/prefs.js
# * repeat
# - set OS timezone to a city (windows: click right on clock in taskbar)
# - restart
# - observe guess in error console and verify whether guessed timezone city
# makes sense for OS city.
# 'Warning: Operating system timezone "E. South America Standard Time"
# no longer matches ZoneInfo timezone "America/Sao_Paulo".'
# Testing notes:
# - Brasil DST change dates are set every year by decree, so likely out of sync.
# - Only appears on OSes from which timezone can be obtained
# (windows; or TZ env var, /etc/localtime target path, or line in
# /etc/timezone or /etc/sysconfig/clock contains ZoneInfo timezone id).
# - Windows: turning off "Automatically adjust clock for daylight saving time"
# can also trigger this warning.
# $timezone OS timezone id
# $zoneInfoTimezoneId ZoneInfo timezone id
warning-os-tz-no-match =
Warning: Operating system timezone "{ $timezone }"
no longer matches the internal ZoneInfo timezone "{ $zoneInfoTimezoneId }".
# "Skipping Operating System timezone 'Pacific/New_Country'."
# Testing note: not easily testable. May occur someday if (non-windows)
# OS uses different version of ZoneInfo database which has a timezone name
# that is not included in our current ZoneInfo database (or if the mapping
# mapping from windows to ZoneInfo timezone ids does).
# $timezone OS timezone id
skipping-os-timezone = Skipping Operating System timezone '{ $timezone }'.
# "Skipping locale timezone 'America/New_Yawk'."
# Testing note: Skipping occurs if a likely-timezone id is unknown or misspelled.
# $timezone likely timezone id
skipping-locale-timezone = Skipping locale timezone '{ $timezone }'.
# Testing note: "No match" timezones include Bucharest on W2k.
# Brazil timezones may be "No match" (change every year, so often out of date,
# and changes are often more than a week different).
warning-using-floating-tz-no-match =
Warning: Using "floating" timezone.
No ZoneInfo timezone data matched the operating system timezone data.
# "Warning: Using guessed timezone
# America/New York (UTC-0500/-0400).
# [rfc2445 summer daylight saving shift rules for timezone]
# This ZoneInfo timezone almost matches/seems to match..."
# This ZoneInfo timezone was chosen based on ... "
# $timezone $offset $detail1 $detail2
warning-using-guessedtz =
Warning: Using guessed timezone
{ $timezone } (UTC{ $offset }).
{ $detail1 }
{ $detail2 }
# Testing note: "Almost match" timezones include Cairo on W2k.
tz-almost-matches-os-differ-at-mostaweek =
This ZoneInfo timezone almost matches the operating system timezone.
For this rule, the next transitions between daylight and standard time
differ at most a week from the operating system timezone transitions.
There may be discrepancies in the data, such as differing start date,
or differing rule, or approximation for non-Gregorian-calendar rule.
tz-seems-to-matchos = This ZoneInfo timezone seems to match the operating system timezone this year.
# LOCALIZATION NOTE (tz-fromos):
# used for a display of a chosen timezone
# $timezone will be replaced with the name of a timezone
tz-fromos =
This ZoneInfo timezone was chosen based on the operating system timezone
identifier "{ $timezone }".
# Localization note (tz-from-locale): Substitute name of your locale language.
tz-from-locale =
This ZoneInfo timezone was chosen based on matching the operating system
timezone with likely timezones for internet users using US English.
tz-from-known-timezones =
This ZoneInfo timezone was chosen based on matching the operating system
timezone with known timezones in alphabetical order of timezone id.
# Print Layout
tasks-with-no-due-date = Tasks with no due date
# Providers
cal-dav-name = CalDAV
composite-name = Composite
ics-name-key = iCalendar (ICS)
memory-name = Temporary (memory)
storage-name = Local (SQLite)
# Used in created html code for export
html-prefix-title = Title
html-prefix-when = When
html-prefix-location = Location
html-prefix-description = Description
# $task task
html-task-completed = { $task } (completed)
# Categories
add-category = Add Category
multiple-categories = Multiple Categories
calendar-today = Today
calendar-tomorrow = Tomorrow
yesterday = Yesterday
# Today pane
events-only = Events
events-and-tasks = Events and Tasks
tasks-only = Tasks
short-calendar-week = CW
calendar-go = Go
# Some languages have different conjugations of 'next' and 'last'. If yours
# does not, simply repeat the value. This will be used with day names, as in
# 'next Sunday'.
calendar-next1 = next
calendar-next2 = next
calendar-last1 = last
calendar-last2 = last
# Alarm Dialog
# $count reminder count
alarm-window-title-label =
{ $count ->
[one] { $count } Reminder
*[other] { $count } Reminders
}
# LOCALIZATION NOTE (alarm-starts):
# used for a display the start of an alarm like 'Starts: Thu 2 Oct 2008 13:21'
# $datetime will be replaced with a date-time
alarm-starts =
.value = Starts: { $datetime }
# LOCALIZATION NOTE (alarm-today-at):
# used for a display the date-time of an alarm like 'Today at Thu 2 Oct 2008 13:21'
# $datetime will be replaced with a date-time
alarm-today-at = Today at { $datetime }
# LOCALIZATION NOTE (alarm-tomorrow-at):
# used for a display the date-time of an alarm like 'Tomorrow at Thu 2 Oct 2008 13:21'
# $datetime will be replaced with a date-time
alarm-tomorrow-at = Tomorrow at { $datetime }
# LOCALIZATION NOTE (alarm-yesterday-at):
# used for a display the date-time of an alarm like 'Yesterday at Thu 2 Oct 2008 13:21'
# $datetime will be replaced with a date-time
alarm-yesterday-at = Yesterday at { $datetime }
# Alarm interface strings
# LOCALIZATION NOTE: These strings do not get displayed. They are only visible
# when exporting an item with i.e a DISPLAY alarm, that doesn't have a
# description set, or an EMAIL alarm that doesn't have a summary set.
alarm-default-description = Default Mozilla Description
alarm-default-summary = Default Mozilla Summary
# $count number of months
alarm-snooze-limit-exceeded = {
$count ->
[one] You cannot snooze an alarm for more than { $count } month.
*[other] You cannot snooze an alarm for more than { $count } months.
}
task-details-status-needs-action = Needs Action
# LOCALIZATION NOTE (task-details-status-in-progress):
# used for a display of how much of a task is completed ' Complete'
# $percent will be replaced with the number of percentage completed
task-details-status-in-progress = { $percent }% Complete
task-details-status-completed = Completed
# LOCALIZATION NOTE (task-details-status-completed-on):
# used for a display of completion date like 'Completed on Thu 2 Oct 2008 13:21'
# $datetime will be replaced with the completion date-time of the task
task-details-status-completed-on = Completed on { $datetime }
task-details-status-cancelled = Canceled
getting-calendar-info-common =
.label = Checking Calendars…
# LOCALIZATION NOTE (getting-calendar-info-detail):
# used for a progress-display of processed like 'Checking Calendar 5 of 10'
# $index will be replaced with the index of the currently processed calendar
# $total will be replaced with the total numbers of calendars
getting-calendar-info-detail =
.label = Checking Calendar { $index } of { $total }
# LOCALIZATION NOTE (error-code):
# $errorCode will be replaced with the number of an error code
error-code = Error code: { $errorCode }
# LOCALIZATION NOTE (error-description):
# $errorDescription will be replaced with the description of an error
error-description = Description: { $errorDescription }
# LOCALIZATION NOTE (error-writing):
# used for an message like 'An error occurred when writing to the calendar Home!'
# $name will be replaced with the name of a calendar
error-writing2 = An error occurred when writing to the calendar { $name }! Please see below for more information.
# LOCALIZATION NOTE (error-writing-details):
# This will be displayed in the detail section of the error dialog
error-writing-details = If you're seeing this message after snoozing or dismissing a reminder and this is for a calendar you do not want to add or edit events for, you can mark this calendar as read-only to avoid such experience in future. To do so, get to the calendar properties by right-clicking on this calendar in the list in the calendar or task view.
# LOCALIZATION NOTE (tooltip-calendar-disabled):
# used for an alert-message like 'The calendar Home is momentarily not available'
# $name will be replaced with the name of a calendar
tooltip-calendar-disabled =
.title = The calendar { $name } is momentarily not available
# LOCALIZATION NOTE (tooltip-calendar-read-only):
# used for an message like 'The calendar Home is readonly'
# $name will be replaced with the name of a calendar
tooltip-calendar-read-only =
.title = The calendar { $name } is readonly
task-edit-instructions = Click here to add a new task
task-edit-instructions-readonly = Please select a writable calendar
task-edit-instructions-capability = Please select a calendar that supports tasks
event-details-start-date = Start:
event-details-end-date = End:
# LOCALIZATION NOTE (datetime-with-timezone):
# used for a display of a date-time with timezone 'Thu 2 Oct 2008 13:21', Europe/Paris
# $datetime will be replaced with the completion date-time
# $timezone will be replaced with the name of the timezone
datetime-with-timezone = { $datetime }, { $timezone }
# LOCALIZATION NOTE (single-long-calendar-week):
# used for display of calendar weeks in short form like 'Calendar Week 43'
# $index will be replaced with the index of the week
single-long-calendar-week = Calendar Week: { $index }
# LOCALIZATION NOTE (single-calendar-week):
# used for display of calendar weeks in short form like 'CW 43'
# $index will be replaced with the index of the week
single-calendar-week = CW: { $index }
.title = Calendar Week: { $index }
# LOCALIZATION NOTE (several-calendar-weeks):
# used for display of calendar weeks in short form like 'CWs 43 - 45'
# $startIndex will be replaced with the index of the start-week
# $endIndex will be replaced with the index of the end-week
several-calendar-weeks = CWs: { $startIndex }-{ $endIndex }
.title = Calendar Weeks { $startIndex }-{ $endIndex }
# LOCALIZATION NOTE (multiweek-view-week):
# Used for displaying the week number in the first day box of every week
# in multiweek and month views.
# It allows to localize the label with the week number in case your locale
# requires it.
# Take into account that this label is placed in the same room of the day label
# inside the day boxes, exactly on left side, hence a possible string shouldn't
# be too long otherwise it will create confusion between the week number and
# the day number other than a possible crop when the window is resized.
# $number is a number from 1 to 53 that represents the week number.
multiweek-view-week = W { $number }
# Task tree, "Due In" column.
# LOCALIZATION NOTE (due-in-days, due-in-hours): Semi-colon list of plural
# forms. See: http://developer.mozilla.org/en/Localization_and_Plurals
# $count count
due-in-days = {
$count ->
[one] { $count } day
*[other] { $count } days
}
# $count count
due-in-hours = {
$count ->
[one] { $count } hour
*[other] { $count } hours
}
due-in-less-than-one-hour = < 1 hour
# LOCALIZATION NOTE (month-in-year):
# used for display of Month-dates like 'December 2008'
# $month will be replaced with name of the month
# $year will be replaced with the year
month-in-year = { $month } { $year }
month-in-year-label =
.aria-label = { $month } { $year }
# LOCALIZATION NOTE (month-in-year-month-format):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
month-in-year-month-format = nominative
# LOCALIZATION NOTE (format-date-long):
# used for display dates in long format like 'Mon 15 Oct 2008' when it's
# impossible to retrieve the formatatted date from the OS.
# $dayName will be replaced with name of the day in short format;
# $dayIndex will be replaced with the day-index of the month, possibly followed by an ordinal symbol
# (depending on the string dayOrdinalSymbol in dateFormat.properties);
# $monthName will be replaced with the name of the month in short format;
# $year will be replaced with the year.
format-date-long = { $dayName } { $dayIndex } { $monthName } { $year }
# LOCALIZATION NOTE (day-header):
# used for display the labels in the header of the days in day/week views in short
# or long format. For example: 'Monday 6 Oct.' or 'Mon. 6 Oct.'
# $dayName will be replaced with name of the day in short or long format
# $dayIndex will be replaced with the day-index of the month, possibly followed by an ordinal symbol
# (depending on the string dayOrdinalSymbol in dateFormat.properties), plus the name
# of the month in short format (the day/month order depends on the OS settings).
day-header = { $dayName } { $dayIndex }
day-header-elem =
.label = { day-header }
# LOCALIZATION NOTE (days-interval-in-month):
# used for display of intervals in the form of 'March 3 - 9, 2008'
# $startMonth will be replaced with name of the month of the start date
# $startDayIndex will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# $endDayIndex will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# $year will be replaced with the common year of both dates
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
days-interval-in-month = { $startMonth } { $startDayIndex } – { $endDayIndex }, { $year }
# LOCALIZATION NOTE (days-interval-in-month-month-format):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
days-interval-in-month-month-format = nominative
# LOCALIZATION NOTE (days-interval-between-months):
# used for display of intervals in the form 'September 29 - October 5, 2008'
# $startMonth will be replaced with name of the month of the start date
# $startDayIndex will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# $endMonth will be replaced with name of the month of the end date
# $endDayIndex will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# $year will be replaced with the common year of both dates
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
days-interval-between-months = { $startMonth } { $startDayIndex } – { $endMonth } { $endDayIndex }, { $year }
# LOCALIZATION NOTE (days-interval-between-months-month-format):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
days-interval-between-months-month-format = nominative
# LOCALIZATION NOTE (days-interval-between-years):
# used for display of intervals in the form 'December 29, 2008 - January 4, 2009'
# $startMonth will be replaced with name of the month of the start date
# $startDayIndex will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# $startYear will be replaced with the year of the start date
# $endMonth will be replaced with name of the month of the end date
# $endDayIndex will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# $endYear will be replaced with the year of the end date
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
days-interval-between-years = { $startMonth } { $startDayIndex }, { $startYear } – { $endMonth } { $endDayIndex }, { $endYear }
# LOCALIZATION NOTE (days-interval-between-years-month-format):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
days-interval-between-years-month-format = nominative
# LOCALIZATION NOTE (datetime-interval-on-same-date-time):
# used for intervals where end is equals to start
# displayed form is '5 Jan 2006 13:00'
# $startDate will be replaced with the date of the start date
# $startTime will be replaced with the time of the start date
datetime-interval-on-same-date-time = { $startDate } { $startTime }
# LOCALIZATION NOTE (datetime-interval-on-same-day):
# used for intervals where end is on the same day as start, so we can leave out the
# end date but still include end time
# displayed form is '5 Jan 2006 13:00 - 17:00'
# $startDate will be replaced with the date of the start date
# $startTime will be replaced with the time of the start date
# $endTime will be replaced with the time of the end date
datetime-interval-on-same-day = { $startDate } { $startTime } – { $endTime }
# LOCALIZATION NOTE (datetime-interval-on-several-days):
# used for intervals spanning multiple days by including date and time
# displayed form is '5 Jan 2006 13:00 - 7 Jan 2006 9:00'
# $startDate will be replaced with the date of the start date
# $startTime will be replaced with the time of the start date
# $endDate will be replaced with the date of the end date
# $endTime will be replaced with the time of the end date
datetime-interval-on-several-days = { $startDate } { $startTime } – { $endDate } { $endTime }
# LOCALIZATION NOTE (datetime-interval-task-without-date):
# used for task without start and due date
# (showed only in exported calendar in Html format)
datetime-interval-task-without-date = no start or due date
# LOCALIZATION NOTE (datetime-interval-task-without-due-date):
# used for intervals in task with only start date
# displayed form is 'start date 5 Jan 2006 13:00'
# (showed only in exported calendar in Html format)
# $date will be replaced with the date of the start date
# $time will be replaced with the time of the start date
datetime-interval-task-without-due-date = start date { $date } { $time }
# LOCALIZATION NOTE (datetime-interval-task-without-start-date):
# used for intervals in task with only due date
# displayed form is 'due date 5 Jan 2006 13:00'
# (showed only in exported calendar in Html format)
# $date will be replaced with the date of the due date
# $time will be replaced with the time of the due date
datetime-interval-task-without-start-date = due date { $date } { $time }
# LOCALIZATION NOTE (drag-label-tasks-with-only-entry-date
# drag-label-tasks-with-only-due-date)
# Labels that appear while dragging a task with only
# entry date OR due date
drag-label-tasks-with-only-entry-date = Starting time
drag-label-tasks-with-only-due-date = Due at
delete-task =
.label = Delete Task
.accesskey = l
delete-item =
.label = Delete
.accesskey = l
delete-event =
.label = Delete Event
.accesskey = l
# $count count
calendar-properties-every-minute =
.label = { $count ->
[one] Every minute
*[other] Every { $count } minutes
}
# LOCALIZATION NOTE (extract-using)
# Used in message header
# $languageName will be replaced with language name from languageNames.properties
extract-using = Using { $languageName }
# LOCALIZATION NOTE (extract-using-region)
# Used in message header
# $languageName will be replaced with language name from languageNames.properties
# $region will be replaced with region like US in en-US
extract-using-region = Using { $languageName } ({ $region })
# LOCALIZATION NOTE (unit)
# Used to determine the correct plural form of a unit
# $count count
unit-minutes =
{ $count ->
[one] { $count } minute
*[other] { $count } minutes
}
# $count count
unit-hours =
{ $count ->
[one] { $count } hour
*[other] { $count } hours
}
# $count count
unit-days =
{ $count ->
[one] { $count } day
*[other] { $count } days
}
# $count count
unit-weeks =
{ $count ->
[one] { $count } week
*[other] { $count } weeks
}
# LOCALIZATION NOTE (show-calendar)
# Used in calendar list context menu
# $name will be replaced with the calendar name
# uses the access key calendar.context.togglevisible.accesskey
# $name calendar name
show-calendar = Show { $name }
# $name calendar name
hide-calendar = Hide { $name }
hide-calendar-title =
.title = Show { $name }
show-calendar-title =
.title = Hide { $name }
show-calendar-label =
.label = Show { $name }
hide-calendar-label =
.label = Hide { $name }
# uses the access key calendar.context.showonly.accesskey
# $name calendar name
show-only-calendar =
.label = Show Only { $name }
# LOCALIZATION NOTE (modify-conflict-*)
# Used by the event dialog to resolve item modification conflicts.
modify-conflict-prompt-title = Item Modification Conflict
modify-conflict-prompt-message = The item being edited in the dialog has been modified since it was opened.
modify-conflict-prompt-button1 = Overwrite the other changes
modify-conflict-prompt-button2 = Discard these changes
# Accessible description of a grid calendar with no selected date
minimonth-no-selected-date =
.aria-label = No date selected

Просмотреть файл

@ -2,6 +2,5 @@
# 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/.
# default categories
# default categories, comma separated
categories2=Anniversary,Birthday,Business,Calls,Clients,Competition,Customer,Favorites,Follow up,Gifts,Holidays,Ideas,Issues,Meeting,Miscellaneous,Personal,Projects,Public Holiday,Status,Suppliers,Travel,Vacation

Просмотреть файл

@ -1,39 +0,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 http://mozilla.org/MPL/2.0/.
# LOCALIZATION NOTE (reminderCustomTitle):
# %1$S = unit, %2$S = reminderCustomOrigin
# Example: "3 minutes" "before the task starts"
reminderCustomTitle=%1$S %2$S
reminderTitleAtStartEvent=The moment the event starts
reminderTitleAtStartTask=The moment the task starts
reminderTitleAtEndEvent=The moment the event ends
reminderTitleAtEndTask=The moment the task ends
# LOCALIZATION NOTE (reminderSnoozeOkA11y)
# This string is not seen in the UI, it is read by screen readers when the user
# focuses the "OK" button in the "Snooze for..." popup of the alarm dialog.
# %1$S = any of unit*
reminderSnoozeOkA11y=Snooze reminder for %1$S
reminderCustomOriginBeginBeforeEvent=before the event starts
reminderCustomOriginBeginAfterEvent=after the event starts
reminderCustomOriginEndBeforeEvent=before the event ends
reminderCustomOriginEndAfterEvent=after the event ends
reminderCustomOriginBeginBeforeTask=before the task starts
reminderCustomOriginBeginAfterTask=after the task starts
reminderCustomOriginEndBeforeTask=before the task ends
reminderCustomOriginEndAfterTask=after the task ends
reminderErrorMaxCountReachedEvent=The selected calendar has a limitation of #1 reminder per event.;The selected calendar has a limitation of #1 reminders per event.
reminderErrorMaxCountReachedTask=The selected calendar has a limitation of #1 reminder per task.;The selected calendar has a limitation of #1 reminders per task.
# LOCALIZATION NOTE (reminderReadonlyNotification)
# This notification will be presented in the alarm dialog if reminders for not
# writable items/calendars are displayed.
# %1$S - localized value of calendar.alarm.snoozeallfor.label (defined in calendar.dtd)
reminderReadonlyNotification=Reminders for read-only calendars currently cannot be snoozed but only dismissed - the button '%1$S' will only snooze reminders for writable calendars.
# LOCALIZATION NOTE (reminderDisabledSnoozeButtonTooltip)
# This tooltip is only displayed, if the button is disabled
reminderDisabledSnoozeButtonTooltip=Snoozing of a reminder is not supported for read-only calendars

Просмотреть файл

@ -1,15 +0,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 http://mozilla.org/MPL/2.0/.
event.attendee.role.required = Required Attendee
event.attendee.role.optional = Optional Attendee
event.attendee.role.nonparticipant = Non Participant
event.attendee.role.chair = Chair
event.attendee.role.unknown = Unknown Attendee (%1$S)
event.attendee.usertype.individual = Individual
event.attendee.usertype.group = Group
event.attendee.usertype.resource = Resource
event.attendee.usertype.room = Room
event.attendee.usertype.unknown = Unknown Type (%1$S)

Просмотреть файл

@ -1,10 +0,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 http://mozilla.org/MPL/2.0/.
allday-event=All day event
recurrent-event=Repeating event
location=Location: %S
organizer=Organizer: %S
attendee=Attendee: %S
none=None

Просмотреть файл

@ -1,53 +0,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 http://mozilla.org/MPL/2.0/.
header.isrepeating.event.label=is a repeating event
header.isrepeating.task.label=is a repeating task
header.containsrepeating.event.label=contains repeating events
header.containsrepeating.task.label=contains repeating tasks
header.containsrepeating.mixed.label=contains repeating items of different type
windowtitle.event.copy=Copy Repeating Event
windowtitle.task.copy=Copy Repeating Task
windowtitle.mixed.copy=Copy Repeating Items
windowtitle.event.cut=Cut Repeating Event
windowtitle.task.cut=Cut Repeating Task
windowtitle.mixed.cut=Cut Repeating Items
windowtitle.event.delete=Delete Repeating Event
windowtitle.task.delete=Delete Repeating Task
windowtitle.mixed.delete=Delete Repeating Items
windowtitle.event.edit=Edit Repeating Event
windowtitle.task.edit=Edit Repeating Task
windowtitle.mixed.edit=Edit Repeating Items
windowtitle.multipleitems=Selected items
buttons.single.occurrence.copy.label=Copy only this occurrence
buttons.single.occurrence.cut.label=Cut only this occurrence
buttons.single.occurrence.delete.label=Delete only this occurrence
buttons.single.occurrence.edit.label=Edit only this occurrence
buttons.multiple.occurrence.copy.label=Copy only selected occurrences
buttons.multiple.occurrence.cut.label=Cut only selected occurrences
buttons.multiple.occurrence.delete.label=Delete only selected occurrences
buttons.multiple.occurrence.edit.label=Edit only selected occurrences
buttons.single.allfollowing.copy.label=Copy this and all future occurrences
buttons.single.allfollowing.cut.label=Cut this and all future occurrences
buttons.single.allfollowing.delete.label=Delete this and all future occurrences
buttons.single.allfollowing.edit.label=Edit this and all future occurrences
buttons.multiple.allfollowing.copy.label=Copy selected and all future occurrences
buttons.multiple.allfollowing.cut.label=Cut selected and all future occurrences
buttons.multiple.allfollowing.delete.label=Delete selected and all future occurrences
buttons.multiple.allfollowing.edit.label=Edit selected and all future occurrences
buttons.single.parent.copy.label=Copy all occurrences
buttons.single.parent.cut.label=Cut all occurrences
buttons.single.parent.delete.label=Delete all occurrences
buttons.single.parent.edit.label=Edit all occurrences
buttons.multiple.parent.copy.label=Copy all occurrences of selected items
buttons.multiple.parent.cut.label=Cut all occurrences of selected items
buttons.multiple.parent.delete.label=Delete all occurrences of selected items
buttons.multiple.parent.edit.label=Edit all occurrences of selected items

Просмотреть файл

@ -1,696 +0,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 http://mozilla.org/MPL/2.0/.
# Default name for new events
newEvent=New Event
# Titles for the event/task dialog
newEventDialog=New Event
editEventDialog=Edit Event
newTaskDialog=New Task
editTaskDialog=Edit Task
# Do you want to save changes?
askSaveTitleEvent=Save Event
askSaveTitleTask=Save Task
askSaveMessageEvent=Event has not been saved. Do you want to save the event?
askSaveMessageTask=Task has not been saved. Do you want to save the task?
# Event Dialog Warnings
warningEndBeforeStart=The end date you entered occurs before the start date
warningUntilDateBeforeStart=The until date occurs before the start date
# The name of the calendar provided with the application by default
homeCalendarName=Home
# The name given to a calendar if an opened calendar has an empty filename
untitledCalendarName=Untitled Calendar
# Event status: Tentative, Confirmed, Cancelled
# ToDo task status: NeedsAction, InProcess, Completed, Cancelled
statusTentative =Tentative
statusConfirmed =Confirmed
eventStatusCancelled=Canceled
todoStatusCancelled =Canceled
statusNeedsAction =Needs Action
statusInProcess =In Process
statusCompleted =Completed
# Task priority, these should match the priority.level.* labels in calendar.dtd
highPriority=High
normalPriority=Normal
lowPriority=Low
importPrompt=Which calendar do you want to import these items into?
exportPrompt=Which calendar do you want to export from?
pastePrompt=Which of your currently writable calendars do you want to paste into?
publishPrompt=Which calendar do you want to publish?
# LOCALIZATION NOTE (pasteEventAlso): The users pasting operation includes among
# others also a meeting invitation - this is used as a affix in
# pasteNotifyAbout
pasteEventAlso=Your pasting includes a meeting
# LOCALIZATION NOTE (pasteEventsAlso): The users pasting operation includes among
# others also several meeting invitations - this is used as a affix in
# pasteNotifyAbout
pasteEventsAlso=Your pasting includes meetings
# LOCALIZATION NOTE (pasteTaskAlso): The users pasting operation includes among
# others also an assigned task - this is used as a affix in pasteNotifyAbout
pasteTaskAlso=Your pasting includes an assigned task
# LOCALIZATION NOTE (pasteTasksAlso): The users pasting operation include among
# others also several assigned tasks - this is used as a affix in
# pasteNotifyAbout
pasteTasksAlso=Your pasting includes assigned tasks
# LOCALIZATION NOTE (pasteItemsAlso): The users pasting operation includes among
# others also assigned task(s) and meeting invitation(s) - this is used as a affix
# in pasteNotifyAbout
pasteItemsAlso=Your pasting includes meetings and assigned tasks
# LOCALIZATION NOTE (pasteEventOnly): The users is pasting a meeting -
# this is used as a affix in pasteNotifyAbout
pasteEventOnly=You are pasting a meeting
# LOCALIZATION NOTE (pasteEventsOnly): The users is pasting several meetings -
# this is used as a affix in pasteNotifyAbout
pasteEventsOnly=You are pasting meetings
# LOCALIZATION NOTE (pasteEventOnly): The users is pasting an assigned task -
# this is used as a affix in pasteNotifyAbout
pasteTaskOnly=You are pasting an assigned task
# LOCALIZATION NOTE (pasteEventsOnly): The users is pasting several assigned
# tasks - this is used as a affix in pasteNotifyAbout
pasteTasksOnly=You are pasting assigned tasks
# LOCALIZATION NOTE (pasteEventsOnly): The users is pasting assigned task(s) and
# meeting(s) - this is used as a affix in pasteNotifyAbout
pasteItemsOnly=You are pasting meetings and assigned tasks
# LOCALIZATION NOTE (pasteNotifyAbout): Text displayed if pasting an invitation
# or assigned task
# %1$S - pasteEvent* or pasteTask*
pasteNotifyAbout=%1$S - do you want to send an update to everybody involved?
# LOCALIZATION NOTE (pasteAndNotifyLabel): button label used in calendar prompt
# of the pasted item has attendees
pasteAndNotifyLabel=Paste and send now
# LOCALIZATION NOTE (pasteDontNotifyLabel): button label used in calendar prompt
# of the pasted item has attendees
pasteDontNotifyLabel=Paste without sending
# LOCALIZATION NOTE (importItemsFailed):
# %1$S will be replaced with number of failed items
# %2$S will be replaced with last error code / error string
importItemsFailed=%1$S items failed to import. The last error was: %2$S
# LOCALIZATION NOTE (noItemsInCalendarFile2):
# %1$S will be replaced with file path
noItemsInCalendarFile2=Cannot import from %1$S. There are no importable items in this file.
#spaces needed at the end of the following lines
eventDescription=Description:
unableToRead=Unable to read from file:
unableToWrite=Unable to write to file:
defaultFileName=MozillaCalEvents
HTMLTitle=Mozilla Calendar
# LOCALIZATION NOTE (timezoneError):
# used for an error message like 'An unknown and undefined timezone was found while reading c:\Mycalendarfile.ics'
# %1$S will be replaced with the path to a file
timezoneError=An unknown and undefined timezone was found while reading %1$S.
# LOCALIZATION NOTE (duplicateError):
# %1$S will be replaced with number of duplicate items
# %2$S will be replaced with a file path pointing to a calendar
duplicateError=%1$S item(s) were ignored since they exist in both the destination calendar and %2$S.
unableToCreateProvider=An error was encountered preparing the calendar located at %1$S for use. It will not be available.
# Sample: Unknown timezone "USPacific" in "Dentist Appt". Using the 'floating' local timezone instead: 2008/02/28 14:00:00
unknownTimezoneInItem=Unknown timezone "%1$S" in "%2$S". Treated as 'floating' local timezone instead: %3$S
TimezoneErrorsAlertTitle=Timezone Errors
TimezoneErrorsSeeConsole=See Error Console: Unknown timezones are treated as the 'floating' local timezone.
# The following strings are for the prompt to delete/unsubscribe from the calendar
removeCalendarTitle=Remove Calendar
removeCalendarButtonDelete=Delete Calendar
removeCalendarButtonUnsubscribe=Unsubscribe
# LOCALIZATION NOTE (removeCalendarMessageDeleteOrUnsubscribe): Shown for
# calendar where both deleting and unsubscribing is possible.
# %1$S: The name of a calendar
removeCalendarMessageDeleteOrUnsubscribe=Do you want to remove the calendar "%1$S"? Unsubscribing will remove the calendar from the list, deleting will also permanently purge its data.
# LOCALIZATION NOTE (removeCalendarMessageDelete): Shown for calendar where
# deleting is the only option.
# %1$S: The name of a calendar
removeCalendarMessageDelete=Do you want to permanently delete the calendar "%1$S"?
# LOCALIZATION NOTE (removeCalendarMessageUnsubscribe): Shown for calendar
# where unsubscribing is the only option.
# %1$S: The name of a calendar
removeCalendarMessageUnsubscribe=Do you want to unsubscribe from the calendar "%1$S"?
WeekTitle=Week %1$S
None=None
# Error strings
## @name UID_NOT_FOUND
## @loc none
# LOCALIZATION NOTE (tooNewSchemaErrorText):
# %1$S will be replaced with the name of the host application, e.g. 'Thunderbird'
# %2$S will be replaced with the name of the new copy of the file, e.g. 'local-2020-05-11T21-30-17.sqlite'
tooNewSchemaErrorText=Your calendar data is not compatible with this version of %1$S. The calendar data in your profile was updated by a newer version of %1$S. A backup of the data file has been created, named "%2$S". Continuing with a newly created data file.
# List of events or todos (unifinder)
eventUntitled=Untitled
# Tooltips of events or todos
tooltipTitle=Title:
tooltipLocation=Location:
# event date, usually an interval, such as
# Date: 7:00--8:00 Thu 9 Oct 2011
# Date: Thu 9 Oct 2000 -- Fri 10 Oct 2000
tooltipDate=Date:
# event calendar name
tooltipCalName=Calendar Name:
# event status: tentative, confirmed, cancelled
tooltipStatus=Status:
# event organizer
tooltipOrganizer=Organizer:
# task/todo fields
# start date time, due date time, task priority number, completed date time
tooltipStart=Start:
tooltipDue=Due:
tooltipPriority=Priority:
tooltipPercent=% Complete:
tooltipCompleted=Completed:
#File commands and dialogs
New=New
Open=Open
filepickerTitleImport=Import
filepickerTitleExport=Export
# Filters for export/import/open file picker. %1$S will be replaced with
# wildmat used to filter files by extension, such as (*.html; *.htm).
filterIcs=iCalendar (%1$S)
filterHtml=Web Page (%1$S)
# Remote calendar errors
genericErrorTitle=An error has occurred
httpPutError=Publishing the calendar file failed.\nStatus code: %1$S: %2$S
otherPutError=Publishing the calendar file failed.\nStatus code: 0x%1$S
# LOCALIZATION NOTE (readOnlyMode):
# used for an message like 'There has been an error reading data for calendar: Home. It has been...'
# %1$S will be replaced with the name of a calendar
readOnlyMode=There has been an error reading data for calendar: %1$S. It has been placed in read-only mode, since changes to this calendar will likely result in data-loss. You may change this setting by choosing 'Edit Calendar'.
# LOCALIZATION NOTE (disabledMode):
# used for an message like 'There has been an error reading data for calendar: Home. It has been...'
# %1$S will be replaced with the name of a calendar
disabledMode=There has been an error reading data for calendar: %1$S. It has been disabled until it is safe to use it.
# LOCALIZATION NOTE (minorError):
# used for an message like 'There has been an error reading data for calendar: Home. However this...'
# %1$S will be replaced with the name of a calendar
minorError=There has been an error reading data for calendar: %1$S. However, this error is believed to be minor, so the program will attempt to continue.
# LOCALIZATION NOTE (stillReadOnlyError):
# used for an message like 'There has been an error reading data for calendar: Home.'
# %1$S will be replaced with the name of a calendar
stillReadOnlyError=There has been an error reading data for calendar: %1$S.
utf8DecodeError=An error occurred while decoding an iCalendar (ics) file as UTF-8. Check that the file, including symbols and accented letters, is encoded using the UTF-8 character encoding.
icsMalformedError=Parsing an iCalendar (ics) file failed. Check that the file conforms to iCalendar (ics) file syntax.
itemModifiedOnServerTitle=Item changed on server
itemModifiedOnServer=This item has recently been changed on the server.\n
modifyWillLoseData=Submitting your changes will overwrite the changes made on the server.
deleteWillLoseData=Deleting this item will cause loss of the changes made on the server.
updateFromServer=Discard my changes and reload
proceedModify=Submit my changes anyway
proceedDelete=Delete anyway
dav_notDav=The resource at %1$S is either not a DAV collection or not available
dav_davNotCaldav=The resource at %1$S is a DAV collection but not a CalDAV calendar
itemPutError=There was an error storing the item on the server.
itemDeleteError=There was an error deleting the item from the server.
caldavRequestError=An error occurred when sending the invitation.
caldavResponseError=An error occurred when sending the response.
caldavRequestStatusCode=Status Code: %1$S
caldavRequestStatusCodeStringGeneric=The request cannot be processed.
caldavRequestStatusCodeString400=The request contains bad syntax and cannot be processed.
caldavRequestStatusCodeString403=The user lacks the required permission to perform the request.
caldavRequestStatusCodeString404=Resource not found.
caldavRequestStatusCodeString409=Resource conflict.
caldavRequestStatusCodeString412=Precondition failed.
caldavRequestStatusCodeString500=Internal server error.
caldavRequestStatusCodeString502=Bad gateway (Proxy configuration?).
caldavRequestStatusCodeString503=Internal server error (Temporary server outage?).
caldavRedirectTitle=Update location for calendar %1$S?
caldavRedirectText=The requests for %1$S are being redirected to a new location. Would you like to change the location to the following value?
caldavRedirectDisableCalendar=Disable Calendar
# LOCALIZATION NOTE (likelyTimezone):
# Translators, please put the most likely timezone(s) where the people using
# your locale will be. Use the Olson ZoneInfo timezone name *in English*,
# ie "Europe/Paris", (continent or ocean)/(largest city in timezone).
# Order does not matter, except if two historically different zones now match,
# such as America/New_York and America/Toronto, will only find first listed.
# (Particularly needed to guess the most relevant timezones if there are
# similar timezones at the same June/December GMT offsets with alphabetically
# earlier ZoneInfo timezone names. Sample explanations for English below.)
# for english-US:
# America/Los_Angeles likelier than America/Dawson
# America/New_York likelier than America/Detroit (NY for US-EasternTime)
# for english:
# Europe/London likelier than Atlantic/Canary
# Europe/Paris likelier than Africa/Ceuta (for WestEuropeanTime)
# America/Halifax likelier than America/Glace_Bay (Canada-AtlanticTime)
# America/Mexico_City likelier than America/Cancun
# America/Argentina/Buenos_Aires likelier than America/Araguaina
# America/Sao_Paolo (may not recognize: summer-time dates change every year)
# Asia/Singapore likelier than Antarctica/Casey
# Asia/Tokyo likelier than Asia/Dili
# Africa/Lagos likelier than Africa/Algiers (for WestAfricanTime)
# Africa/Johannesburg likelier than Africa/Blantyre (for SouthAfricanStdTime)
# Africa/Nairobi likelier than Africa/Addis_Ababa (for EastAfricanTime)
# Australia/Brisbane likelier than Antarctica/DumontDUrville
# Australia/Sydney likelier than Australia/Currie or Australia/Hobart
# Pacific/Auckland likelier than Antarctica/McMurdo
likelyTimezone=America/New_York, America/Chicago, America/Denver, America/Phoenix, America/Los_Angeles, America/Anchorage, America/Adak, Pacific/Honolulu, America/Puerto_Rico, America/Halifax, America/Mexico_City, America/Argentina/Buenos_Aires, America/Sao_Paulo, Europe/London, Europe/Paris, Asia/Singapore, Asia/Tokyo, Africa/Lagos, Africa/Johannesburg, Africa/Nairobi, Australia/Brisbane, Australia/Sydney, Pacific/Auckland
# Guessed Timezone errors and warnings.
# Testing note:
# * remove preference for calendar.timezone.default in userprofile/prefs.js
# * repeat
# - set OS timezone to a city (windows: click right on clock in taskbar)
# - restart
# - observe guess in error console and verify whether guessed timezone city
# makes sense for OS city.
#
# 'Warning: Operating system timezone "E. South America Standard Time"
# no longer matches ZoneInfo timezone "America/Sao_Paulo".'
# Testing notes:
# - Brasil DST change dates are set every year by decree, so likely out of sync.
# - Only appears on OSes from which timezone can be obtained
# (windows; or TZ env var, /etc/localtime target path, or line in
# /etc/timezone or /etc/sysconfig/clock contains ZoneInfo timezone id).
# - Windows: turning off "Automatically adjust clock for daylight saving time"
# can also trigger this warning.
WarningOSTZNoMatch=Warning: Operating system timezone "%1$S"\nno longer matches the internal ZoneInfo timezone "%2$S".
# "Skipping Operating System timezone 'Pacific/New_Country'."
# Testing note: not easily testable. May occur someday if (non-windows)
# OS uses different version of ZoneInfo database which has a timezone name
# that is not included in our current ZoneInfo database (or if the mapping
# mapping from windows to ZoneInfo timezone ids does).
SkippingOSTimezone=Skipping Operating System timezone '%1$S'.
# "Skipping locale timezone 'America/New_Yawk'."
# Testing note: Skipping occurs if a likelyTimezone id is unknown or misspelled.
SkippingLocaleTimezone=Skipping locale timezone '%1$S'.
# Testing note: "No match" timezones include Bucharest on W2k.
# Brazil timezones may be "No match" (change every year, so often out of date,
# and changes are often more than a week different).
warningUsingFloatingTZNoMatch=Warning: Using "floating" timezone.\nNo ZoneInfo timezone data matched the operating system timezone data.
# "Warning: Using guessed timezone
# America/New York (UTC-0500/-0400).
# [rfc2445 summer daylight saving shift rules for timezone]
# This ZoneInfo timezone almost matches/seems to match..."
# This ZoneInfo timezone was chosen based on ... "
WarningUsingGuessedTZ=Warning: Using guessed timezone\n %1$S (UTC%2$S).\n%3$S\n%4$S
# Testing note: "Almost match" timezones include Cairo on W2k.
TZAlmostMatchesOSDifferAtMostAWeek=This ZoneInfo timezone almost matches the operating system timezone.\nFor this rule, the next transitions between daylight and standard time\ndiffer at most a week from the operating system timezone transitions.\nThere may be discrepancies in the data, such as differing start date,\nor differing rule, or approximation for non-Gregorian-calendar rule.
TZSeemsToMatchOS=This ZoneInfo timezone seems to match the operating system timezone this year.
# LOCALIZATION NOTE (TZFromOS):
# used for a display of a chosen timezone
# %1$S will be replaced with the name of a timezone
TZFromOS=This ZoneInfo timezone was chosen based on the operating system timezone\nidentifier "%1$S".
# Localization note (TZFromLocale): Substitute name of your locale language.
TZFromLocale=This ZoneInfo timezone was chosen based on matching the operating system\ntimezone with likely timezones for internet users using US English.
TZFromKnownTimezones=This ZoneInfo timezone was chosen based on matching the operating system\ntimezone with known timezones in alphabetical order of timezone id.
# Print Layout
tasksWithNoDueDate = Tasks with no due date
# Providers
caldavName=CalDAV
compositeName=Composite
icsName=iCalendar (ICS)
memoryName=Temporary (memory)
storageName=Local (SQLite)
# Used in created html code for export
htmlPrefixTitle=Title
htmlPrefixWhen=When
htmlPrefixLocation=Location
htmlPrefixDescription=Description
htmlTaskCompleted=%1$S (completed)
# Categories
addCategory=Add Category
multipleCategories=Multiple Categories
today=Today
tomorrow=Tomorrow
yesterday=Yesterday
#Today pane
eventsonly=Events
eventsandtasks=Events and Tasks
tasksonly=Tasks
shortcalendarweek=CW
go=Go
# Some languages have different conjugations of 'next' and 'last'. If yours
# does not, simply repeat the value. This will be used with day names, as in
# 'next Sunday'.
next1=next
next2=next
last1=last
last2=last
# Alarm Dialog
# LOCALIZATION NOTE (alarmWindowTitle.label): Semi-colon list of plural
# forms. See: http://developer.mozilla.org/en/Localization_and_Plurals
alarmWindowTitle.label=#1 Reminder;#1 Reminders
# LOCALIZATION NOTE (alarmStarts):
# used for a display the start of an alarm like 'Starts: Thu 2 Oct 2008 13:21'
# %1$S will be replaced with a date-time
alarmStarts=Starts: %1$S
# LOCALIZATION NOTE (alarmTodayAt):
# used for a display the date-time of an alarm like 'Today at Thu 2 Oct 2008 13:21'
# %1$S will be replaced with a date-time
alarmTodayAt=Today at %1$S
# LOCALIZATION NOTE (alarmTomorrowAt):
# used for a display the date-time of an alarm like 'Tomorrow at Thu 2 Oct 2008 13:21'
# %1$S will be replaced with a date-time
alarmTomorrowAt=Tomorrow at %1$S
# LOCALIZATION NOTE (alarmYesterdayAt):
# used for a display the date-time of an alarm like 'Yesterday at Thu 2 Oct 2008 13:21'
# %1$S will be replaced with a date-time
alarmYesterdayAt=Yesterday at %1$S
# Alarm interface strings
# LOCALIZATION NOTE: These strings do not get displayed. They are only visible
# when exporting an item with i.e a DISPLAY alarm, that doesn't have a
# description set, or an EMAIL alarm that doesn't have a summary set.
alarmDefaultDescription=Default Mozilla Description
alarmDefaultSummary=Default Mozilla Summary
# LOCALIZATION NOTE (alarmSnoozeLimitExceeded): Semi-colon list of plural
# forms.
alarmSnoozeLimitExceeded=You cannot snooze an alarm for more than #1 month.;You cannot snooze an alarm for more than #1 months.
taskDetailsStatusNeedsAction=Needs Action
# LOCALIZATION NOTE (taskDetailsStatusInProgress):
# used for a display of how much of a task is completed '25% Complete'
# %1$S will be replaced with the number of percentage completed
taskDetailsStatusInProgress=%1$S%% Complete
taskDetailsStatusCompleted=Completed
# LOCALIZATION NOTE (taskDetailsStatusCompletedOn):
# used for a display of completion date like 'Completed on Thu 2 Oct 2008 13:21'
# %1$S will be replaced with the completion date-time of the task
taskDetailsStatusCompletedOn=Completed on %1$S
taskDetailsStatusCancelled=Canceled
gettingCalendarInfoCommon=Checking Calendars…
# LOCALIZATION NOTE (gettingCalendarInfoDetail):
# used for a progress-display of processed like 'Checking Calendar 5 of 10'
# %1$S will be replaced with the index of the currently processed calendar
# %2$S will be replaced with the total numbers of calendars
gettingCalendarInfoDetail=Checking Calendar %1$S of %2$S
# LOCALIZATION NOTE (errorCode):
# %1$S will be replaced with the number of an error code
errorCode=Error code: %1$S
# LOCALIZATION NOTE (errorDescription):
# %1$S will be replaced with the description of an error
errorDescription=Description: %1$S
# LOCALIZATION NOTE (errorWriting):
# used for an message like 'An error occurred when writing to the calendar Home!'
# %1$S will be replaced with the name of a calendar
errorWriting2=An error occurred when writing to the calendar %1$S! Please see below for more information.
# LOCALIZATION NOTE (errorWritingDetails):
# This will be displayed in the detail section of the error dialog
errorWritingDetails=If you're seeing this message after snoozing or dismissing a reminder and this is for a calendar you do not want to add or edit events for, you can mark this calendar as read-only to avoid such experience in future. To do so, get to the calendar properties by right-clicking on this calendar in the list in the calendar or task view.
# LOCALIZATION NOTE (tooltipCalendarDisabled):
# used for an alert-message like 'The calendar Home is momentarily not available'
# %1$S will be replaced with the name of a calendar
tooltipCalendarDisabled=The calendar %1$S is momentarily not available
# LOCALIZATION NOTE (tooltipCalendarReadOnly):
# used for an message like 'The calendar Home is readonly'
# %1$S will be replaced with the name of a calendar
tooltipCalendarReadOnly=The calendar %1$S is readonly
taskEditInstructions=Click here to add a new task
taskEditInstructionsReadonly=Please select a writable calendar
taskEditInstructionsCapability=Please select a calendar that supports tasks
eventDetailsStartDate=Start:
eventDetailsEndDate=End:
# LOCALIZATION NOTE (datetimeWithTimezone):
# used for a display of a date-time with timezone 'Thu 2 Oct 2008 13:21', Europe/Paris
# %1$S will be replaced with the completion date-time
# %2$S will be replaced with the name of the timezone
datetimeWithTimezone=%1$S, %2$S
# LOCALIZATION NOTE (singleLongCalendarWeek):
# used for display of calendar weeks in short form like 'Calendar Week 43'
# %1$S will be replaced with the index of the week
singleLongCalendarWeek=Calendar Week: %1$S
# LOCALIZATION NOTE (severalLongCalendarWeeks):
# used for display of calendar weeks in short form like 'Calendar Weeks 43 - 45'
# %1$S will be replaced with the index of the start-week
# %2$S will be replaced with the index of the end-week
severalLongCalendarWeeks=Calendar Weeks %1$S-%2$S
# LOCALIZATION NOTE (singleShortCalendarWeek):
# used for display of calendar weeks in short form like 'CW 43'
# %1$S will be replaced with the index of the week
singleShortCalendarWeek=CW: %1$S
# LOCALIZATION NOTE (severalShortCalendarWeeks):
# used for display of calendar weeks in short form like 'CWs 43 - 45'
# %1$S will be replaced with the index of the start-week
# %2$S will be replaced with the index of the end-week
severalShortCalendarWeeks=CWs: %1$S-%2$S
# LOCALIZATION NOTE (multiweekViewWeek):
# Used for displaying the week number in the first day box of every week
# in multiweek and month views.
# It allows to localize the label with the week number in case your locale
# requires it.
# Take into account that this label is placed in the same room of the day label
# inside the day boxes, exactly on left side, hence a possible string shouldn't
# be too long otherwise it will create confusion between the week number and
# the day number other than a possible crop when the window is resized.
#
# %1$S is a number from 1 to 53 that represents the week number.
multiweekViewWeek=W %1$S
# Task tree, "Due In" column.
# LOCALIZATION NOTE (dueInDays, dueInHours): Semi-colon list of plural
# forms. See: http://developer.mozilla.org/en/Localization_and_Plurals
dueInDays=#1 day;#1 days
dueInHours=#1 hour;#1 hours
dueInLessThanOneHour=< 1 hour
# LOCALIZATION NOTE (monthInYear):
# used for display of Month-dates like 'December 2008'
# %1$S will be replaced with name of the month
# %2$S will be replaced with the year
monthInYear=%1$S %2$S
# LOCALIZATION NOTE (monthInYear.monthFormat):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
monthInYear.monthFormat=nominative
# LOCALIZATION NOTE (formatDateLong):
# used for display dates in long format like 'Mon 15 Oct 2008' when it's
# impossible to retrieve the formatatted date from the OS.
# %1$S will be replaced with name of the day in short format;
# %2$S will be replaced with the day-index of the month, possibly followed by an ordinal symbol
# (depending on the string dayOrdinalSymbol in dateFormat.properties);
# %3$S will be replaced with the name of the month in short format;
# %4$S will be replaced with the year.
formatDateLong=%1$S %2$S %3$S %4$S
# LOCALIZATION NOTE (dayHeaderLabel):
# used for display the labels in the header of the days in day/week views in short
# or long format. For example: 'Monday 6 Oct.' or 'Mon. 6 Oct.'
# %1$S will be replaced with name of the day in short or long format
# %2$S will be replaced with the day-index of the month, possibly followed by an ordinal symbol
# (depending on the string dayOrdinalSymbol in dateFormat.properties), plus the name
# of the month in short format (the day/month order depends on the OS settings).
dayHeaderLabel=%1$S %2$S
# LOCALIZATION NOTE (daysIntervalInMonth):
# used for display of intervals in the form of 'March 3 - 9, 2008'
# %1$S will be replaced with name of the month of the start date
# %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# %3$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# %4$S will be replaced with the common year of both dates
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
daysIntervalInMonth=%1$S %2$S – %3$S, %4$S
# LOCALIZATION NOTE (daysIntervalInMonth.monthFormat):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
daysIntervalInMonth.monthFormat=nominative
# LOCALIZATION NOTE (daysIntervalBetweenMonths):
# used for display of intervals in the form 'September 29 - October 5, 2008'
# %1$S will be replaced with name of the month of the start date
# %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# %3$S will be replaced with name of the month of the end date
# %4$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# %5$S will be replaced with the common year of both dates
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
daysIntervalBetweenMonths=%1$S %2$S – %3$S %4$S, %5$S
# LOCALIZATION NOTE (daysIntervalBetweenMonths.monthFormat):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
daysIntervalBetweenMonths.monthFormat=nominative
# LOCALIZATION NOTE (daysIntervalBetweenYears):
# used for display of intervals in the form 'December 29, 2008 - January 4, 2009'
# %1$S will be replaced with name of the month of the start date
# %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
# %3$S will be replaced with the year of the start date
# %4$S will be replaced with name of the month of the end date
# %5$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
# %6$S will be replaced with the year of the end date
# The presence of the ordinal symbol in the day-indexes depends on the string
# dayOrdinalSymbol in dateFormat.properties
daysIntervalBetweenYears=%1$S %2$S, %3$S – %4$S %5$S, %6$S
# LOCALIZATION NOTE (daysIntervalBetweenYears.monthFormat):
# If your language requires a different declension, change this to
# one of the values specified in dateFormat.properties.
# In any case, DO NOT TRANSLATE.
daysIntervalBetweenYears.monthFormat=nominative
# LOCALIZATION NOTE (datetimeIntervalOnSameDateTime):
# used for intervals where end is equals to start
# displayed form is '5 Jan 2006 13:00'
# %1$S will be replaced with the date of the start date
# %2$S will be replaced with the time of the start date
datetimeIntervalOnSameDateTime=%1$S %2$S
# LOCALIZATION NOTE (datetimeIntervalOnSameDay):
# used for intervals where end is on the same day as start, so we can leave out the
# end date but still include end time
# displayed form is '5 Jan 2006 13:00 - 17:00'
# %1$S will be replaced with the date of the start date
# %2$S will be replaced with the time of the start date
# %3$S will be replaced with the time of the end date
datetimeIntervalOnSameDay=%1$S %2$S – %3$S
# LOCALIZATION NOTE (datetimeIntervalOnSeveralDays):
# used for intervals spanning multiple days by including date and time
# displayed form is '5 Jan 2006 13:00 - 7 Jan 2006 9:00'
# %1$S will be replaced with the date of the start date
# %2$S will be replaced with the time of the start date
# %3$S will be replaced with the date of the end date
# %4$S will be replaced with the time of the end date
datetimeIntervalOnSeveralDays=%1$S %2$S – %3$S %4$S
# LOCALIZATION NOTE (datetimeIntervalTaskWithoutDate):
# used for task without start and due date
# (showed only in exported calendar in Html format)
datetimeIntervalTaskWithoutDate= no start or due date
# LOCALIZATION NOTE (datetimeIntervalTaskWithoutDueDate):
# used for intervals in task with only start date
# displayed form is 'start date 5 Jan 2006 13:00'
# (showed only in exported calendar in Html format)
# %1$S will be replaced with the date of the start date
# %2$S will be replaced with the time of the start date
datetimeIntervalTaskWithoutDueDate=start date %1$S %2$S
# LOCALIZATION NOTE (datetimeIntervalTaskWithoutStartDate):
# used for intervals in task with only due date
# displayed form is 'due date 5 Jan 2006 13:00'
# (showed only in exported calendar in Html format)
# %1$S will be replaced with the date of the due date
# %2$S will be replaced with the time of the due date
datetimeIntervalTaskWithoutStartDate=due date %1$S %2$S
# LOCALIZATION NOTE (dragLabelTasksWithOnlyEntryDate
# dragLabelTasksWithOnlyDueDate)
# Labels that appear while dragging a task with only
# entry date OR due date
dragLabelTasksWithOnlyEntryDate=Starting time
dragLabelTasksWithOnlyDueDate=Due at
deleteTaskLabel=Delete Task
deleteTaskAccesskey=l
deleteItemLabel=Delete
deleteItemAccesskey=l
deleteEventLabel=Delete Event
deleteEventAccesskey=l
calendarPropertiesEveryMinute=Every minute;Every #1 minutes
# LOCALIZATION NOTE (extractUsing)
# Used in message header
# %1$S will be replaced with language name from languageNames.properties
extractUsing=Using %1$S
# LOCALIZATION NOTE (extractUsingRegion)
# Used in message header
# %1$S will be replaced with language name from languageNames.properties
# %2$S will be replaced with region like US in en-US
extractUsingRegion=Using %1$S (%2$S)
# LOCALIZATION NOTE (unit)
# Used to determine the correct plural form of a unit
unitMinutes=#1 minute;#1 minutes
unitHours=#1 hour;#1 hours
unitDays=#1 day;#1 days
unitWeeks=#1 week;#1 weeks
# LOCALIZATION NOTE (showCalendar)
# Used in calendar list context menu
# %1$S will be replaced with the calendar name
# uses the access key calendar.context.togglevisible.accesskey
showCalendar=Show %1$S
hideCalendar=Hide %1$S
# uses the access key calendar.context.showonly.accesskey
showOnlyCalendar=Show Only %1$S
# LOCALIZATION NOTE (modifyConflict)
# Used by the event dialog to resolve item modification conflicts.
modifyConflictPromptTitle=Item Modification Conflict
modifyConflictPromptMessage=The item being edited in the dialog has been modified since it was opened.
modifyConflictPromptButton1=Overwrite the other changes
modifyConflictPromptButton2=Discard these changes
# Accessible description of a grid calendar with no selected date
minimonthNoSelectedDate=No date selected

Просмотреть файл

@ -8,20 +8,14 @@
@AB_CD@.jar:
% locale calendar @AB_CD@ %locale/@AB_CD@/calendar/
locale/@AB_CD@/calendar/calendar-alarms.properties (%chrome/calendar/calendar-alarms.properties)
locale/@AB_CD@/calendar/calendar-event-dialog-attendees.properties (%chrome/calendar/calendar-event-dialog-attendees.properties)
locale/@AB_CD@/calendar/calendar-event-dialog.dtd (%chrome/calendar/calendar-event-dialog.dtd)
locale/@AB_CD@/calendar/calendar-event-dialog.properties (%chrome/calendar/calendar-event-dialog.properties)
locale/@AB_CD@/calendar/calendar-extract.properties (%chrome/calendar/calendar-extract.properties)
locale/@AB_CD@/calendar/calendar-invitations-dialog.dtd (%chrome/calendar/calendar-invitations-dialog.dtd)
locale/@AB_CD@/calendar/calendar-invitations-dialog.properties (%chrome/calendar/calendar-invitations-dialog.properties)
locale/@AB_CD@/calendar/calendar-occurrence-prompt.dtd (%chrome/calendar/calendar-occurrence-prompt.dtd)
locale/@AB_CD@/calendar/calendar-occurrence-prompt.properties (%chrome/calendar/calendar-occurrence-prompt.properties)
locale/@AB_CD@/calendar/calendar.dtd (%chrome/calendar/calendar.dtd)
locale/@AB_CD@/calendar/calendar.properties (%chrome/calendar/calendar.properties)
locale/@AB_CD@/calendar/calendarCreation.dtd (%chrome/calendar/calendarCreation.dtd)
locale/@AB_CD@/calendar/calendarCreation.properties (%chrome/calendar/calendarCreation.properties)
locale/@AB_CD@/calendar/categories.properties (%chrome/calendar/categories.properties)
locale/@AB_CD@/calendar/dateFormat.properties (%chrome/calendar/dateFormat.properties)
locale/@AB_CD@/calendar/dialogs/calendar-event-dialog-reminder.dtd (%chrome/calendar/dialogs/calendar-event-dialog-reminder.dtd)
locale/@AB_CD@/calendar/global.dtd (%chrome/calendar/global.dtd)

Просмотреть файл

@ -28,7 +28,8 @@ var XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>\n';
var MIME_TEXT_XML = "text/xml; charset=utf-8";
var cIOL = Ci.calIOperationListener;
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export function CalDavCalendar() {
this.initProviderBase();
this.unmappedProperties = [];
@ -1942,11 +1943,11 @@ CalDavCalendar.prototype = {
*/
reportDavError(aErrNo, status, extraInfo) {
const mapError = {};
mapError[Ci.calIErrors.DAV_NOT_DAV] = "dav_notDav";
mapError[Ci.calIErrors.DAV_DAV_NOT_CALDAV] = "dav_davNotCaldav";
mapError[Ci.calIErrors.DAV_PUT_ERROR] = "itemPutError";
mapError[Ci.calIErrors.DAV_REMOVE_ERROR] = "itemDeleteError";
mapError[Ci.calIErrors.DAV_REPORT_ERROR] = "disabledMode";
mapError[Ci.calIErrors.DAV_NOT_DAV] = "dav-not-dav";
mapError[Ci.calIErrors.DAV_DAV_NOT_CALDAV] = "dav-dav-not-cal-dav";
mapError[Ci.calIErrors.DAV_PUT_ERROR] = "item-put-error";
mapError[Ci.calIErrors.DAV_REMOVE_ERROR] = "item-delete-error";
mapError[Ci.calIErrors.DAV_REPORT_ERROR] = "disabled-mode";
const mapModification = {};
mapModification[Ci.calIErrors.DAV_NOT_DAV] = false;
@ -1962,7 +1963,7 @@ CalDavCalendar.prototype = {
// Only notify if there is a message for this error
return;
}
const localizedMessage = cal.l10n.getCalString(message, [this.mUri.spec]);
const localizedMessage = lazy.l10n.formatValueSync(message, { name: this.mUri.spec });
this.mDisabledByDavError = true;
this.notifyError(aErrNo, localizedMessage);
this.notifyError(
@ -1976,16 +1977,15 @@ CalDavCalendar.prototype = {
return "";
}
const props = Services.strings.createBundle("chrome://calendar/locale/calendar.properties");
let statusString;
try {
statusString = props.GetStringFromName("caldavRequestStatusCodeString" + status);
statusString = lazy.l10n.formatValueSync(`cal-dav-request-status-code-string-${status}`);
} catch (e) {
// Fallback on generic string if no string is defined for the status code
statusString = props.GetStringFromName("caldavRequestStatusCodeStringGeneric");
statusString = lazy.l10n.formatValueSync("cal-dav-request-status-code-string-generic");
}
return (
props.formatStringFromName("caldavRequestStatusCode", [status]) +
lazy.l10n.formatValueSync("cal-dav-request-status-code", { statusCode: status }) +
", " +
statusString +
"\n\n" +

Просмотреть файл

@ -9,6 +9,8 @@ import { DNS } from "resource:///modules/DNS.sys.mjs";
import { CalDavPropfindRequest } from "resource:///modules/caldav/CalDavRequest.sys.mjs";
import { CalDavDetectionSession } from "resource:///modules/caldav/CalDavSession.sys.mjs";
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
// NOTE: This module should not be loaded directly, it is available when
// including calUtils.sys.mjs under the cal.provider.caldav namespace.
@ -23,7 +25,7 @@ export var CalDavProvider = {
},
get displayName() {
return cal.l10n.getCalString("caldavName");
return lazy.l10n.formatValueSync("cal-dav-name");
},
get shortName() {

Просмотреть файл

@ -13,7 +13,8 @@ import {
// NOTE: This module should not be loaded directly, it is available when
// including calUtils.sys.mjs under the cal.provider.ics namespace.
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
/**
* @implements {calICalendarProvider}
*/
@ -25,7 +26,7 @@ export var CalICSProvider = {
},
get displayName() {
return cal.l10n.getCalString("icsName");
return lazy.l10n.formatValueSync("ics-name-key");
},
get shortName() {

Просмотреть файл

@ -7,7 +7,8 @@ import { cal } from "resource:///modules/calendar/calUtils.sys.mjs";
import { CalReadableStreamFactory } from "resource:///modules/CalReadableStreamFactory.sys.mjs";
var cICL = Ci.calIChangeLog;
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export function CalMemoryCalendar() {
this.initProviderBase();
this.initMemoryCalendar();
@ -49,7 +50,7 @@ CalMemoryCalendar.prototype = {
//
get displayName() {
return cal.l10n.getCalString("memoryName");
return lazy.l10n.formatValueSync("memory-name");
},
get shortName() {

Просмотреть файл

@ -12,7 +12,8 @@ import { upgradeDB } from "resource:///modules/calendar/calStorageUpgrade.sys.mj
const kCalICalendar = Ci.calICalendar;
const cICL = Ci.calIChangeLog;
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
export function CalStorageCalendar() {
this.initProviderBase();
}
@ -49,7 +50,7 @@ CalStorageCalendar.prototype = {
//
get displayName() {
return cal.l10n.getCalString("storageName");
return lazy.l10n.formatValueSync("storage-name");
},
get shortName() {

Просмотреть файл

@ -76,7 +76,7 @@ import {
} from "resource:///modules/calendar/calStorageHelpers.sys.mjs";
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true));
ChromeUtils.defineESModuleGetters(lazy, {
CalAlarm: "resource:///modules/CalAlarm.sys.mjs",
CalAttachment: "resource:///modules/CalAttachment.sys.mjs",
@ -292,7 +292,10 @@ function handleTooNewSchema(storageCalendar) {
storageCalendar.db.close();
const appName = cal.l10n.getAnyString("branding", "brand", "brandShortName");
const errorText = cal.l10n.getCalString("tooNewSchemaErrorText", [appName, copyFileName]);
const errorText = lazy.l10n.formatValueSync("too-new-schema-error-text", {
hostApplication: appName,
fileName: copyFileName,
});
cal.ERROR(errorText);
storageCalendar.prepareInitDB();

Просмотреть файл

@ -12,6 +12,7 @@ var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.
ChromeUtils.defineESModuleGetters(this, {
CalEvent: "resource:///modules/CalEvent.sys.mjs",
});
const l10n = new Localization(["calendar/categories.ftl"], true);
const EVENTTITLE = "Event";
const EVENTLOCATION = "Location";
@ -85,7 +86,7 @@ add_task(async function testEventDialog() {
Assert.equal(iframeDocument.getElementById("item-title").placeholder, defTitle);
// Prepare category.
const categories = cal.l10n.getAnyString("calendar", "categories", "categories2");
const categories = l10n.formatValueSync("categories2");
// Pick 4th value in a comma-separated list.
const category = categories.split(",")[4];
// Calculate date to repeat until.

Просмотреть файл

@ -20,7 +20,7 @@ calendar.setProperty("organizerId", "mailto:pillow@example.com");
registerCleanupFunction(() => {
CalendarTestUtils.removeCalendar(calendar);
});
const l10n = new Localization(["calendar/categories.ftl"], true);
// Test that closing an event dialog with no changes does not prompt for save.
add_task(async function testEventDialogModificationPrompt() {
await CalendarTestUtils.setCalendarView(window, "day");
@ -30,7 +30,7 @@ add_task(async function testEventDialogModificationPrompt() {
// Create new event.
let { dialogWindow, iframeWindow } = await CalendarTestUtils.editNewEvent(window, createbox);
const categories = cal.l10n.getAnyString("calendar", "categories", "categories2").split(",");
const categories = l10n.formatValueSync("categories2").split(",");
data[0].categories.push(categories[0]);
data[1].categories.push(categories[1], categories[2]);

Просмотреть файл

@ -15,8 +15,7 @@ var { cancelItemDialog } = ChromeUtils.importESModule(
"resource://testing-common/calendar/ItemEditingHelpers.sys.mjs"
);
var { PluralForm } = ChromeUtils.importESModule("resource:///modules/PluralForm.sys.mjs");
const l10n = new Localization(["calendar/calendar.ftl", "calendar/calendar-alarms.ftl"], true);
const DEFVALUE = 43;
add_task(async function testDefaultAlarms() {
@ -26,13 +25,17 @@ add_task(async function testDefaultAlarms() {
CalendarTestUtils.removeCalendar(calendar);
});
const localeUnitString = cal.l10n.getCalString("unitDays");
const unitString = PluralForm.get(DEFVALUE, localeUnitString).replace("#1", DEFVALUE);
const alarmString = (...args) => cal.l10n.getString("calendar-alarms", ...args);
const originStringEvent = alarmString("reminderCustomOriginBeginBeforeEvent");
const originStringTask = alarmString("reminderCustomOriginBeginBeforeTask");
const expectedEventReminder = alarmString("reminderCustomTitle", [unitString, originStringEvent]);
const expectedTaskReminder = alarmString("reminderCustomTitle", [unitString, originStringTask]);
const unitString = l10n.formatValueSync("unit-days", { count: DEFVALUE });
const originStringEvent = l10n.formatValueSync("reminder-custom-origin-begin-before-event");
const originStringTask = l10n.formatValueSync("reminder-custom-origin-begin-before-task");
const expectedEventReminder = l10n.formatValueSync("reminder-custom-title", {
unit: unitString,
reminderCustomOrigin: originStringEvent,
});
const expectedTaskReminder = l10n.formatValueSync("reminder-custom-title", {
unit: unitString,
reminderCustomOrigin: originStringTask,
});
// Configure the preferences.
const { prefsWindow, prefsDocument } = await openNewPrefsTab(

Просмотреть файл

@ -90,6 +90,7 @@
<link rel="localization" href="messenger/appmenu.ftl" />
<link rel="localization" href="messenger/openpgp/openpgp.ftl" />
<link rel="localization" href="messenger/openpgp/openpgp-frontend.ftl" />
<link rel="localization" href="calendar/calendar.ftl"/>
<script defer="defer" src="chrome://messenger/content/globalOverlay.js"></script>
<script defer="defer" src="chrome://messenger/content/mailWindow.js"></script>

Просмотреть файл

@ -100,6 +100,7 @@
<link rel="localization" href="messenger/openpgp/openpgp.ftl" />
<link rel="localization" href="messenger/openpgp/openpgp-frontend.ftl" />
<link rel="localization" href="messenger/openpgp/msgReadStatus.ftl"/>
<link rel="localization" href="calendar/calendar.ftl" />
<link rel="localization" href="calendar/calendar-today-pane.ftl" />
<link rel="localization" href="calendar/calendar-widgets.ftl" />
<link rel="localization" href="calendar/calendar-context-menus.ftl" />

Просмотреть файл

@ -15,6 +15,11 @@ ChromeUtils.defineLazyGetter(lazy, "gMailBundle", function () {
"chrome://messenger/locale/messenger.properties"
);
});
ChromeUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["calendar/calendar.ftl"], true)
);
if (AppConstants.NIGHTLY_BUILD) {
ChromeUtils.defineLazyGetter(
@ -1145,7 +1150,7 @@ function reportAddressBookTypes() {
*/
async function reportCalendars() {
const telemetryReport = {};
const home = lazy.cal.l10n.getCalString("homeCalendarName");
const home = lazy.l10n.formatValueSync("home-calendar-name");
for (const calendar of lazy.cal.manager.getCalendars()) {
if (calendar.name == home && calendar.type == "storage") {

Просмотреть файл

@ -0,0 +1,129 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
from fluent.migratetb.helpers import VARIABLE_REFERENCE
from fluent.migratetb.transforms import Transform, TransformPattern, PLURALS, REPLACE_IN_TEXT
replacements_label = dict({"%1$S": VARIABLE_REFERENCE("label")})
replacements_unit = dict({"%1$S": VARIABLE_REFERENCE("unit")})
replacements_unit_reminderCustomOrigin = dict(
{"%1$S": VARIABLE_REFERENCE("unit"), "%2$S": VARIABLE_REFERENCE("reminderCustomOrigin")}
)
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 2. part {index}"""
target = reference = "calendar/calendar/calendar-alarms.ftl"
source = "calendar/chrome/calendar/calendar-alarms.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
reminder-custom-title = {REPLACE(from_path, "reminderCustomTitle", replacements_unit_reminderCustomOrigin)}
reminder-title-at-start-event = {COPY(from_path, "reminderTitleAtStartEvent")}
reminder-title-at-start-task = {COPY(from_path, "reminderTitleAtStartTask")}
reminder-title-at-end-event = {COPY(from_path, "reminderTitleAtEndEvent")}
reminder-title-at-end-task = {COPY(from_path, "reminderTitleAtEndTask")}
reminder-snooze-ok-a11y =
.aria-label = {REPLACE(from_path, "reminderSnoozeOkA11y", replacements_unit)}
reminder-custom-origin-begin-before-event = {COPY(from_path, "reminderCustomOriginBeginBeforeEvent")}
reminder-custom-origin-begin-after-event = {COPY(from_path, "reminderCustomOriginBeginAfterEvent")}
reminder-custom-origin-end-before-event = {COPY(from_path, "reminderCustomOriginEndBeforeEvent")}
reminder-custom-origin-end-after-event = {COPY(from_path, "reminderCustomOriginEndAfterEvent")}
reminder-custom-origin-begin-before-task = {COPY(from_path, "reminderCustomOriginBeginBeforeTask")}
reminder-custom-origin-begin-after-task = {COPY(from_path, "reminderCustomOriginBeginAfterTask")}
reminder-custom-origin-end-before-task = {COPY(from_path, "reminderCustomOriginEndBeforeTask")}
reminder-custom-origin-end-after-task = {COPY(from_path, "reminderCustomOriginEndAfterTask")}
reminder-custom-origin-begin-before-event-dom =
.label = { reminder-custom-origin-begin-before-event }
reminder-custom-origin-begin-after-event-dom =
.label = { reminder-custom-origin-begin-after-event }
reminder-custom-origin-end-before-event-dom =
.label = { reminder-custom-origin-end-before-event }
reminder-custom-origin-end-after-event-dom =
.label = { reminder-custom-origin-end-after-event }
reminder-custom-origin-begin-before-task-dom =
.label = { reminder-custom-origin-begin-before-task }
reminder-custom-origin-begin-after-task-dom =
.label = { reminder-custom-origin-begin-after-task }
reminder-custom-origin-end-before-task-dom =
.label = { reminder-custom-origin-end-before-task }
reminder-custom-origin-end-after-task-dom =
.label = { reminder-custom-origin-end-after-task }
""",
from_path=source,
replacements_unit=replacements_unit,
replacements_unit_reminderCustomOrigin=replacements_unit_reminderCustomOrigin,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("reminder-error-max-count-reached-event"),
value=PLURALS(
source,
"reminderErrorMaxCountReachedEvent",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("reminder-error-max-count-reached-task"),
value=PLURALS(
source,
"reminderErrorMaxCountReachedTask",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
reminder-readonly-notification = {REPLACE(from_path, "reminderReadonlyNotification", replacements_label)}
reminder-disabled-snooze-button-tooltip =
.tooltiptext = {COPY(from_path, "reminderDisabledSnoozeButtonTooltip")}
""",
from_path=source,
replacements_label=replacements_label,
replacements_unit=replacements_unit,
replacements_unit_reminderCustomOrigin=replacements_unit_reminderCustomOrigin,
),
)

Просмотреть файл

@ -0,0 +1,858 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
from fluent.migratetb.helpers import VARIABLE_REFERENCE
from fluent.migratetb.transforms import Transform, TransformPattern, PLURALS, REPLACE_IN_TEXT
replacements_count_error = dict(
{"%1$S": VARIABLE_REFERENCE("count"), "%2$S": VARIABLE_REFERENCE("error")}
)
replacements_date_time = dict(
{"%1$S": VARIABLE_REFERENCE("date"), "%2$S": VARIABLE_REFERENCE("time")}
)
replacements_datetime = dict({"%1$S": VARIABLE_REFERENCE("datetime")})
replacements_datetime_timezone = dict(
{"%1$S": VARIABLE_REFERENCE("datetime"), "%2$S": VARIABLE_REFERENCE("timezone")}
)
replacements_dayName_dayIndex = dict(
{"%1$S": VARIABLE_REFERENCE("dayName"), "%2$S": VARIABLE_REFERENCE("dayIndex")}
)
replacements_dayName_dayIndex_monthName_year = dict(
{
"%1$S": VARIABLE_REFERENCE("dayName"),
"%2$S": VARIABLE_REFERENCE("dayIndex"),
"%3$S": VARIABLE_REFERENCE("monthName"),
"%4$S": VARIABLE_REFERENCE("year"),
}
)
replacements_errorCode = dict({"%1$S": VARIABLE_REFERENCE("errorCode")})
replacements_errorDescription = dict({"%1$S": VARIABLE_REFERENCE("errorDescription")})
replacements_filePath = dict({"%1$S": VARIABLE_REFERENCE("filePath")})
replacements_hostApplication_fileName = dict(
{
"%1$S": VARIABLE_REFERENCE("hostApplication"),
"%2$S": VARIABLE_REFERENCE("fileName"),
}
)
replacements_index = dict({"%1$S": VARIABLE_REFERENCE("index")})
replacements_index_total = dict(
{"%1$S": VARIABLE_REFERENCE("index"), "%2$S": VARIABLE_REFERENCE("total")}
)
replacements_languageName = dict({"%1$S": VARIABLE_REFERENCE("languageName")})
replacements_languageName_region = dict(
{"%1$S": VARIABLE_REFERENCE("languageName"), "%2$S": VARIABLE_REFERENCE("region")}
)
replacements_location = dict({"%1$S": VARIABLE_REFERENCE("location")})
replacements_month_year = dict(
{"%1$S": VARIABLE_REFERENCE("month"), "%2$S": VARIABLE_REFERENCE("year")}
)
replacements_name = dict({"%1$S": VARIABLE_REFERENCE("name")})
replacements_number = dict({"%1$S": VARIABLE_REFERENCE("number")})
replacements_pasteItem = dict({"%1$S": VARIABLE_REFERENCE("pasteItem")})
replacements_percent = dict({"%1$S": VARIABLE_REFERENCE("percent")})
replacements_startDate_startTime = dict(
{"%1$S": VARIABLE_REFERENCE("startDate"), "%2$S": VARIABLE_REFERENCE("startTime")}
)
replacements_startDate_startTime_endDate_endTime = dict(
{
"%1$S": VARIABLE_REFERENCE("startDate"),
"%2$S": VARIABLE_REFERENCE("startTime"),
"%3$S": VARIABLE_REFERENCE("endDate"),
"%4$S": VARIABLE_REFERENCE("endTime"),
}
)
replacements_startDate_startTime_endTime = dict(
{
"%1$S": VARIABLE_REFERENCE("startDate"),
"%2$S": VARIABLE_REFERENCE("startTime"),
"%3$S": VARIABLE_REFERENCE("endTime"),
}
)
replacements_startIndex_endIndex = dict(
{"%1$S": VARIABLE_REFERENCE("startIndex"), "%2$S": VARIABLE_REFERENCE("endIndex")}
)
replacements_startMonth_startDayIndex_endDayIndex_year = dict(
{
"%1$S": VARIABLE_REFERENCE("startMonth"),
"%2$S": VARIABLE_REFERENCE("startDayIndex"),
"%3$S": VARIABLE_REFERENCE("endDayIndex"),
"%4$S": VARIABLE_REFERENCE("year"),
}
)
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year = dict(
{
"%1$S": VARIABLE_REFERENCE("startMonth"),
"%2$S": VARIABLE_REFERENCE("startDayIndex"),
"%3$S": VARIABLE_REFERENCE("endMonth"),
"%4$S": VARIABLE_REFERENCE("endDayIndex"),
"%5$S": VARIABLE_REFERENCE("year"),
}
)
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear = dict(
{
"%1$S": VARIABLE_REFERENCE("startMonth"),
"%2$S": VARIABLE_REFERENCE("startDayIndex"),
"%3$S": VARIABLE_REFERENCE("startYear"),
"%4$S": VARIABLE_REFERENCE("endMonth"),
"%5$S": VARIABLE_REFERENCE("endDayIndex"),
"%6$S": VARIABLE_REFERENCE("endYear"),
}
)
replacements_statusCode = dict({"%1$S": VARIABLE_REFERENCE("statusCode")})
replacements_task = dict({"%1$S": VARIABLE_REFERENCE("task")})
replacements_timezone = dict({"%1$S": VARIABLE_REFERENCE("timezone")})
replacements_timezone_title_datetime = dict(
{
"%1$S": VARIABLE_REFERENCE("timezone"),
"%2$S": VARIABLE_REFERENCE("title"),
"%3$S": VARIABLE_REFERENCE("datetime"),
}
)
replacements_title = dict({"%1$S": VARIABLE_REFERENCE("title")})
replacements_wildmat = dict({"%1$S": VARIABLE_REFERENCE("wildmat")})
replacements_timezone_offset_detail1_detail2 = dict(
{
"%1$S": VARIABLE_REFERENCE("timezone"),
"%2$S": VARIABLE_REFERENCE("offset"),
"%3$S": VARIABLE_REFERENCE("detail1"),
"%4$S": VARIABLE_REFERENCE("detail2"),
}
)
replacements_timezone_zoneInfoTimezoneId = dict(
{
"%1$S": VARIABLE_REFERENCE("timezone"),
"%2$S": VARIABLE_REFERENCE("zoneInfoTimezoneId"),
}
)
replacements_statusCode_statusCodeInfo = dict(
{
"%1$S": VARIABLE_REFERENCE("statusCode"),
"%2$S": VARIABLE_REFERENCE("statusCodeInfo"),
}
)
replacements_count_filePath = dict(
{"%1$S": VARIABLE_REFERENCE("count"), "%2$S": VARIABLE_REFERENCE("filePath")}
)
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 2. part {index}"""
target = reference = "calendar/calendar/calendar.ftl"
source = "calendar/chrome/calendar/calendar.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
new-event =
.placeholder = {COPY(from_path, "newEvent")}
new-event-dialog = {COPY(from_path, "newEventDialog")}
edit-event-dialog = {COPY(from_path, "editEventDialog")}
new-task-dialog = {COPY(from_path, "newTaskDialog")}
edit-task-dialog = {COPY(from_path, "editTaskDialog")}
ask-save-title-event = {COPY(from_path, "askSaveTitleEvent")}
ask-save-title-task = {COPY(from_path, "askSaveTitleTask")}
ask-save-message-event = {COPY(from_path, "askSaveMessageEvent")}
ask-save-message-task = {COPY(from_path, "askSaveMessageTask")}
warning-end-before-start = {COPY(from_path, "warningEndBeforeStart")}
warning-until-date-before-start = {COPY(from_path, "warningUntilDateBeforeStart")}
home-calendar-name = {COPY(from_path, "homeCalendarName")}
untitled-calendar-name = {COPY(from_path, "untitledCalendarName")}
status-tentative = {COPY(from_path, "statusTentative")}
status-confirmed = {COPY(from_path, "statusConfirmed")}
event-status-cancelled = {COPY(from_path, "eventStatusCancelled")}
todo-status-cancelled = {COPY(from_path, "todoStatusCancelled")}
status-needs-action = {COPY(from_path, "statusNeedsAction")}
status-in-process = {COPY(from_path, "statusInProcess")}
status-completed = {COPY(from_path, "statusCompleted")}
high-priority = {COPY(from_path, "highPriority")}
normal-priority = {COPY(from_path, "normalPriority")}
low-priority = {COPY(from_path, "lowPriority")}
import-prompt = {COPY(from_path, "importPrompt")}
export-prompt = {COPY(from_path, "exportPrompt")}
paste-prompt = {COPY(from_path, "pastePrompt")}
publish-prompt = {COPY(from_path, "publishPrompt")}
paste-event-also = {COPY(from_path, "pasteEventAlso")}
paste-events-also = {COPY(from_path, "pasteEventsAlso")}
paste-task-also = {COPY(from_path, "pasteTaskAlso")}
paste-tasks-also = {COPY(from_path, "pasteTasksAlso")}
paste-items-also = {COPY(from_path, "pasteItemsAlso")}
paste-event-only = {COPY(from_path, "pasteEventOnly")}
paste-events-only = {COPY(from_path, "pasteEventsOnly")}
paste-task-only = {COPY(from_path, "pasteTaskOnly")}
paste-tasks-only = {COPY(from_path, "pasteTasksOnly")}
paste-items-only = {COPY(from_path, "pasteItemsOnly")}
paste-notify-about = {REPLACE(from_path, "pasteNotifyAbout", replacements_pasteItem)}
paste-and-notify-label = {COPY(from_path, "pasteAndNotifyLabel")}
paste-dont-notify-label = {COPY(from_path, "pasteDontNotifyLabel")}
import-items-failed = {REPLACE(from_path, "importItemsFailed", replacements_count_error)}
no-items-in-calendar-file2 = {REPLACE(from_path, "noItemsInCalendarFile2", replacements_filePath)}
event-description = {COPY(from_path, "eventDescription")}
unable-to-read = {COPY(from_path, "unableToRead")}
unable-to-write = {COPY(from_path, "unableToWrite")} { $filePath }
default-file-name = {COPY(from_path, "defaultFileName")}
html-title = {COPY(from_path, "HTMLTitle")}
timezone-error = {REPLACE(from_path, "timezoneError", replacements_filePath)}
duplicate-error =
{ $count ->
[one] {REPLACE(from_path, "duplicateError", replacements_count_filePath)}
*[other] {REPLACE(from_path, "duplicateError", replacements_count_filePath)}
}
unable-to-create-provider = {REPLACE(from_path, "unableToCreateProvider", replacements_location)}
unknown-timezone-in-item = {REPLACE(from_path, "unknownTimezoneInItem", replacements_timezone_title_datetime)}
timezone-errors-alert-title = {COPY(from_path, "TimezoneErrorsAlertTitle")}
timezone-errors-see-console = {COPY(from_path, "TimezoneErrorsSeeConsole")}
remove-calendar-title = {COPY(from_path, "removeCalendarTitle")}
remove-calendar-button-delete = {COPY(from_path, "removeCalendarButtonDelete")}
remove-calendar-button-unsubscribe = {COPY(from_path, "removeCalendarButtonUnsubscribe")}
remove-calendar-message-delete-or-unsubscribe = {REPLACE(from_path, "removeCalendarMessageDeleteOrUnsubscribe", replacements_name)}
remove-calendar-message-delete = {REPLACE(from_path, "removeCalendarMessageDelete", replacements_name)}
remove-calendar-message-unsubscribe = {REPLACE(from_path, "removeCalendarMessageUnsubscribe", replacements_name)}
week-title = {REPLACE(from_path, "WeekTitle", replacements_title)}
week-title-label =
.aria-label = {REPLACE(from_path, "WeekTitle", replacements_title)}
calendar-none =
.label = {COPY(from_path, "None")}
too-new-schema-error-text = {REPLACE(from_path, "tooNewSchemaErrorText", replacements_hostApplication_fileName)}
event-untitled = {COPY(from_path, "eventUntitled")}
tooltip-title = {COPY(from_path, "tooltipTitle")}
tooltip-location = {COPY(from_path, "tooltipLocation")}
tooltip-date = {COPY(from_path, "tooltipDate")}
tooltip-cal-name = {COPY(from_path, "tooltipCalName")}
tooltip-status = {COPY(from_path, "tooltipStatus")}
tooltip-organizer = {COPY(from_path, "tooltipOrganizer")}
tooltip-start = {COPY(from_path, "tooltipStart")}
tooltip-due = {COPY(from_path, "tooltipDue")}
tooltip-priority = {COPY(from_path, "tooltipPriority")}
tooltip-percent = {COPY(from_path, "tooltipPercent")}
tooltip-completed = {COPY(from_path, "tooltipCompleted")}
calendar-new = {COPY(from_path, "New")}
calendar-open = {COPY(from_path, "Open")}
filepicker-title-import = {COPY(from_path, "filepickerTitleImport")}
filepicker-title-export = {COPY(from_path, "filepickerTitleExport")}
filter-ics = {REPLACE(from_path, "filterIcs", replacements_wildmat)}
filter-html = {REPLACE(from_path, "filterHtml", replacements_wildmat)}
generic-error-title = {COPY(from_path, "genericErrorTitle")}
http-put-error = {REPLACE(from_path, "httpPutError", replacements_statusCode_statusCodeInfo)}
other-put-error = {REPLACE(from_path, "otherPutError", replacements_statusCode)}
read-only-mode = {REPLACE(from_path, "readOnlyMode", replacements_name)}
disabled-mode = {REPLACE(from_path, "disabledMode", replacements_name)}
minor-error = {REPLACE(from_path, "minorError", replacements_name)}
still-read-only-error = {REPLACE(from_path, "stillReadOnlyError", replacements_name)}
utf8-decode-error = {COPY(from_path, "utf8DecodeError")}
ics-malformed-error = {COPY(from_path, "icsMalformedError")}
item-modified-on-server-title = {COPY(from_path, "itemModifiedOnServerTitle")}
item-modified-on-server = {COPY(from_path, "itemModifiedOnServer")}
modify-will-lose-data = {COPY(from_path, "modifyWillLoseData")}
delete-will-lose-data = {COPY(from_path, "deleteWillLoseData")}
calendar-conflicts-dialog =
.buttonlabelcancel = {COPY(from_path, "updateFromServer")}
proceed-modify =
.label = {COPY(from_path, "proceedModify")}
proceed-delete =
.label = {COPY(from_path, "proceedDelete")}
dav-not-dav = {REPLACE(from_path, "dav_notDav", replacements_name)}
dav-dav-not-cal-dav = {REPLACE(from_path, "dav_davNotCaldav", replacements_name)}
item-put-error = {COPY(from_path, "itemPutError")}
item-delete-error = {COPY(from_path, "itemDeleteError")}
cal-dav-request-error = {COPY(from_path, "caldavRequestError")}
cal-dav-response-error = {COPY(from_path, "caldavResponseError")}
cal-dav-request-status-code = {REPLACE(from_path, "caldavRequestStatusCode", replacements_statusCode)}
cal-dav-request-status-code-string-generic = {COPY(from_path, "caldavRequestStatusCodeStringGeneric")}
cal-dav-request-status-code-string-400 = {COPY(from_path, "caldavRequestStatusCodeString400")}
cal-dav-request-status-code-string-403 = {COPY(from_path, "caldavRequestStatusCodeString403")}
cal-dav-request-status-code-string-404 = {COPY(from_path, "caldavRequestStatusCodeString404")}
cal-dav-request-status-code-string-409 = {COPY(from_path, "caldavRequestStatusCodeString409")}
cal-dav-request-status-code-string-412 = {COPY(from_path, "caldavRequestStatusCodeString412")}
cal-dav-request-status-code-string-500 = {COPY(from_path, "caldavRequestStatusCodeString500")}
cal-dav-request-status-code-string-502 = {COPY(from_path, "caldavRequestStatusCodeString502")}
cal-dav-request-status-code-string-503 = {COPY(from_path, "caldavRequestStatusCodeString503")}
cal-dav-redirect-title = {REPLACE(from_path, "caldavRedirectTitle", replacements_name)}
cal-dav-redirect-text = {REPLACE(from_path, "caldavRedirectText", replacements_name)}
cal-dav-redirect-disable-calendar = {COPY(from_path, "caldavRedirectDisableCalendar")}
likely-timezone = {COPY(from_path, "likelyTimezone")}
warning-os-tz-no-match = {REPLACE(from_path, "WarningOSTZNoMatch", replacements_timezone_zoneInfoTimezoneId)}
skipping-os-timezone = {REPLACE(from_path, "SkippingOSTimezone", replacements_timezone)}
skipping-locale-timezone = {REPLACE(from_path, "SkippingLocaleTimezone", replacements_timezone)}
warning-using-floating-tz-no-match = {COPY(from_path, "warningUsingFloatingTZNoMatch")}
warning-using-guessedtz = {REPLACE(from_path, "WarningUsingGuessedTZ", replacements_timezone_offset_detail1_detail2)}
tz-almost-matches-os-differ-at-mostaweek = {COPY(from_path, "TZAlmostMatchesOSDifferAtMostAWeek")}
tz-seems-to-matchos = {COPY(from_path, "TZSeemsToMatchOS")}
tz-fromos = {REPLACE(from_path, "TZFromOS", replacements_timezone)}
tz-from-locale = {COPY(from_path, "TZFromLocale")}
tz-from-known-timezones = {COPY(from_path, "TZFromKnownTimezones")}
tasks-with-no-due-date = {COPY(from_path, "tasksWithNoDueDate")}
cal-dav-name = {COPY(from_path, "caldavName")}
composite-name = {COPY(from_path, "compositeName")}
ics-name-key = {COPY(from_path, "icsName")}
memory-name = {COPY(from_path, "memoryName")}
storage-name = {COPY(from_path, "storageName")}
html-prefix-title = {COPY(from_path, "htmlPrefixTitle")}
html-prefix-when = {COPY(from_path, "htmlPrefixWhen")}
html-prefix-location = {COPY(from_path, "htmlPrefixLocation")}
html-prefix-description = {COPY(from_path, "htmlPrefixDescription")}
html-task-completed = {REPLACE(from_path, "htmlTaskCompleted", replacements_task)}
add-category = {COPY(from_path, "addCategory")}
multiple-categories = {COPY(from_path, "multipleCategories")}
calendar-today = {COPY(from_path, "today")}
calendar-tomorrow = {COPY(from_path, "tomorrow")}
yesterday = {COPY(from_path, "yesterday")}
events-only = {COPY(from_path, "eventsonly")}
events-and-tasks = {COPY(from_path, "eventsandtasks")}
tasks-only = {COPY(from_path, "tasksonly")}
short-calendar-week = {COPY(from_path, "shortcalendarweek")}
calendar-go = {COPY(from_path, "go")}
calendar-next1 = {COPY(from_path, "next1")}
calendar-next2 = {COPY(from_path, "next2")}
calendar-last1 = {COPY(from_path, "last1")}
calendar-last2 = {COPY(from_path, "last2")}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
replacements_timezone_offset_detail1_detail2=replacements_timezone_offset_detail1_detail2,
replacements_timezone_zoneInfoTimezoneId=replacements_timezone_zoneInfoTimezoneId,
replacements_statusCode_statusCodeInfo=replacements_statusCode_statusCodeInfo,
replacements_count_filePath=replacements_count_filePath,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("alarm-window-title-label"),
comment=FTL.Comment("Alarm Dialog\n$count reminder count"),
value=PLURALS(
source,
"alarmWindowTitle.label",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
alarm-starts =
.value = {REPLACE(from_path, "alarmStarts", replacements_datetime)}
alarm-today-at = {REPLACE(from_path, "alarmTodayAt", replacements_datetime)}
alarm-tomorrow-at = {REPLACE(from_path, "alarmTomorrowAt", replacements_datetime)}
alarm-yesterday-at = {REPLACE(from_path, "alarmYesterdayAt", replacements_datetime)}
alarm-default-description = {COPY(from_path, "alarmDefaultDescription")}
alarm-default-summary = {COPY(from_path, "alarmDefaultSummary")}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("alarm-snooze-limit-exceeded"),
comment=FTL.Comment("$count number of months"),
value=PLURALS(
source,
"alarmSnoozeLimitExceeded",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
task-details-status-needs-action = {COPY(from_path, "taskDetailsStatusNeedsAction")}
task-details-status-in-progress = {REPLACE(from_path, "taskDetailsStatusInProgress", replacements_percent)}
task-details-status-completed = {COPY(from_path, "taskDetailsStatusCompleted")}
task-details-status-completed-on = {REPLACE(from_path, "taskDetailsStatusCompletedOn", replacements_datetime)}
task-details-status-cancelled = {COPY(from_path, "taskDetailsStatusCancelled")}
getting-calendar-info-common =
.label = {COPY(from_path, "gettingCalendarInfoCommon")}
getting-calendar-info-detail =
.label = {REPLACE(from_path, "gettingCalendarInfoDetail", replacements_index_total)}
error-code = {REPLACE(from_path, "errorCode", replacements_errorCode)}
error-description = {REPLACE(from_path, "errorDescription", replacements_errorDescription)}
error-writing2 = {REPLACE(from_path, "errorWriting2", replacements_name)}
error-writing-details = {COPY(from_path, "errorWritingDetails")}
tooltip-calendar-disabled =
.title = {REPLACE(from_path, "tooltipCalendarDisabled", replacements_name)}
tooltip-calendar-read-only =
.title = {REPLACE(from_path, "tooltipCalendarReadOnly", replacements_name)}
task-edit-instructions = {COPY(from_path, "taskEditInstructions")}
task-edit-instructions-readonly = {COPY(from_path, "taskEditInstructionsReadonly")}
task-edit-instructions-capability = {COPY(from_path, "taskEditInstructionsCapability")}
event-details-start-date = {COPY(from_path, "eventDetailsStartDate")}
event-details-end-date = {COPY(from_path, "eventDetailsEndDate")}
datetime-with-timezone = {REPLACE(from_path, "datetimeWithTimezone", replacements_datetime_timezone)}
single-long-calendar-week = {REPLACE(from_path, "singleLongCalendarWeek", replacements_index)}
single-calendar-week = {REPLACE(from_path, "singleShortCalendarWeek", replacements_index)}
.title = {REPLACE(from_path, "singleLongCalendarWeek", replacements_index)}
several-calendar-weeks = {REPLACE(from_path, "severalShortCalendarWeeks", replacements_startIndex_endIndex)}
.title = {REPLACE(from_path, "severalLongCalendarWeeks", replacements_startIndex_endIndex)}
multiweek-view-week = {REPLACE(from_path, "multiweekViewWeek", replacements_number)}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("due-in-days"),
comment=FTL.Comment(
'Task tree, "Due In" column.\nLOCALIZATION NOTE (due-in-days, due-in-hours): Semi-colon list of plural\nforms. See: http://developer.mozilla.org/en/Localization_and_Plurals\n$count count'
),
value=PLURALS(
source,
"dueInDays",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("due-in-hours"),
comment=FTL.Comment("$count count"),
value=PLURALS(
source,
"dueInHours",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
due-in-less-than-one-hour = {COPY(from_path, "dueInLessThanOneHour")}
month-in-year = {REPLACE(from_path, "monthInYear", replacements_month_year)}
month-in-year-label =
.aria-label = {REPLACE(from_path, "monthInYear", replacements_month_year)}
month-in-year-month-format = {COPY(from_path, "monthInYear.monthFormat")}
format-date-long = {REPLACE(from_path, "formatDateLong", replacements_dayName_dayIndex_monthName_year)}
day-header = {REPLACE(from_path, "dayHeaderLabel", replacements_dayName_dayIndex)}
day-header-elem =
.label = { day-header }
days-interval-in-month = {REPLACE(from_path, "daysIntervalInMonth", replacements_startMonth_startDayIndex_endDayIndex_year)}
days-interval-in-month-month-format = {COPY(from_path, "daysIntervalInMonth.monthFormat")}
days-interval-between-months = {REPLACE(from_path, "daysIntervalBetweenMonths", replacements_startMonth_startDayIndex_endMonth_endDayIndex_year)}
days-interval-between-months-month-format = {COPY(from_path, "daysIntervalBetweenMonths.monthFormat")}
days-interval-between-years = {REPLACE(from_path, "daysIntervalBetweenYears", replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear)}
days-interval-between-years-month-format = {COPY(from_path, "daysIntervalBetweenYears.monthFormat")}
datetime-interval-on-same-date-time = {REPLACE(from_path, "datetimeIntervalOnSameDateTime", replacements_startDate_startTime)}
datetime-interval-on-same-day = {REPLACE(from_path, "datetimeIntervalOnSameDay", replacements_startDate_startTime_endTime)}
datetime-interval-on-several-days = {REPLACE(from_path, "datetimeIntervalOnSeveralDays", replacements_startDate_startTime_endDate_endTime)}
datetime-interval-task-without-date = {COPY(from_path, "datetimeIntervalTaskWithoutDate")}
datetime-interval-task-without-due-date = {REPLACE(from_path, "datetimeIntervalTaskWithoutDueDate", replacements_date_time)}
datetime-interval-task-without-start-date = {REPLACE(from_path, "datetimeIntervalTaskWithoutStartDate", replacements_date_time)}
drag-label-tasks-with-only-entry-date = {COPY(from_path, "dragLabelTasksWithOnlyEntryDate")}
drag-label-tasks-with-only-due-date = {COPY(from_path, "dragLabelTasksWithOnlyDueDate")}
delete-task =
.label = {COPY(from_path, "deleteTaskLabel")}
.accesskey = {COPY(from_path, "deleteTaskAccesskey")}
delete-item =
.label = {COPY(from_path, "deleteItemLabel")}
.accesskey = {COPY(from_path, "deleteItemAccesskey")}
delete-event =
.label = {COPY(from_path, "deleteEventLabel")}
.accesskey = {COPY(from_path, "deleteEventAccesskey")}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("calendar-properties-every-minute"),
attributes=[
FTL.Attribute(
id=FTL.Identifier("label"),
value=PLURALS(
source,
"calendarPropertiesEveryMinute",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
)
],
)
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
extract-using = {REPLACE(from_path, "extractUsing", replacements_languageName)}
extract-using-region = {REPLACE(from_path, "extractUsingRegion", replacements_languageName_region)}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
),
)
ctx.add_transforms(
target,
reference,
[
FTL.Message(
id=FTL.Identifier("unit-minutes"),
comment=FTL.Comment(
"LOCALIZATION NOTE (unit)\nUsed to determine the correct plural form of a unit\n$count count"
),
value=PLURALS(
source,
"unitMinutes",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
),
FTL.Message(
id=FTL.Identifier("unit-hours"),
comment=FTL.Comment("$count count"),
value=PLURALS(
source,
"unitHours",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
),
FTL.Message(
id=FTL.Identifier("unit-days"),
comment=FTL.Comment("$count count"),
value=PLURALS(
source,
"unitDays",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
),
FTL.Message(
id=FTL.Identifier("unit-weeks"),
comment=FTL.Comment("$count count"),
value=PLURALS(
source,
"unitWeeks",
VARIABLE_REFERENCE("count"),
foreach=lambda n: REPLACE_IN_TEXT(
n,
dict(
{
"#1": VARIABLE_REFERENCE("count"),
}
),
),
),
),
],
)
ctx.add_transforms(
target,
reference,
transforms_from(
"""
show-calendar = {REPLACE(from_path, "showCalendar", replacements_name)}
hide-calendar = {REPLACE(from_path, "hideCalendar", replacements_name)}
hide-calendar-title =
.title = {REPLACE(from_path, "showCalendar", replacements_name)}
show-calendar-title =
.title = {REPLACE(from_path, "hideCalendar", replacements_name)}
show-calendar-label =
.label = {REPLACE(from_path, "showCalendar", replacements_name)}
hide-calendar-label =
.label = {REPLACE(from_path, "hideCalendar", replacements_name)}
show-only-calendar =
.label = {REPLACE(from_path, "showOnlyCalendar", replacements_name)}
modify-conflict-prompt-title = {COPY(from_path, "modifyConflictPromptTitle")}
modify-conflict-prompt-message = {COPY(from_path, "modifyConflictPromptMessage")}
modify-conflict-prompt-button1 = {COPY(from_path, "modifyConflictPromptButton1")}
modify-conflict-prompt-button2 = {COPY(from_path, "modifyConflictPromptButton2")}
minimonth-no-selected-date =
.aria-label = {COPY(from_path, "minimonthNoSelectedDate")}
""",
from_path=source,
replacements_count_error=replacements_count_error,
replacements_date_time=replacements_date_time,
replacements_datetime=replacements_datetime,
replacements_datetime_timezone=replacements_datetime_timezone,
replacements_dayName_dayIndex=replacements_dayName_dayIndex,
replacements_dayName_dayIndex_monthName_year=replacements_dayName_dayIndex_monthName_year,
replacements_errorCode=replacements_errorCode,
replacements_errorDescription=replacements_errorDescription,
replacements_filePath=replacements_filePath,
replacements_hostApplication_fileName=replacements_hostApplication_fileName,
replacements_index=replacements_index,
replacements_index_total=replacements_index_total,
replacements_languageName=replacements_languageName,
replacements_languageName_region=replacements_languageName_region,
replacements_location=replacements_location,
replacements_month_year=replacements_month_year,
replacements_name=replacements_name,
replacements_number=replacements_number,
replacements_pasteItem=replacements_pasteItem,
replacements_percent=replacements_percent,
replacements_startDate_startTime=replacements_startDate_startTime,
replacements_startDate_startTime_endDate_endTime=replacements_startDate_startTime_endDate_endTime,
replacements_startDate_startTime_endTime=replacements_startDate_startTime_endTime,
replacements_startIndex_endIndex=replacements_startIndex_endIndex,
replacements_startMonth_startDayIndex_endDayIndex_year=replacements_startMonth_startDayIndex_endDayIndex_year,
replacements_startMonth_startDayIndex_endMonth_endDayIndex_year=replacements_startMonth_startDayIndex_endMonth_endDayIndex_year,
replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear=replacements_startMonth_startDayIndex_startYear_endMonth_endDayIndex_endYear,
replacements_statusCode=replacements_statusCode,
replacements_task=replacements_task,
replacements_timezone=replacements_timezone,
replacements_timezone_title_datetime=replacements_timezone_title_datetime,
replacements_title=replacements_title,
replacements_wildmat=replacements_wildmat,
),
)

Просмотреть файл

@ -0,0 +1,42 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
from fluent.migratetb.helpers import VARIABLE_REFERENCE
replacements_locationProperty = dict({"%1$S": VARIABLE_REFERENCE("locationProperty")})
replacements_organizerProperty = dict({"%1$S": VARIABLE_REFERENCE("organizerProperty")})
replacements_attendeeProperty = dict({"%1$S": VARIABLE_REFERENCE("attendeeProperty")})
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 3. part {index}"""
target = reference = "calendar/calendar/calendar-invitations-dialog.ftl"
source = "calendar/chrome/calendar/calendar-invitations-dialog.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
allday-event = {COPY(from_path, "allday-event")}
recurrent-event =
.value = {COPY(from_path, "recurrent-event")}
calendar-invitations-location =
.value = {REPLACE(from_path, "location", replacements_locationProperty)}
organizer =
.value = {REPLACE(from_path, "organizer", replacements_organizerProperty)}
calendar-invitations-attendee =
.value = {REPLACE(from_path, "attendee", replacements_attendeeProperty)}
calendar-invitations-none = {COPY(from_path, "none")}
""",
from_path=source,
replacements_locationProperty=replacements_locationProperty,
replacements_organizerProperty=replacements_organizerProperty,
replacements_attendeeProperty=replacements_attendeeProperty,
),
)

Просмотреть файл

@ -0,0 +1,46 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
from fluent.migratetb.helpers import VARIABLE_REFERENCE
replacements_role = dict({"%1$S": VARIABLE_REFERENCE("role")})
replacements_userType = dict({"%1$S": VARIABLE_REFERENCE("userType")})
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 4. part {index}"""
target = reference = "calendar/calendar/calendar-event-dialog-attendees.ftl"
source = "calendar/chrome/calendar/calendar-event-dialog-attendees.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
event-attendee-role-required =
.title = {COPY(from_path, "event.attendee.role.required")}
event-attendee-role-optional =
.title = {COPY(from_path, "event.attendee.role.optional")}
event-attendee-role-nonparticipant =
.title = {COPY(from_path, "event.attendee.role.nonparticipant")}
event-attendee-role-chair =
.title = {COPY(from_path, "event.attendee.role.chair")}
event-attendee-role-unknown =
.title = {REPLACE(from_path, "event.attendee.role.unknown", replacements_role)}
event-attendee-usertype-individual = {COPY(from_path, "event.attendee.usertype.individual")}
event-attendee-usertype-group = {COPY(from_path, "event.attendee.usertype.group")}
event-attendee-usertype-resource = {COPY(from_path, "event.attendee.usertype.resource")}
event-attendee-usertype-room = {COPY(from_path, "event.attendee.usertype.room")}
event-attendee-usertype-unknown = {REPLACE(from_path, "event.attendee.usertype.unknown", replacements_userType)}
""",
from_path=source,
replacements_role=replacements_role,
replacements_userType=replacements_userType,
),
)

Просмотреть файл

@ -0,0 +1,97 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
from fluent.migratetb.helpers import VARIABLE_REFERENCE
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 5. part {index}"""
target = reference = "calendar/calendar/calendar-occurrence-prompt.ftl"
source = "calendar/chrome/calendar/calendar-occurrence-prompt.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
header-isrepeating-event =
.label = {COPY(from_path, "header.isrepeating.event.label")}
header-isrepeating-task =
.label = {COPY(from_path, "header.isrepeating.task.label")}
header-containsrepeating-event =
.label = {COPY(from_path, "header.containsrepeating.event.label")}
header-containsrepeating-task =
.label = {COPY(from_path, "header.containsrepeating.task.label")}
header-containsrepeating-mixed =
.label = {COPY(from_path, "header.containsrepeating.mixed.label")}
windowtitle-event-copy = {COPY(from_path, "windowtitle.event.copy")}
windowtitle-task-copy = {COPY(from_path, "windowtitle.task.copy")}
windowtitle-mixed-copy = {COPY(from_path, "windowtitle.mixed.copy")}
windowtitle-event-cut = {COPY(from_path, "windowtitle.event.cut")}
windowtitle-task-cut = {COPY(from_path, "windowtitle.task.cut")}
windowtitle-mixed-cut = {COPY(from_path, "windowtitle.mixed.cut")}
windowtitle-event-delete = {COPY(from_path, "windowtitle.event.delete")}
windowtitle-task-delete = {COPY(from_path, "windowtitle.task.delete")}
windowtitle-mixed-delete = {COPY(from_path, "windowtitle.mixed.delete")}
windowtitle-event-edit = {COPY(from_path, "windowtitle.event.edit")}
windowtitle-task-edit = {COPY(from_path, "windowtitle.task.edit")}
windowtitle-mixed-edit = {COPY(from_path, "windowtitle.mixed.edit")}
windowtitle-multipleitems =
.value = {COPY(from_path, "windowtitle.multipleitems")}
buttons-single-occurrence-copy =
.label = {COPY(from_path, "buttons.single.occurrence.copy.label")}
buttons-single-occurrence-cut =
.label = {COPY(from_path, "buttons.single.occurrence.cut.label")}
buttons-single-occurrence-delete =
.label = {COPY(from_path, "buttons.single.occurrence.delete.label")}
buttons-single-occurrence-edit =
.label = {COPY(from_path, "buttons.single.occurrence.edit.label")}
buttons-multiple-occurrence-copy =
.label = {COPY(from_path, "buttons.multiple.occurrence.copy.label")}
buttons-multiple-occurrence-cut =
.label = {COPY(from_path, "buttons.multiple.occurrence.cut.label")}
buttons-multiple-occurrence-delete =
.label = {COPY(from_path, "buttons.multiple.occurrence.delete.label")}
buttons-multiple-occurrence-edit =
.label = {COPY(from_path, "buttons.multiple.occurrence.edit.label")}
buttons-single-allfollowing-copy =
.label = {COPY(from_path, "buttons.single.allfollowing.copy.label")}
buttons-single-allfollowing-cut =
.label = {COPY(from_path, "buttons.single.allfollowing.cut.label")}
buttons-single-allfollowing-delete =
.label = {COPY(from_path, "buttons.single.allfollowing.delete.label")}
buttons-single-allfollowing-edit =
.label = {COPY(from_path, "buttons.single.allfollowing.edit.label")}
buttons-multiple-allfollowing-copy =
.label = {COPY(from_path, "buttons.multiple.allfollowing.copy.label")}
buttons-multiple-allfollowing-cut =
.label = {COPY(from_path, "buttons.multiple.allfollowing.cut.label")}
buttons-multiple-allfollowing-delete =
.label = {COPY(from_path, "buttons.multiple.allfollowing.delete.label")}
buttons-multiple-allfollowing-edit =
.label = {COPY(from_path, "buttons.multiple.allfollowing.edit.label")}
buttons-single-parent-copy =
.label = {COPY(from_path, "buttons.single.parent.copy.label")}
buttons-single-parent-cut =
.label = {COPY(from_path, "buttons.single.parent.cut.label")}
buttons-single-parent-delete =
.label = {COPY(from_path, "buttons.single.parent.delete.label")}
buttons-single-parent-edit =
.label = {COPY(from_path, "buttons.single.parent.edit.label")}
buttons-multiple-parent-copy =
.label = {COPY(from_path, "buttons.multiple.parent.copy.label")}
buttons-multiple-parent-cut =
.label = {COPY(from_path, "buttons.multiple.parent.cut.label")}
buttons-multiple-parent-delete =
.label = {COPY(from_path, "buttons.multiple.parent.delete.label")}
buttons-multiple-parent-edit =
.label = {COPY(from_path, "buttons.multiple.parent.edit.label")}
""",
from_path=source,
),
)

Просмотреть файл

@ -0,0 +1,25 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
import fluent.migratetb.helpers
from fluent.migratetb import COPY
from fluent.migratetb.helpers import transforms_from
def migrate(ctx):
"""Bug 1893758 Calendar Fluent Migrations - Properties Part A Files 6. part {index}"""
target = reference = "calendar/calendar/categories.ftl"
source = "calendar/chrome/calendar/categories.properties"
ctx.add_transforms(
target,
reference,
transforms_from(
"""
categories2 = {COPY(from_path, "categories2")}
""",
from_path=source,
),
)

Просмотреть файл

@ -5,6 +5,8 @@ fluent-lint:
- .
exclude:
- dom/l10n/tests/mochitest/document_l10n/non-system-principal/localization/test.ftl
# Exclude files with single and double non-smart quotes during Migration
- comm/calendar/locales/en-US/calendar/calendar.ftl
extensions: ['ftl']
support-files:
- 'tools/lint/fluent-lint/*.py'