summaryrefslogtreecommitdiffstats
path: root/toolkit/content/aboutwebrtc/copyButton.mjs
blob: f39210c70939d28a9bbeacabaeb600bbdf3fb901 (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
/* 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/. */

/*
 * This creates a button that can be used to copy text to the clipboard.
 * Whenever the button is pressed the getCopyContentsFn passed into the
 * constructor is called and the resulting text is copied. It uses CSS
 * transitions to perform a short animation.
 */
class CopyButton {
  constructor(getCopyContentsFn) {
    const button = document.createElement("span");
    button.textContent = String.fromCodePoint(0x1f4cb);
    button.classList.add("copy-button", "copy-button-base");
    button.onclick = () => {
      if (!button.classList.contains("copy-button")) {
        return;
      }

      const handleAnimation = async () => {
        const switchFadeDirection = () => {
          if (button.classList.contains("copy-button-fade-out")) {
            // We just faded out so let's fade in
            button.classList.toggle("copy-button-fade-out");
            button.classList.toggle("copy-button-fade-in");
          } else {
            // We just faded in so let's fade out
            button.classList.toggle("copy-button-fade-out");
            button.classList.toggle("copy-button-fade-in");
          }
        };

        // Fade out clipboard icon
        // Fade out the clipboard character
        button.classList.toggle("copy-button-fade-out");
        // Wait for CSS transition to end
        await new Promise(r => (button.ontransitionend = r));

        // Fade in checkmark icon
        // This is the start of fade in.
        // Switch to the checkmark character
        button.textContent = String.fromCodePoint(0x2705);
        // Trigger CSS fade in transition
        switchFadeDirection();
        // Wait for CSS transition to end
        await new Promise(r => (button.ontransitionend = r));

        // Fade out clipboard icon
        // Trigger CSS fade out transition
        switchFadeDirection();
        // Wait for CSS transition to end
        await new Promise(r => (button.ontransitionend = r));

        // Fade in clipboard icon
        // This is the start of fade in.
        // Switch to the clipboard character
        button.textContent = String.fromCodePoint(0x1f4cb);
        // Trigger CSS fade in transition
        switchFadeDirection();
        // Wait for CSS transition to end
        await new Promise(r => (button.ontransitionend = r));

        // Remove fade
        button.classList.toggle("copy-button-fade-in");
        // Re-enable clicks and hidding when parent div has lost :hover
        button.classList.add("copy-button");
      };

      // Note the fade effect is handled in the CSS, we just need to swap
      // between the different CSS classes. This returns a promise that waits
      // for the current fade to end, starts the next fade, then resolves.

      navigator.clipboard.writeText(getCopyContentsFn());
      // Prevent animation from disappearing when parent div losses :hover,
      // and prevent additional clicks until the animation finishes.
      button.classList.remove("copy-button");
      handleAnimation(); // runs unawaited
    };
    this.element = button;
  }
}
export { CopyButton };