1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* 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 { html } from "chrome://global/content/vendor/lit.all.mjs";
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://browser/content/shopping/highlight-item.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://browser/content/shopping/shopping-card.mjs";
const VALID_HIGHLIGHT_L10N_IDs = new Map([
["price", "shopping-highlight-price"],
["quality", "shopping-highlight-quality"],
["shipping", "shopping-highlight-shipping"],
["competitiveness", "shopping-highlight-competitiveness"],
["packaging/appearance", "shopping-highlight-packaging"],
]);
/**
* Class for displaying all available highlight categories for a product and any
* highlight reviews per category.
*/
class ReviewHighlights extends MozLitElement {
/**
* highlightsMap is a map of highlight categories to an array of reviews per category.
* It is possible for a category to have no reviews.
*/
#highlightsMap;
static properties = {
highlights: { type: Object },
lang: { type: String, reflect: true },
};
static get queries() {
return {
reviewHighlightsListEl: "#review-highlights-list",
};
}
updateHighlightsMap() {
let availableKeys;
this.#highlightsMap = null;
try {
if (!this.highlights) {
return;
}
// Filter highlights that have data.
let keys = Object.keys(this.highlights);
availableKeys = keys.filter(
key => Object.values(this.highlights[key]).flat().length !== 0
);
// Filter valid highlight category types. Valid types are guaranteed to have data-l10n-ids.
availableKeys = availableKeys.filter(key =>
VALID_HIGHLIGHT_L10N_IDs.has(key)
);
// If there are no highlights to show in the end, stop here and don't render content.
if (!availableKeys.length) {
return;
}
} catch (e) {
return;
}
this.#highlightsMap = new Map();
for (let key of availableKeys) {
// Ignore negative,neutral,positive sentiments and simply append review strings into one array.
let reviews = Object.values(this.highlights[key]).flat();
this.#highlightsMap.set(key, reviews);
}
}
createHighlightElement(type, reviews) {
let highlightEl = document.createElement("highlight-item");
// We already verify highlight type and its l10n id in updateHighlightsMap.
let l10nId = VALID_HIGHLIGHT_L10N_IDs.get(type);
highlightEl.id = type;
highlightEl.l10nId = l10nId;
highlightEl.highlightType = type;
highlightEl.reviews = reviews;
highlightEl.lang = this.lang;
return highlightEl;
}
render() {
this.updateHighlightsMap();
if (!this.#highlightsMap) {
this.hidden = true;
return null;
}
this.hidden = false;
let highlightsTemplate = [];
for (let [key, value] of this.#highlightsMap) {
let highlightEl = this.createHighlightElement(key, value);
highlightsTemplate.push(highlightEl);
}
return html`
<shopping-card
data-l10n-id="shopping-highlights-label"
data-l10n-attrs="label"
type="show-more"
>
<div slot="content" id="review-highlights-wrapper">
<dl id="review-highlights-list">${highlightsTemplate}</dl>
</div>
</shopping-card>
`;
}
}
customElements.define("review-highlights", ReviewHighlights);
|