commit 7fc0395c52083d57b85aa4c0e6bacb8dc12f28b7
parent 251eeab1c468eb1557269952c712580e4cc16e29
Author: Drew Willcoxon <adw@mozilla.com>
Date: Tue, 28 Oct 2025 02:50:52 +0000
Bug 1996702 - Replace RealtimeSuggestProvider.getViewUpdateForValues (plural) with getViewUpdateForValue (singular). r=daisuke
Differential Revision: https://phabricator.services.mozilla.com/D270274
Diffstat:
4 files changed, 282 insertions(+), 321 deletions(-)
diff --git a/browser/components/urlbar/private/FlightStatusSuggestions.sys.mjs b/browser/components/urlbar/private/FlightStatusSuggestions.sys.mjs
@@ -86,183 +86,177 @@ export class FlightStatusSuggestions extends RealtimeSuggestProvider {
];
}
- getViewUpdateForValues(values) {
- return Object.assign(
- {},
- ...values.flatMap((v, i) => {
- let status;
- switch (v.status) {
- case "Scheduled": {
- status = "ontime";
- break;
- }
- case "En Route": {
- status = "inflight";
- break;
- }
- case "Arrived": {
- status = "arrived";
- break;
- }
- case "Cancelled": {
- status = "cancelled";
- break;
- }
- case "Delayed": {
- status = "delayed";
- break;
- }
- }
+ getViewUpdateForValue(i, v) {
+ let status;
+ switch (v.status) {
+ case "Scheduled": {
+ status = "ontime";
+ break;
+ }
+ case "En Route": {
+ status = "inflight";
+ break;
+ }
+ case "Arrived": {
+ status = "arrived";
+ break;
+ }
+ case "Cancelled": {
+ status = "cancelled";
+ break;
+ }
+ case "Delayed": {
+ status = "delayed";
+ break;
+ }
+ }
- let departureTime;
- let departureTimeZone;
- let arrivalTime;
- let arrivalTimeZone;
- if (status == "delayed" || !v.delayed) {
- departureTime = new Date(v.departure.scheduled_time);
- departureTimeZone = getTimeZone(v.departure.scheduled_time);
- arrivalTime = new Date(v.arrival.scheduled_time);
- arrivalTimeZone = getTimeZone(v.arrival.scheduled_time);
- } else {
- departureTime = new Date(v.departure.estimated_time);
- departureTimeZone = getTimeZone(v.departure.estimated_time);
- arrivalTime = new Date(v.arrival.estimated_time);
- arrivalTimeZone = getTimeZone(v.arrival.estimated_time);
- }
+ let departureTime;
+ let departureTimeZone;
+ let arrivalTime;
+ let arrivalTimeZone;
+ if (status == "delayed" || !v.delayed) {
+ departureTime = new Date(v.departure.scheduled_time);
+ departureTimeZone = getTimeZone(v.departure.scheduled_time);
+ arrivalTime = new Date(v.arrival.scheduled_time);
+ arrivalTimeZone = getTimeZone(v.arrival.scheduled_time);
+ } else {
+ departureTime = new Date(v.departure.estimated_time);
+ departureTimeZone = getTimeZone(v.departure.estimated_time);
+ arrivalTime = new Date(v.arrival.estimated_time);
+ arrivalTimeZone = getTimeZone(v.arrival.estimated_time);
+ }
- let statusL10nId = `urlbar-result-flight-status-status-${status}`;
- let statusL10nArgs;
- if (status == "delayed") {
- statusL10nArgs = {
- departureEstimatedTime: new Intl.DateTimeFormat(undefined, {
- hour: "numeric",
- minute: "numeric",
- timeZone: getTimeZone(v.departure.estimated_time),
- }).format(new Date(v.departure.estimated_time)),
- };
- }
+ let statusL10nId = `urlbar-result-flight-status-status-${status}`;
+ let statusL10nArgs;
+ if (status == "delayed") {
+ statusL10nArgs = {
+ departureEstimatedTime: new Intl.DateTimeFormat(undefined, {
+ hour: "numeric",
+ minute: "numeric",
+ timeZone: getTimeZone(v.departure.estimated_time),
+ }).format(new Date(v.departure.estimated_time)),
+ };
+ }
- let foregroundImage;
- let backgroundImage;
- if (status == "inflight") {
- let backgroundImageId =
- v.progress_percent == 100 ? 4 : Math.floor(v.progress_percent / 20);
- backgroundImage = {
- style: {
- "--airline-color": v.airline.color,
- },
- attributes: {
- backgroundImageId,
- hasForegroundImage: !!v.airline.icon,
- },
- };
- foregroundImage = {
- attributes: {
- src: v.airline.icon,
- },
- };
- } else {
- foregroundImage = {
- attributes: {
- src:
- v.airline.icon ??
- "chrome://browser/skin/urlbar/flight-airline.svg",
- fallback: !v.airline.icon,
- },
- };
- }
+ let foregroundImage;
+ let backgroundImage;
+ if (status == "inflight") {
+ let backgroundImageId =
+ v.progress_percent == 100 ? 4 : Math.floor(v.progress_percent / 20);
+ backgroundImage = {
+ style: {
+ "--airline-color": v.airline.color,
+ },
+ attributes: {
+ backgroundImageId,
+ hasForegroundImage: !!v.airline.icon,
+ },
+ };
+ foregroundImage = {
+ attributes: {
+ src: v.airline.icon,
+ },
+ };
+ } else {
+ foregroundImage = {
+ attributes: {
+ src:
+ v.airline.icon ?? "chrome://browser/skin/urlbar/flight-airline.svg",
+ fallback: !v.airline.icon,
+ },
+ };
+ }
- return {
- [`item_${i}`]: {
- attributes: {
- status,
- },
- },
- [`image_container_${i}`]: backgroundImage,
- [`image_${i}`]: foregroundImage,
- [`departure_time_${i}`]: {
- textContent: new Intl.DateTimeFormat(undefined, {
- hour: "numeric",
- minute: "numeric",
- timeZone: departureTimeZone,
- }).format(departureTime),
- },
- [`departure_date_${i}`]: {
- textContent: new Intl.DateTimeFormat(undefined, {
- month: "long",
- day: "numeric",
- weekday: "short",
- timeZone: departureTimeZone,
- }).format(departureTime),
- },
- [`arrival_time_${i}`]: {
- textContent: new Intl.DateTimeFormat(undefined, {
- hour: "numeric",
- minute: "numeric",
- timeZone: arrivalTimeZone,
- }).format(arrivalTime),
+ return {
+ [`item_${i}`]: {
+ attributes: {
+ status,
+ },
+ },
+ [`image_container_${i}`]: backgroundImage,
+ [`image_${i}`]: foregroundImage,
+ [`departure_time_${i}`]: {
+ textContent: new Intl.DateTimeFormat(undefined, {
+ hour: "numeric",
+ minute: "numeric",
+ timeZone: departureTimeZone,
+ }).format(departureTime),
+ },
+ [`departure_date_${i}`]: {
+ textContent: new Intl.DateTimeFormat(undefined, {
+ month: "long",
+ day: "numeric",
+ weekday: "short",
+ timeZone: departureTimeZone,
+ }).format(departureTime),
+ },
+ [`arrival_time_${i}`]: {
+ textContent: new Intl.DateTimeFormat(undefined, {
+ hour: "numeric",
+ minute: "numeric",
+ timeZone: arrivalTimeZone,
+ }).format(arrivalTime),
+ },
+ [`origin_airport_${i}`]: {
+ l10n: {
+ id: "urlbar-result-flight-status-airport",
+ args: {
+ city: v.origin.city,
+ code: v.origin.code,
},
- [`origin_airport_${i}`]: {
- l10n: {
- id: "urlbar-result-flight-status-airport",
- args: {
- city: v.origin.city,
- code: v.origin.code,
- },
- cacheable: true,
- excludeArgsFromCacheKey: true,
- },
+ cacheable: true,
+ excludeArgsFromCacheKey: true,
+ },
+ },
+ [`destination_airport_${i}`]: {
+ l10n: {
+ id: "urlbar-result-flight-status-airport",
+ args: {
+ city: v.destination.city,
+ code: v.destination.code,
},
- [`destination_airport_${i}`]: {
+ cacheable: true,
+ excludeArgsFromCacheKey: true,
+ },
+ },
+ [`flight_number_${i}`]: v.airline.name
+ ? {
l10n: {
- id: "urlbar-result-flight-status-airport",
+ id: "urlbar-result-flight-status-flight-number-with-airline",
args: {
- city: v.destination.city,
- code: v.destination.code,
+ flightNumber: v.flight_number,
+ airlineName: v.airline.name,
},
cacheable: true,
- excludeArgsFromCacheKey: true,
+ excludeArgsFromCacheKey: !!statusL10nArgs,
},
+ }
+ : {
+ textContent: v.flight_number,
},
- [`flight_number_${i}`]: v.airline.name
- ? {
- l10n: {
- id: "urlbar-result-flight-status-flight-number-with-airline",
- args: {
- flightNumber: v.flight_number,
- airlineName: v.airline.name,
- },
- cacheable: true,
- excludeArgsFromCacheKey: !!statusL10nArgs,
+ [`status_${i}`]: {
+ l10n: {
+ id: statusL10nId,
+ args: statusL10nArgs,
+ cacheable: true,
+ excludeArgsFromCacheKey: !!statusL10nArgs,
+ },
+ },
+ [`time_left_minutes_${i}`]:
+ v.time_left_minutes != undefined
+ ? {
+ l10n: {
+ id: "urlbar-result-flight-status-time-left-minutes",
+ args: {
+ timeLeftMinutes: v.time_left_minutes,
},
- }
- : {
- textContent: v.flight_number,
+ cacheable: true,
+ excludeArgsFromCacheKey: !!statusL10nArgs,
},
- [`status_${i}`]: {
- l10n: {
- id: statusL10nId,
- args: statusL10nArgs,
- cacheable: true,
- excludeArgsFromCacheKey: !!statusL10nArgs,
- },
- },
- [`time_left_minutes_${i}`]:
- v.time_left_minutes != undefined
- ? {
- l10n: {
- id: "urlbar-result-flight-status-time-left-minutes",
- args: {
- timeLeftMinutes: v.time_left_minutes,
- },
- cacheable: true,
- excludeArgsFromCacheKey: !!statusL10nArgs,
- },
- }
- : null,
- };
- })
- );
+ }
+ : null,
+ };
}
}
diff --git a/browser/components/urlbar/private/MarketSuggestions.sys.mjs b/browser/components/urlbar/private/MarketSuggestions.sys.mjs
@@ -95,64 +95,59 @@ export class MarketSuggestions extends RealtimeSuggestProvider {
];
}
- getViewUpdateForValues(values) {
- return Object.assign(
- {},
- ...values.flatMap((v, i) => {
- let arrowImageUri;
- let changeDescription;
- let changePercent = parseFloat(v.todays_change_perc);
- if (changePercent < 0) {
- changeDescription = "down";
- arrowImageUri = "chrome://browser/skin/urlbar/market-down.svg";
- } else if (changePercent > 0) {
- changeDescription = "up";
- arrowImageUri = "chrome://browser/skin/urlbar/market-up.svg";
- } else {
- changeDescription = "unchanged";
- arrowImageUri = "chrome://browser/skin/urlbar/market-unchanged.svg";
- }
-
- let imageUri = v.image_url;
- let isImageAnArrow = false;
- if (!imageUri) {
- isImageAnArrow = true;
- imageUri = arrowImageUri;
- }
-
- return {
- [`item_${i}`]: {
- attributes: {
- change: changeDescription,
- },
- },
- [`image_container_${i}`]: {
- attributes: {
- "is-arrow": isImageAnArrow ? "" : null,
- },
- },
- [`image_${i}`]: {
- attributes: {
- src: imageUri,
- },
- },
- [`name_${i}`]: {
- textContent: v.name,
- },
- [`ticker_${i}`]: {
- textContent: v.ticker,
- },
- [`todays_change_perc_${i}`]: {
- textContent: `${v.todays_change_perc}%`,
- },
- [`last_price_${i}`]: {
- textContent: v.last_price,
- },
- [`exchange_${i}`]: {
- textContent: v.exchange,
- },
- };
- })
- );
+ getViewUpdateForValue(i, v) {
+ let arrowImageUri;
+ let changeDescription;
+ let changePercent = parseFloat(v.todays_change_perc);
+ if (changePercent < 0) {
+ changeDescription = "down";
+ arrowImageUri = "chrome://browser/skin/urlbar/market-down.svg";
+ } else if (changePercent > 0) {
+ changeDescription = "up";
+ arrowImageUri = "chrome://browser/skin/urlbar/market-up.svg";
+ } else {
+ changeDescription = "unchanged";
+ arrowImageUri = "chrome://browser/skin/urlbar/market-unchanged.svg";
+ }
+
+ let imageUri = v.image_url;
+ let isImageAnArrow = false;
+ if (!imageUri) {
+ isImageAnArrow = true;
+ imageUri = arrowImageUri;
+ }
+
+ return {
+ [`item_${i}`]: {
+ attributes: {
+ change: changeDescription,
+ },
+ },
+ [`image_container_${i}`]: {
+ attributes: {
+ "is-arrow": isImageAnArrow ? "" : null,
+ },
+ },
+ [`image_${i}`]: {
+ attributes: {
+ src: imageUri,
+ },
+ },
+ [`name_${i}`]: {
+ textContent: v.name,
+ },
+ [`ticker_${i}`]: {
+ textContent: v.ticker,
+ },
+ [`todays_change_perc_${i}`]: {
+ textContent: `${v.todays_change_perc}%`,
+ },
+ [`last_price_${i}`]: {
+ textContent: v.last_price,
+ },
+ [`exchange_${i}`]: {
+ textContent: v.exchange,
+ },
+ };
}
}
diff --git a/browser/components/urlbar/private/RealtimeSuggestProvider.sys.mjs b/browser/components/urlbar/private/RealtimeSuggestProvider.sys.mjs
@@ -43,7 +43,7 @@ export class RealtimeSuggestProvider extends SuggestProvider {
throw new Error("Trying to access the base class, must be overridden");
}
- getViewUpdateForValues(_values) {
+ getViewUpdateForValue(_index, _value) {
throw new Error("Trying to access the base class, must be overridden");
}
@@ -447,30 +447,29 @@ export class RealtimeSuggestProvider extends SuggestProvider {
return null;
}
- return mergeObjects(
- Object.assign(
- {
- root: {
- dataset: {
- // This `url` or `query` will be used when there's only one value.
- url: values[0].url,
- query: values[0].query,
- },
- },
+ let update = {
+ root: {
+ dataset: {
+ // This `url` or `query` will be used when there's only one value.
+ url: values[0].url,
+ query: values[0].query,
},
- ...values.flatMap((v, i) => ({
- [`item_${i}`]: {
- dataset: {
- // These `url` or `query`s will be used when there are multiple
- // values.
- url: v.url,
- query: v.query,
- },
- },
- }))
- ),
- this.getViewUpdateForValues(values)
- );
+ },
+ };
+
+ for (let i = 0; i < values.length; i++) {
+ let value = values[i];
+ Object.assign(update, this.getViewUpdateForValue(i, value));
+
+ // These `url` or `query`s will be used when there are multiple values.
+ let itemName = `item_${i}`;
+ update[itemName] ??= {};
+ update[itemName].dataset ??= {};
+ update[itemName].dataset.url ??= value.url;
+ update[itemName].dataset.query ??= value.query;
+ }
+
+ return update;
}
getResultCommands(result) {
@@ -634,25 +633,3 @@ export class RealtimeSuggestProvider extends SuggestProvider {
return Math.max(minLength, 0);
}
}
-
-function mergeObjects(dest, source) {
- if (!source || typeof source != "object") {
- return source;
- }
-
- if (Array.isArray(source)) {
- if (!Array.isArray(dest)) {
- dest = [];
- }
- dest.push(...source);
- return dest;
- }
-
- if (!dest || typeof dest != "object") {
- dest = {};
- }
- for (let [key, value] of Object.entries(source)) {
- dest[key] = mergeObjects(dest[key], value);
- }
- return dest;
-}
diff --git a/browser/components/urlbar/private/YelpRealtimeSuggestions.sys.mjs b/browser/components/urlbar/private/YelpRealtimeSuggestions.sys.mjs
@@ -83,60 +83,55 @@ export class YelpRealtimeSuggestions extends RealtimeSuggestProvider {
];
}
- getViewUpdateForValues(values) {
- return Object.assign(
- {},
- ...values.flatMap((v, i) => {
- return {
- [`item_${i}`]: {
- attributes: {
- state: v.business_hours[0].is_open_now ? "open" : "closed",
- },
- },
- [`image_${i}`]: {
- attributes: {
- src: v.image_url,
- },
- },
- [`title_${i}`]: {
- textContent: v.name,
- },
- [`address_${i}`]: {
- textContent: v.address,
- },
- [`pricing_${i}`]: {
- textContent: v.pricing,
- },
- [`business_hours_${i}`]: {
- l10n: {
- id: v.business_hours[0].is_open_now
- ? "urlbar-result-yelp-realtime-business-hours-open"
- : "urlbar-result-yelp-realtime-business-hours-closed",
- args: {
- // TODO: Need to pass "time until keeping the status" after resolving
- // the timezone issue.
- timeUntil: new Intl.DateTimeFormat(undefined, {
- hour: "numeric",
- }).format(new Date()),
- },
- parseMarkup: true,
- cacheable: true,
- excludeArgsFromCacheKey: true,
- },
+ getViewUpdateForValue(i, v) {
+ return {
+ [`item_${i}`]: {
+ attributes: {
+ state: v.business_hours[0].is_open_now ? "open" : "closed",
+ },
+ },
+ [`image_${i}`]: {
+ attributes: {
+ src: v.image_url,
+ },
+ },
+ [`title_${i}`]: {
+ textContent: v.name,
+ },
+ [`address_${i}`]: {
+ textContent: v.address,
+ },
+ [`pricing_${i}`]: {
+ textContent: v.pricing,
+ },
+ [`business_hours_${i}`]: {
+ l10n: {
+ id: v.business_hours[0].is_open_now
+ ? "urlbar-result-yelp-realtime-business-hours-open"
+ : "urlbar-result-yelp-realtime-business-hours-closed",
+ args: {
+ // TODO: Need to pass "time until keeping the status" after resolving
+ // the timezone issue.
+ timeUntil: new Intl.DateTimeFormat(undefined, {
+ hour: "numeric",
+ }).format(new Date()),
},
- [`popularity_${i}`]: {
- l10n: {
- id: "urlbar-result-yelp-realtime-popularity",
- args: {
- rating: v.rating,
- review_count: v.review_count,
- },
- cacheable: true,
- excludeArgsFromCacheKey: true,
- },
+ parseMarkup: true,
+ cacheable: true,
+ excludeArgsFromCacheKey: true,
+ },
+ },
+ [`popularity_${i}`]: {
+ l10n: {
+ id: "urlbar-result-yelp-realtime-popularity",
+ args: {
+ rating: v.rating,
+ review_count: v.review_count,
},
- };
- })
- );
+ cacheable: true,
+ excludeArgsFromCacheKey: true,
+ },
+ },
+ };
}
}