summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/bouncetrackingprotection/test/browser/file_bounce.html
blob: d7aa1174815e4e2db788687bfea4e2ef8f6f65d4 (plain)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Bounce!</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>

<body>
  <p id="test-config"></p>
  <script>
    const SET_STATE_HANDLERS = {
      "cookie-client": setCookie,
      "localStorage": setLocalStorage,
      "indexedDB": setIndexedDB,
    };

    function setCookie(id) {
      let cookie = document.cookie;
      if (cookie) {
        console.info("Received cookie", cookie);
      } else {
        let newCookie = `id=${id}`;
        console.info("Setting new cookie", newCookie);
        document.cookie = newCookie;
      }
    }

    function setLocalStorage(id) {
      let entry = localStorage.getItem("id");
      if (entry) {
        console.info("Found localStorage entry. id", entry);
      } else {
        console.info("Setting new localStorage entry. id", id);
        localStorage.setItem(id, id);
      }
    }

    function setIndexedDB() {
      return new Promise((resolve, reject) => {
        let request = window.indexedDB.open("bounce", 1);
        request.onsuccess = () => {
          console.info("Opened indexedDB");
          resolve()
        };
        request.onerror = (event) => {
          console.error("Error opening indexedDB", event);
          reject();
        };
        request.onupgradeneeded = (event) => {
          console.info("Initializing indexedDB");
          let db = event.target.result;
          db.createObjectStore("bounce");
        };
      });
    }

    function setIndexedDBInWorker(nested = false) {
      let worker = new Worker("file_web_worker.js");
      let msg = nested ? "setIndexedDBNested" : "setIndexedDB";
      worker.postMessage(msg);
      return new Promise((resolve, reject) => {
        worker.onmessage = () => {
          console.info("IndexedDB set in worker");
          resolve();
        };
        worker.onerror = (event) => {
          console.error("Error setting indexedDB in worker", event);
          reject();
        };
      });
    }

    /**
     * Set a state in a child frame.
     */
    function setStateInFrame() {
      // Embed self
      let iframe = document.createElement("iframe");

      let src = new URL(location.href);
      // Remove search params we don't need for the iframe.
      src.searchParams.delete("target");
      src.searchParams.delete("redirectDelay");
      src.searchParams.delete("setStateSameSiteFrame");
      iframe.src = src.href;

      let frameReadyPromise = new Promise((resolve) => {
        iframe.addEventListener("load", () => {
          iframe.contentWindow.readyPromise.then(resolve);
        });
      });
      document.body.appendChild(iframe);

      return frameReadyPromise;
    }

    // Wrap the entire block so we can run async code. Store the result in a
    // promise so that parent windows can wait for us to be ready.
    window.readyPromise = (async () => {
      let url = new URL(location.href);
      // Display the test config in the body.
      document.getElementById("test-config").innerText = JSON.stringify(Object.fromEntries(url.searchParams), null, 2);

      if (url.searchParams.get("setStateSameSiteFrame") === "true") {
        // Set state in a child frame.
        await setStateInFrame(url);
      } else if(url.searchParams.get("setStateInWebWorker") === "true") {
        // Set state in a worker.
        await setIndexedDBInWorker();
      } else if(url.searchParams.get("setStateInNestedWebWorker") === "true") {
        // Set state in a nested worker.
        await setIndexedDBInWorker(true);
      } else {
        // Set a state in this window.
        let setState = url.searchParams.get("setState");
        if (setState) {
          let id = Math.random().toString();

          let handler = SET_STATE_HANDLERS[setState];
          if (!handler) {
            throw new Error("Unknown state handler: " + setState);
          }
          await handler(id);
        }
      }

      // Redirect to the target URL after a delay.
      // If no target is specified, do nothing.
      let redirectDelay = url.searchParams.get("redirectDelay");
      if (redirectDelay != null) {
        redirectDelay = Number.parseInt(redirectDelay);
      } else {
        redirectDelay = 50;
      }

      let target = url.searchParams.get("target");
      if (target) {
        console.info("Redirecting to", target);
        setTimeout(() => {
          location.href = target;
        }, redirectDelay);
      }
    })();
  </script>
</body>

</html>