Merge branch '5.3' into 5.4
[GitHub/WoltLab/WCF.git] / ts / WoltLabSuite / Core / Ui / Message / UserConsent.ts
1 /**
2 * Prompts the user for their consent before displaying external media.
3 *
4 * @author Alexander Ebert
5 * @copyright 2001-2020 WoltLab GmbH
6 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7 * @module WoltLabSuite/Core/Ui/Message/UserConsent
8 */
9
10 import * as Ajax from "../../Ajax";
11 import * as Core from "../../Core";
12 import DomChangeListener from "../../Dom/Change/Listener";
13 import DomUtil from "../../Dom/Util";
14 import User from "../../User";
15
16 class UserConsent {
17 private enableAll = false;
18 private readonly knownButtons = new WeakSet();
19
20 constructor() {
21 if (window.sessionStorage.getItem(`${Core.getStoragePrefix()}user-consent`) === "all") {
22 this.enableAll = true;
23 }
24
25 this.registerEventListeners();
26
27 DomChangeListener.add("WoltLabSuite/Core/Ui/Message/UserConsent", () => this.registerEventListeners());
28 }
29
30 private registerEventListeners(): void {
31 if (this.enableAll) {
32 this.enableAllExternalMedia();
33 } else {
34 document.querySelectorAll(".jsButtonMessageUserConsentEnable").forEach((button: HTMLAnchorElement) => {
35 if (!this.knownButtons.has(button)) {
36 this.knownButtons.add(button);
37
38 button.addEventListener("click", (ev) => this.click(ev));
39 }
40 });
41 }
42 }
43
44 private click(event: MouseEvent): void {
45 event.preventDefault();
46
47 this.enableAll = true;
48
49 this.enableAllExternalMedia();
50
51 if (User.userId) {
52 Ajax.apiOnce({
53 data: {
54 actionName: "saveUserConsent",
55 className: "wcf\\data\\user\\UserAction",
56 },
57 silent: true,
58 });
59 } else {
60 window.sessionStorage.setItem(`${Core.getStoragePrefix()}user-consent`, "all");
61 }
62 }
63
64 private enableExternalMedia(container: HTMLElement): void {
65 const payload = atob(container.dataset.payload!);
66
67 DomUtil.insertHtml(payload, container, "before");
68 container.remove();
69 }
70
71 private enableAllExternalMedia(): void {
72 document.querySelectorAll(".messageUserConsent").forEach((el: HTMLElement) => this.enableExternalMedia(el));
73 }
74 }
75
76 let userConsent: UserConsent;
77
78 export function init(): void {
79 if (!userConsent) {
80 userConsent = new UserConsent();
81 }
82 }