summaryrefslogtreecommitdiffstats
path: root/toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
commitdef92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch)
tree2ef34b9ad8bb9a9220e05d60352558b15f513894 /toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs
parentAdding debian version 125.0.3-1. (diff)
downloadfirefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz
firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs')
-rw-r--r--toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs258
1 files changed, 258 insertions, 0 deletions
diff --git a/toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs b/toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs
new file mode 100644
index 0000000000..f00df0b40b
--- /dev/null
+++ b/toolkit/components/satchel/megalist/aggregator/datasources/AddressesDataSource.sys.mjs
@@ -0,0 +1,258 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { DataSourceBase } from "resource://gre/modules/megalist/aggregator/datasources/DataSourceBase.sys.mjs";
+import { formAutofillStorage } from "resource://autofill/FormAutofillStorage.sys.mjs";
+
+async function updateAddress(address, field, value) {
+ try {
+ const newAddress = {
+ ...address,
+ [field]: value ?? "",
+ };
+
+ formAutofillStorage.INTERNAL_FIELDS.forEach(
+ name => delete newAddress[name]
+ );
+ formAutofillStorage.addresses.VALID_COMPUTED_FIELDS.forEach(
+ name => delete newAddress[name]
+ );
+
+ if (address.guid) {
+ await formAutofillStorage.addresses.update(address.guid, newAddress);
+ } else {
+ await formAutofillStorage.addresses.add(newAddress);
+ }
+ } catch (error) {
+ //todo
+ console.error("failed to modify address", error);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Data source for Addresses.
+ *
+ */
+
+export class AddressesDataSource extends DataSourceBase {
+ #namePrototype;
+ #organizationPrototype;
+ #streetAddressPrototype;
+ #addressLevelOnePrototype;
+ #addressLevelTwoPrototype;
+ #addressLevelThreePrototype;
+ #postalCodePrototype;
+ #countryPrototype;
+ #phonePrototype;
+ #emailPrototype;
+
+ #addressesDisabledMessage;
+ #enabled;
+ #header;
+
+ constructor(...args) {
+ super(...args);
+ this.formatMessages(
+ "addresses-section-label",
+ "address-name-label",
+ "address-phone-label",
+ "address-email-label",
+ "command-copy",
+ "addresses-disabled",
+ "command-delete",
+ "command-edit",
+ "addresses-command-create"
+ ).then(
+ ([
+ headerLabel,
+ nameLabel,
+ phoneLabel,
+ emailLabel,
+ copyLabel,
+ addressesDisabled,
+ deleteLabel,
+ editLabel,
+ createLabel,
+ ]) => {
+ const copyCommand = { id: "Copy", label: copyLabel };
+ const editCommand = { id: "Edit", label: editLabel };
+ const deleteCommand = { id: "Delete", label: deleteLabel };
+ this.#addressesDisabledMessage = addressesDisabled;
+ this.#header = this.createHeaderLine(headerLabel);
+ this.#header.commands.push({ id: "Create", label: createLabel });
+
+ let self = this;
+
+ function prototypeLine(label, key, options = {}) {
+ return self.prototypeDataLine({
+ label: { value: label },
+ value: {
+ get() {
+ return this.editingValue ?? this.record[key];
+ },
+ },
+ commands: {
+ value: [copyCommand, editCommand, "-", deleteCommand],
+ },
+ executeEdit: {
+ value() {
+ this.editingValue = this.record[key] ?? "";
+ this.refreshOnScreen();
+ },
+ },
+ executeSave: {
+ async value(value) {
+ if (await updateAddress(this.record, key, value)) {
+ this.executeCancel();
+ }
+ },
+ },
+ ...options,
+ });
+ }
+
+ this.#namePrototype = prototypeLine(nameLabel, "name", {
+ start: { value: true },
+ });
+ this.#organizationPrototype = prototypeLine(
+ "Organization",
+ "organization"
+ );
+ this.#streetAddressPrototype = prototypeLine(
+ "Street Address",
+ "street-address"
+ );
+ this.#addressLevelThreePrototype = prototypeLine(
+ "Neighbourhood",
+ "address-level3"
+ );
+ this.#addressLevelTwoPrototype = prototypeLine(
+ "City",
+ "address-level2"
+ );
+ this.#addressLevelOnePrototype = prototypeLine(
+ "Province",
+ "address-level1"
+ );
+ this.#postalCodePrototype = prototypeLine("Postal Code", "postal-code");
+ this.#countryPrototype = prototypeLine("Country", "country");
+ this.#phonePrototype = prototypeLine(phoneLabel, "tel");
+ this.#emailPrototype = prototypeLine(emailLabel, "email", {
+ end: { value: true },
+ });
+
+ Services.obs.addObserver(this, "formautofill-storage-changed");
+ Services.prefs.addObserver(
+ "extensions.formautofill.addresses.enabled",
+ this
+ );
+ this.#reloadDataSource();
+ }
+ );
+ }
+
+ async #reloadDataSource() {
+ this.#enabled = Services.prefs.getBoolPref(
+ "extensions.formautofill.addresses.enabled"
+ );
+ if (!this.#enabled) {
+ this.#reloadEmptyDataSource();
+ return;
+ }
+
+ await formAutofillStorage.initialize();
+ const addresses = await formAutofillStorage.addresses.getAll();
+ this.beforeReloadingDataSource();
+ addresses.forEach(address => {
+ const lineId = `${address.name}:${address.tel}`;
+
+ this.addOrUpdateLine(address, lineId + "0", this.#namePrototype);
+ this.addOrUpdateLine(address, lineId + "1", this.#organizationPrototype);
+ this.addOrUpdateLine(address, lineId + "2", this.#streetAddressPrototype);
+ this.addOrUpdateLine(
+ address,
+ lineId + "3",
+ this.#addressLevelThreePrototype
+ );
+ this.addOrUpdateLine(
+ address,
+ lineId + "4",
+ this.#addressLevelTwoPrototype
+ );
+ this.addOrUpdateLine(
+ address,
+ lineId + "5",
+ this.#addressLevelOnePrototype
+ );
+ this.addOrUpdateLine(address, lineId + "6", this.#postalCodePrototype);
+ this.addOrUpdateLine(address, lineId + "7", this.#countryPrototype);
+ this.addOrUpdateLine(address, lineId + "8", this.#phonePrototype);
+ this.addOrUpdateLine(address, lineId + "9", this.#emailPrototype);
+ });
+ this.afterReloadingDataSource();
+ }
+
+ /**
+ * Enumerate all the lines provided by this data source.
+ *
+ * @param {string} searchText used to filter data
+ */
+ *enumerateLines(searchText) {
+ if (this.#enabled === undefined) {
+ // Async Fluent API makes it possible to have data source waiting
+ // for the localized strings, which can be detected by undefined in #enabled.
+ return;
+ }
+
+ yield this.#header;
+ if (this.#header.collapsed || !this.#enabled) {
+ return;
+ }
+
+ const stats = { total: 0, count: 0 };
+ searchText = searchText.toUpperCase();
+ yield* this.enumerateLinesForMatchingRecords(searchText, stats, address =>
+ [
+ "name",
+ "organization",
+ "street-address",
+ "address-level3",
+ "address-level2",
+ "address-level1",
+ "postal-code",
+ "country",
+ "tel",
+ "email",
+ ].some(key => address[key]?.toUpperCase().includes(searchText))
+ );
+
+ this.formatMessages({
+ id:
+ stats.count == stats.total
+ ? "addresses-count"
+ : "addresses-filtered-count",
+ args: stats,
+ }).then(([headerLabel]) => {
+ this.#header.value = headerLabel;
+ });
+ }
+
+ #reloadEmptyDataSource() {
+ this.lines.length = 0;
+ this.#header.value = this.#addressesDisabledMessage;
+ this.refreshAllLinesOnScreen();
+ }
+
+ observe(_subj, topic, message) {
+ if (
+ topic == "formautofill-storage-changed" ||
+ message == "extensions.formautofill.addresses.enabled"
+ ) {
+ this.#reloadDataSource();
+ }
+ }
+}