]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/maplibre/attribution.js
Merge pull request #7302 from tomhughes/terms-locale
[rails.git] / app / assets / javascripts / maplibre / attribution.js
1 OSM.MapLibre.AttributionControl = class extends maplibregl.AttributionControl {
2   constructor({ includeReportLink, credit, ...options } = {}) {
3     if (includeReportLink) {
4       options.compact = false;
5     }
6     super(options);
7     this._map = null;
8     this._container = null;
9     this._includeReportLink = Boolean(includeReportLink);
10     this._credit = credit;
11     this._boundUpdateReportLink = this._updateReportLink.bind(this);
12   }
13
14   _updateAttributions() {
15     if (!this._map.style) return;
16
17     let attribHTML = "";
18
19     // Without the map being loaded, a user is unlikely to have good data-feedback
20     if (this._includeReportLink && this._map.loaded()) {
21       const reportLink = document.createElement("a");
22       reportLink.href = "/fixthemap";
23       reportLink.target = "_blank";
24       reportLink.rel = "noopener noreferrer";
25       reportLink.className = "maplibregl-ctrl-attrib-report-link";
26       reportLink.textContent = OSM.i18n.t("javascripts.embed.report_problem");
27       attribHTML += reportLink.outerHTML + " | ";
28     }
29
30     const copyrightLink = document.createElement("a");
31     copyrightLink.href = "/copyright";
32     copyrightLink.textContent = OSM.i18n.t("javascripts.map.openstreetmap_contributors");
33
34     attribHTML += OSM.i18n.t("javascripts.map.copyright_text", {
35       copyright_link: copyrightLink.outerHTML
36     });
37
38     if (this._credit) {
39       attribHTML += this._credit.donate ? " ♥️ " : ". ";
40       attribHTML += this._buildCreditHtml(this._credit);
41     }
42
43     attribHTML += ". ";
44
45     const termsLink = document.createElement("a");
46     termsLink.href = "https://wiki.osmfoundation.org/wiki/Terms_of_Use";
47     termsLink.target = "_blank";
48     termsLink.rel = "noopener noreferrer";
49     termsLink.textContent = OSM.i18n.t("javascripts.map.website_and_api_terms");
50     attribHTML += termsLink.outerHTML;
51
52     // check if attribution string is different to minimize DOM changes
53     if (attribHTML === this._attribHTML) return;
54
55     this._innerContainer.innerHTML = attribHTML;
56     this._attribHTML = attribHTML;
57     this._updateCompact();
58
59     // Update report link href after initial render
60     if (this._includeReportLink) {
61       this._updateReportLink();
62     }
63   }
64
65   _buildCreditHtml(credit) {
66     const children = {};
67     for (const childId in credit.children) {
68       children[childId] = this._buildCreditHtml(credit.children[childId]);
69     }
70
71     const text = OSM.i18n.t(`javascripts.map.${credit.id}`, children);
72
73     if (!credit.href) {
74       return text;
75     }
76     const link = document.createElement("a");
77     link.href = credit.href;
78     link.textContent = text;
79
80     if (credit.donate) {
81       link.className = "donate-attr";
82     } else {
83       link.target = "_blank";
84       link.rel = "noopener noreferrer";
85     }
86
87     return link.outerHTML;
88   }
89
90   onAdd(map) {
91     this._map = map;
92
93     if (this._includeReportLink) {
94       map.once("load", this._updateAttributions.bind(this));
95       map.on("moveend", this._boundUpdateReportLink);
96     }
97
98     return super.onAdd(map);
99   }
100
101   onRemove() {
102     if (!this._map) return;
103
104     if (this._includeReportLink) {
105       this._map.off("moveend", this._boundUpdateReportLink);
106     }
107     this._map = null;
108     super.onRemove();
109   }
110
111   _updateReportLink() {
112     if (!this._container) return;
113
114     const reportLink = this._container.querySelector(".maplibregl-ctrl-attrib-report-link");
115     if (!reportLink) return;
116
117     const center = this._map.getCenter();
118     const params = new URLSearchParams({
119       lat: center.lat.toFixed(5),
120       lon: center.lng.toFixed(5),
121       zoom: Math.floor(this._map.getZoom())
122     });
123     reportLink.href = `/fixthemap?${params.toString()}`;
124   }
125 };