PageSourceSearch

https://blog.asogi.fun/js/main.js

js asogi.fun collected 2026-09-24 15:01:25 UTC 4,755 bytes, 172 lines download raw bytes

1const Toast = (function () {
2  let container;
3
4  function getContainer() {
5    if (container) return container;
6
7    container = document.createElement("div");
8    container.style.cssText = `
9      position: fixed;
10      top: 20px;
11      left: 50%;
12      transform: translateX(-50%);
13      z-index: 9999;
14    `;
15
16    if (document.body) {
17      document.body.appendChild(container);
18    } else {
19      document.addEventListener("DOMContentLoaded", () => {
20        document.body.appendChild(container);
21      });
22    }
23
24    return container;
25  }
26
27  class ToastMessage {
28    constructor(message, type) {
29      this.message = message;
30      this.type = type;
31      this.element = null;
32      this.create();
33    }
34
35    create() {
36      this.element = document.createElement("div");
37      this.element.textContent = this.message;
38      this.element.style.cssText = `
39        background-color: ${this.type === "success" ? "#4CAF50" : "#F44336"};
40        color: white;
41        padding: 12px 24px;
42        border-radius: 4px;
43        margin-bottom: 10px;
44        box-shadow: 0 2px 5px rgba(0,0,0,0.2);
45        opacity: 0;
46        transition: opacity 0.3s ease-in-out;
47      `;
48      getContainer().appendChild(this.element);
49
50      setTimeout(() => {
51        this.element.style.opacity = "1";
52      }, 10);
53
54      setTimeout(() => {
55        this.remove();
56      }, 3000);
57    }
58
59    remove() {
60      this.element.style.opacity = "0";
61      setTimeout(() => {
62        const parent = this.element.parentNode;
63        if (parent) {
64          parent.removeChild(this.element);
65        }
66      }, 300);
67    }
68  }
69
70  function showToast(message, type) {
71    if (document.readyState === "loading") {
72      document.addEventListener("DOMContentLoaded", () => {
73        new ToastMessage(message, type);
74      });
75    } else {
76      new ToastMessage(message, type);
77    }
78  }
79
80  return {
81    success: function (message) {
82      showToast(message, "success");
83    },
84    error: function (message) {
85      showToast(message, "error");
86    },
87  };
88})();
89
90function sendVerificationCode(button, sendRequest) {
91  let timer;
92  const countdown = 60;
93  const originalButtonText = button.textContent;
94
95  button.addEventListener("click", () => {
96    button.disabled = true;
97    button.textContent = i18nResources.sendVerificationCodeSending;
98    sendRequest()
99      .then(() => {
100        startCountdown();
101        Toast.success(i18nResources.sendVerificationCodeSuccess);
102      })
103      .catch((e) => {
104        button.disabled = false;
105        button.textContent = originalButtonText;
106        if (e instanceof Error) {
107          Toast.error(e.message);
108        } else {
109          Toast.error(i18nResources.sendVerificationCodeFailed);
110        }
111      });
112  });
113
114  function startCountdown() {
115    let remainingTime = countdown;
116    button.disabled = true;
117    button.classList.add("disabled");
118
119    timer = setInterval(() => {
120      if (remainingTime > 0) {
121        button.textContent = `${remainingTime}s`;
122        remainingTime--;
123      } else {
124        clearInterval(timer);
125        button.textContent = originalButtonText;
126        button.disabled = false;
127        button.classList.remove("disabled");
128      }
129    }, 1000);
130  }
131}
132
133document.addEventListener("DOMContentLoaded", () => {
134  const passwordContainers = document.querySelectorAll(".toggle-password-display-flag");
135
136  passwordContainers.forEach((container) => {
137    const passwordInput = container.querySelector('input[type="password"]');
138    const toggleButton = container.querySelector(".toggle-password-button");
139    const displayIcon = container.querySelector(".password-display-icon");
140    const hiddenIcon = container.querySelector(".password-hidden-icon");
141
142    if (passwordInput && toggleButton && displayIcon && hiddenIcon) {
143      toggleButton.addEventListener("click", () => {
144        if (passwordInput.type === "password") {
145          passwordInput.type = "text";
146          displayIcon.style.display = "none";
147          hiddenIcon.style.display = "block";
148        } else {
149          passwordInput.type = "password";
150          displayIcon.style.display = "block";
151          hiddenIcon.style.display = "none";
152        }
153      });
154    }
155  });
156});
157
158function setupPasswordConfirmation(passwordId, confirmPasswordId) {
159  const password = document.getElementById(passwordId);
160  const confirmPassword = document.getElementById(confirmPasswordId);
161
162  function validatePasswordMatch() {
163    if (password.value !== confirmPassword.value) {
164      confirmPassword.setCustomValidity(i18nResources.passwordConfirmationFailed);
165    } else {
166      confirmPassword.setCustomValidity("");
167    }
168  }
169
170  password.addEventListener("change", validatePasswordMatch);
171  confirmPassword.addEventListener("input", validatePasswordMatch);
172}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.