Merge branch '5.5'
[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 */
8
9 import * as Ajax from "../../Ajax";
10 import * as Core from "../../Core";
11 import DomChangeListener from "../../Dom/Change/Listener";
12 import DomUtil from "../../Dom/Util";
13 import User from "../../User";
14
15 class UserConsent {
16 private enableAll = false;
17 private readonly knownButtons = new WeakSet();
18
19 constructor() {
20 if (window.sessionStorage.getItem(`${Core.getStoragePrefix()}user-consent`) === "all") {
21 this.enableAll = true;
22 }
23
24 this.registerEventListeners();
25
26 DomChangeListener.add("WoltLabSuite/Core/Ui/Message/UserConsent", () => this.registerEventListeners());
27 }
28
29 private registerEventListeners(): void {
30 if (this.enableAll) {
31 this.enableAllExternalMedia();
32 } else {
33 document.querySelectorAll(".jsButtonMessageUserConsentEnable").forEach((button: HTMLAnchorElement) => {
34 if (!this.knownButtons.has(button)) {
35 this.knownButtons.add(button);
36
37 button.addEventListener("click", (ev) => this.click(ev));
38 }
39 });
40 }
41 }
42
43 private click(event: MouseEvent): void {
44 event.preventDefault();
45
46 this.enableAll = true;
47
48 this.enableAllExternalMedia();
49
50 if (User.userId) {
51 Ajax.apiOnce({
52 data: {
53 actionName: "saveUserConsent",
54 className: "wcf\\data\\user\\UserAction",
55 },
56 silent: true,
57 });
58 } else {
59 window.sessionStorage.setItem(`${Core.getStoragePrefix()}user-consent`, "all");
60 }
61 }
62
63 private enableExternalMedia(container: HTMLElement): void {
64 if (container.dataset.target) {
65 document.getElementById(container.dataset.target)!.hidden = false;
66 } else {
67 const payload = atob(container.dataset.payload!);
68 DomUtil.insertHtml(payload, container, "before");
69 }
70
71 container.remove();
72 }
73
74 private enableAllExternalMedia(): void {
75 document.querySelectorAll(".messageUserConsent").forEach((el: HTMLElement) => this.enableExternalMedia(el));
76 }
77 }
78
79 let userConsent: UserConsent;
80
81 export function init(): void {
82 if (!userConsent) {
83 userConsent = new UserConsent();
84 }
85 }