MediaWiki:Common.js: Difference between revisions

From Erakh Codex
Jump to navigation Jump to search
Juoh (talk | contribs)
No edit summary
Juoh (talk | contribs)
No edit summary
Line 19: Line 19:
   } catch (e) {}
   } catch (e) {}


   /* --- 인라인 스타일 헬퍼 --- */
   /* --- 인라인 스타일 헬퍼 (important) --- */
   function s(el, styles) {
   function sp(el, prop, val) {
     Object.keys(styles).forEach(function(k) { el.style[k] = styles[k]; });
     el.style.setProperty(prop, val, "important");
   }
   }


   /* --- 헤더 --- */
   /* --- 헤더 --- */
   var header = document.createElement("header");
   var header = document.createElement("header");
   s(header, {
   sp(header, "position", "fixed");
    position: "fixed",
  sp(header, "top", "0");
    top: "0",
  sp(header, "left", "0");
    left: "0",
  sp(header, "right", "0");
    right: "0",
  sp(header, "z-index", "9999");
    zIndex: "9999",
  sp(header, "width", "100%");
    width: "100%",
  sp(header, "background", "#f9f6f0");
    background: "#f9f6f0",
  sp(header, "border-bottom", "1px solid #e2d9c8");
    borderBottom: "1px solid #e2d9c8",
  sp(header, "display", "flex");
    display: "flex",
  sp(header, "align-items", "center");
    alignItems: "center",
  sp(header, "justify-content", "space-between");
    justifyContent: "space-between",
  sp(header, "padding", "0 2rem");
    padding: "0 2rem",
  sp(header, "height", "56px");
    height: "56px",
  sp(header, "box-sizing", "border-box");
    boxSizing: "border-box"
  });


   /* --- 좌측 --- */
   /* --- 좌측 --- */
   var left = document.createElement("div");
   var left = document.createElement("div");
   s(left, {
   sp(left, "display", "flex");
    display: "flex",
  sp(left, "align-items", "center");
    alignItems: "center",
  sp(left, "gap", "1.75rem");
    gap: "1.75rem"
  });


   var logo = document.createElement("a");
   var logo = document.createElement("a");
   logo.href = "https://erakh.com";
   logo.href = "https://erakh.com";
   logo.textContent = "Erakh Archive";
   logo.textContent = "Erakh Archive";
   logo.style.setProperty("font-family", "'Inter', sans-serif", "important");
   sp(logo, "font-family", "'Inter', sans-serif");
   logo.style.setProperty("font-size", "1.125rem", "important");
   sp(logo, "font-size", "1.125rem");
   logo.style.setProperty("font-weight", "500", "important");
   sp(logo, "font-weight", "500");
   logo.style.setProperty("color", "#2a2218", "important");
   sp(logo, "color", "#2a2218");
   logo.style.setProperty("text-decoration", "none", "important");
   sp(logo, "text-decoration", "none");
   logo.style.setProperty("letter-spacing", "0.05em", "important");
   sp(logo, "letter-spacing", "-0.01em");
   logo.style.setProperty("text-transform", "none", "important");
   sp(logo, "text-transform", "none");
   logo.style.setProperty("font-variant", "normal", "important");
   sp(logo, "font-variant", "normal");
   logo.style.setProperty("font-variant-caps", "normal", "important");
   sp(logo, "font-variant-caps", "normal");
   logo.style.setProperty("font-feature-settings", "normal", "important");
   sp(logo, "line-height", "1");
  logo.style.setProperty("line-height", "1", "important");


   var nav = document.createElement("nav");
   var nav = document.createElement("nav");
   s(nav, { display: "flex", alignItems: "center", gap: "1.5rem" });
   sp(nav, "display", "flex");
  sp(nav, "align-items", "center");
  sp(nav, "gap", "1.5rem");


   var codexLink = document.createElement("a");
   var codexLink = document.createElement("a");
   codexLink.href = "https://codex.erakh.com";
   codexLink.href = "https://codex.erakh.com";
   codexLink.textContent = "Codex";
   codexLink.textContent = "Codex";
   s(codexLink, {
   sp(codexLink, "font-family", "'Inter', sans-serif");
    fontFamily: "'EB Garamond', serif",
  sp(codexLink, "font-size", "1rem");
    fontSize: "1rem",
  sp(codexLink, "color", "#6b5e4e");
    color: "#6b5e4e",
  sp(codexLink, "text-decoration", "none");
    textDecoration: "none",
  sp(codexLink, "text-transform", "none");
    textTransform: "none",
  sp(codexLink, "font-variant", "normal");
    fontVariant: "normal",
  sp(codexLink, "line-height", "1");
    lineHeight: "1"
   codexLink.addEventListener("mouseover", function() { this.style.setProperty("color", "#2a2218", "important"); });
  });
   codexLink.addEventListener("mouseout",  function() { this.style.setProperty("color", "#6b5e4e", "important"); });
   codexLink.addEventListener("mouseover", function() { this.style.color = "#2a2218"; });
   codexLink.addEventListener("mouseout",  function() { this.style.color = "#6b5e4e"; });


   nav.appendChild(codexLink);
   nav.appendChild(codexLink);
Line 90: Line 85:
   /* --- 우측 --- */
   /* --- 우측 --- */
   var right = document.createElement("div");
   var right = document.createElement("div");
   s(right, { display: "flex", alignItems: "center" });
   sp(right, "display", "flex");
  sp(right, "align-items", "center");


   if (user && user.email) {
   if (user && user.email) {
     /* 로그인 — 아바타 + 드롭다운 */
     /* 로그인 — 아바타 + 드롭다운 */
     var profile = document.createElement("div");
     var profile = document.createElement("div");
     s(profile, { position: "relative" });
     sp(profile, "position", "relative");


     var avatar = document.createElement("div");
     var avatar = document.createElement("div");
     avatar.textContent = user.email.slice(0, 1).toUpperCase();
     avatar.textContent = user.email.slice(0, 1).toUpperCase();
     s(avatar, {
     sp(avatar, "width", "32px");
      width: "32px",
    sp(avatar, "height", "32px");
      height: "32px",
    sp(avatar, "border-radius", "50%");
      borderRadius: "50%",
    sp(avatar, "background", "#e2d9c8");
      background: "#e2d9c8",
    sp(avatar, "border", "1px solid #c8b99a");
      border: "1px solid #c8b99a",
    sp(avatar, "display", "flex");
      display: "flex",
    sp(avatar, "align-items", "center");
      alignItems: "center",
    sp(avatar, "justify-content", "center");
      justifyContent: "center",
    sp(avatar, "cursor", "pointer");
      cursor: "pointer",
    sp(avatar, "font-family", "'Inter', sans-serif");
      fontFamily: "'Cinzel', serif",
    sp(avatar, "font-size", "0.75rem");
      fontSize: "0.75rem",
    sp(avatar, "font-weight", "500");
      color: "#2a2218",
    sp(avatar, "color", "#2a2218");
      boxSizing: "border-box",
    sp(avatar, "box-sizing", "border-box");
      fontVariant: "normal",
      textTransform: "none"
    });


     var dropdown = document.createElement("div");
     var dropdown = document.createElement("div");
     s(dropdown, {
     sp(dropdown, "display", "none");
      display: "none",
    sp(dropdown, "position", "absolute");
      position: "absolute",
    sp(dropdown, "top", "calc(100% + 8px)");
      top: "calc(100% + 8px)",
    sp(dropdown, "right", "0");
      right: "0",
    sp(dropdown, "background", "#f9f6f0");
      background: "#f9f6f0",
    sp(dropdown, "border", "1px solid #e2d9c8");
      border: "1px solid #e2d9c8",
    sp(dropdown, "min-width", "180px");
      minWidth: "180px",
    sp(dropdown, "padding", "0.5rem 0");
      padding: "0.5rem 0",
    sp(dropdown, "box-shadow", "0 4px 16px rgba(0,0,0,0.06)");
      boxShadow: "0 4px 16px rgba(0,0,0,0.06)",
    sp(dropdown, "z-index", "10000");
      zIndex: "10000",
    sp(dropdown, "box-sizing", "border-box");
      boxSizing: "border-box"
    });


     var emailDiv = document.createElement("div");
     var emailDiv = document.createElement("div");
     emailDiv.textContent = user.email;
     emailDiv.textContent = user.email;
     s(emailDiv, {
     sp(emailDiv, "padding", "0.5rem 1rem 0.75rem");
      padding: "0.5rem 1rem 0.75rem",
    sp(emailDiv, "font-family", "'Inter', sans-serif");
      fontFamily: "'EB Garamond', serif",
    sp(emailDiv, "font-size", "0.8125rem");
      fontSize: "0.875rem",
    sp(emailDiv, "color", "#6b5e4e");
      color: "#6b5e4e",
    sp(emailDiv, "border-bottom", "1px solid #e2d9c8");
      borderBottom: "1px solid #e2d9c8",
    sp(emailDiv, "margin-bottom", "0.25rem");
      marginBottom: "0.25rem",
    sp(emailDiv, "word-break", "break-all");
      fontStyle: "italic",
      wordBreak: "break-all"
    });


     var profileLink = document.createElement("a");
     var profileLink = document.createElement("a");
     profileLink.href = "https://erakh.com/profile";
     profileLink.href = "https://erakh.com/profile";
     profileLink.textContent = "Profile";
     profileLink.textContent = "Profile";
     s(profileLink, {
     sp(profileLink, "display", "block");
      display: "block",
    sp(profileLink, "width", "100%");
      width: "100%",
    sp(profileLink, "padding", "0.5rem 1rem");
      padding: "0.5rem 1rem",
    sp(profileLink, "font-family", "'Inter', sans-serif");
      fontFamily: "'Inter', sans-serif",
    sp(profileLink, "font-size", "0.8125rem");
      fontSize: "0.8125rem",
    sp(profileLink, "color", "#2a2218");
      color: "#2a2218",
    sp(profileLink, "text-decoration", "none");
      textDecoration: "none",
    sp(profileLink, "box-sizing", "border-box");
      boxSizing: "border-box",
      textTransform: "none"
    });


     var signOutBtn = document.createElement("button");
     var signOutBtn = document.createElement("button");
     signOutBtn.textContent = "Sign out";
     signOutBtn.textContent = "Sign out";
     s(signOutBtn, {
     sp(signOutBtn, "display", "block");
      display: "block",
    sp(signOutBtn, "width", "100%");
      width: "100%",
    sp(signOutBtn, "padding", "0.5rem 1rem");
      padding: "0.5rem 1rem",
    sp(signOutBtn, "font-family", "'Inter', sans-serif");
      fontFamily: "'Inter', sans-serif",
    sp(signOutBtn, "font-size", "0.8125rem");
      fontSize: "0.8125rem",
    sp(signOutBtn, "color", "#a04040");
      color: "#a04040",
    sp(signOutBtn, "text-align", "left");
      textAlign: "left",
    sp(signOutBtn, "background", "transparent");
      background: "transparent",
    sp(signOutBtn, "border", "none");
      border: "none",
    sp(signOutBtn, "cursor", "pointer");
      cursor: "pointer",
    sp(signOutBtn, "box-sizing", "border-box");
      boxSizing: "border-box",
 
      textTransform: "none"
    });
     signOutBtn.addEventListener("click", function () {
     signOutBtn.addEventListener("click", function () {
       fetch("https://erakh.com/api/auth/logout", { method: "POST", credentials: "include" })
       fetch("https://erakh.com/api/auth/logout", { method: "POST", credentials: "include" })
Line 201: Line 184:
     loginBtn.href = "https://erakh.com/login?redirect=" + encodeURIComponent(window.location.href);
     loginBtn.href = "https://erakh.com/login?redirect=" + encodeURIComponent(window.location.href);
     loginBtn.textContent = "Sign in";
     loginBtn.textContent = "Sign in";
     s(loginBtn, {
     sp(loginBtn, "font-family", "'Inter', sans-serif");
      fontFamily: "'Inter', sans-serif",
    sp(loginBtn, "font-size", "0.8125rem");
      fontSize: "0.8125rem",
    sp(loginBtn, "font-weight", "500");
      fontWeight: "500",
    sp(loginBtn, "color", "#2a2218");
      color: "#2a2218",
    sp(loginBtn, "text-decoration", "none");
      textDecoration: "none",
    sp(loginBtn, "padding", "0.4rem 1rem");
      padding: "0.4rem 1rem",
    sp(loginBtn, "border", "1px solid #c8b99a");
      border: "1px solid #c8b99a",
    sp(loginBtn, "background", "transparent");
      background: "transparent",
    sp(loginBtn, "cursor", "pointer");
      cursor: "pointer",
    sp(loginBtn, "box-sizing", "border-box");
      textTransform: "none",
    sp(loginBtn, "line-height", "1");
      boxSizing: "border-box",
      lineHeight: "1"
    });
     loginBtn.addEventListener("mouseover", function() {
     loginBtn.addEventListener("mouseover", function() {
       this.style.borderColor = "#c8a060";
       this.style.setProperty("border-color", "#c8a060", "important");
       this.style.background = "#f0ebe0";
       this.style.setProperty("background", "#f0ebe0", "important");
     });
     });
     loginBtn.addEventListener("mouseout", function() {
     loginBtn.addEventListener("mouseout", function() {
       this.style.borderColor = "#c8b99a";
       this.style.setProperty("border-color", "#c8b99a", "important");
       this.style.background = "transparent";
       this.style.setProperty("background", "transparent", "important");
     });
     });
     right.appendChild(loginBtn);
     right.appendChild(loginBtn);

Revision as of 03:48, 9 April 2026

(function () {
  /* --- Google Fonts 강제 로드 --- */
  var fontLink = document.createElement("link");
  fontLink.rel = "stylesheet";
  fontLink.href = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap";
  document.head.insertBefore(fontLink, document.head.firstChild);

  /* --- 쿠키 읽기 --- */
  function getCookie(name) {
    var match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
    return match ? decodeURIComponent(match[1]) : null;
  }

  /* --- 유저 정보 파싱 --- */
  var user = null;
  try {
    var raw = getCookie("erakh_user");
    if (raw) user = JSON.parse(raw);
  } catch (e) {}

  /* --- 인라인 스타일 헬퍼 (important) --- */
  function sp(el, prop, val) {
    el.style.setProperty(prop, val, "important");
  }

  /* --- 헤더 --- */
  var header = document.createElement("header");
  sp(header, "position", "fixed");
  sp(header, "top", "0");
  sp(header, "left", "0");
  sp(header, "right", "0");
  sp(header, "z-index", "9999");
  sp(header, "width", "100%");
  sp(header, "background", "#f9f6f0");
  sp(header, "border-bottom", "1px solid #e2d9c8");
  sp(header, "display", "flex");
  sp(header, "align-items", "center");
  sp(header, "justify-content", "space-between");
  sp(header, "padding", "0 2rem");
  sp(header, "height", "56px");
  sp(header, "box-sizing", "border-box");

  /* --- 좌측 --- */
  var left = document.createElement("div");
  sp(left, "display", "flex");
  sp(left, "align-items", "center");
  sp(left, "gap", "1.75rem");

  var logo = document.createElement("a");
  logo.href = "https://erakh.com";
  logo.textContent = "Erakh Archive";
  sp(logo, "font-family", "'Inter', sans-serif");
  sp(logo, "font-size", "1.125rem");
  sp(logo, "font-weight", "500");
  sp(logo, "color", "#2a2218");
  sp(logo, "text-decoration", "none");
  sp(logo, "letter-spacing", "-0.01em");
  sp(logo, "text-transform", "none");
  sp(logo, "font-variant", "normal");
  sp(logo, "font-variant-caps", "normal");
  sp(logo, "line-height", "1");

  var nav = document.createElement("nav");
  sp(nav, "display", "flex");
  sp(nav, "align-items", "center");
  sp(nav, "gap", "1.5rem");

  var codexLink = document.createElement("a");
  codexLink.href = "https://codex.erakh.com";
  codexLink.textContent = "Codex";
  sp(codexLink, "font-family", "'Inter', sans-serif");
  sp(codexLink, "font-size", "1rem");
  sp(codexLink, "color", "#6b5e4e");
  sp(codexLink, "text-decoration", "none");
  sp(codexLink, "text-transform", "none");
  sp(codexLink, "font-variant", "normal");
  sp(codexLink, "line-height", "1");
  codexLink.addEventListener("mouseover", function() { this.style.setProperty("color", "#2a2218", "important"); });
  codexLink.addEventListener("mouseout",  function() { this.style.setProperty("color", "#6b5e4e", "important"); });

  nav.appendChild(codexLink);
  left.appendChild(logo);
  left.appendChild(nav);

  /* --- 우측 --- */
  var right = document.createElement("div");
  sp(right, "display", "flex");
  sp(right, "align-items", "center");

  if (user && user.email) {
    /* 로그인 — 아바타 + 드롭다운 */
    var profile = document.createElement("div");
    sp(profile, "position", "relative");

    var avatar = document.createElement("div");
    avatar.textContent = user.email.slice(0, 1).toUpperCase();
    sp(avatar, "width", "32px");
    sp(avatar, "height", "32px");
    sp(avatar, "border-radius", "50%");
    sp(avatar, "background", "#e2d9c8");
    sp(avatar, "border", "1px solid #c8b99a");
    sp(avatar, "display", "flex");
    sp(avatar, "align-items", "center");
    sp(avatar, "justify-content", "center");
    sp(avatar, "cursor", "pointer");
    sp(avatar, "font-family", "'Inter', sans-serif");
    sp(avatar, "font-size", "0.75rem");
    sp(avatar, "font-weight", "500");
    sp(avatar, "color", "#2a2218");
    sp(avatar, "box-sizing", "border-box");

    var dropdown = document.createElement("div");
    sp(dropdown, "display", "none");
    sp(dropdown, "position", "absolute");
    sp(dropdown, "top", "calc(100% + 8px)");
    sp(dropdown, "right", "0");
    sp(dropdown, "background", "#f9f6f0");
    sp(dropdown, "border", "1px solid #e2d9c8");
    sp(dropdown, "min-width", "180px");
    sp(dropdown, "padding", "0.5rem 0");
    sp(dropdown, "box-shadow", "0 4px 16px rgba(0,0,0,0.06)");
    sp(dropdown, "z-index", "10000");
    sp(dropdown, "box-sizing", "border-box");

    var emailDiv = document.createElement("div");
    emailDiv.textContent = user.email;
    sp(emailDiv, "padding", "0.5rem 1rem 0.75rem");
    sp(emailDiv, "font-family", "'Inter', sans-serif");
    sp(emailDiv, "font-size", "0.8125rem");
    sp(emailDiv, "color", "#6b5e4e");
    sp(emailDiv, "border-bottom", "1px solid #e2d9c8");
    sp(emailDiv, "margin-bottom", "0.25rem");
    sp(emailDiv, "word-break", "break-all");

    var profileLink = document.createElement("a");
    profileLink.href = "https://erakh.com/profile";
    profileLink.textContent = "Profile";
    sp(profileLink, "display", "block");
    sp(profileLink, "width", "100%");
    sp(profileLink, "padding", "0.5rem 1rem");
    sp(profileLink, "font-family", "'Inter', sans-serif");
    sp(profileLink, "font-size", "0.8125rem");
    sp(profileLink, "color", "#2a2218");
    sp(profileLink, "text-decoration", "none");
    sp(profileLink, "box-sizing", "border-box");

    var signOutBtn = document.createElement("button");
    signOutBtn.textContent = "Sign out";
    sp(signOutBtn, "display", "block");
    sp(signOutBtn, "width", "100%");
    sp(signOutBtn, "padding", "0.5rem 1rem");
    sp(signOutBtn, "font-family", "'Inter', sans-serif");
    sp(signOutBtn, "font-size", "0.8125rem");
    sp(signOutBtn, "color", "#a04040");
    sp(signOutBtn, "text-align", "left");
    sp(signOutBtn, "background", "transparent");
    sp(signOutBtn, "border", "none");
    sp(signOutBtn, "cursor", "pointer");
    sp(signOutBtn, "box-sizing", "border-box");

    signOutBtn.addEventListener("click", function () {
      fetch("https://erakh.com/api/auth/logout", { method: "POST", credentials: "include" })
        .then(function () { window.location.href = "https://erakh.com"; });
    });

    dropdown.appendChild(emailDiv);
    dropdown.appendChild(profileLink);
    dropdown.appendChild(signOutBtn);

    avatar.addEventListener("click", function () {
      dropdown.style.display = dropdown.style.display === "none" ? "block" : "none";
    });
    document.addEventListener("click", function (e) {
      if (!profile.contains(e.target)) dropdown.style.display = "none";
    });

    profile.appendChild(avatar);
    profile.appendChild(dropdown);
    right.appendChild(profile);

  } else {
    /* 비로그인 — Sign in */
    var loginBtn = document.createElement("a");
    loginBtn.href = "https://erakh.com/login?redirect=" + encodeURIComponent(window.location.href);
    loginBtn.textContent = "Sign in";
    sp(loginBtn, "font-family", "'Inter', sans-serif");
    sp(loginBtn, "font-size", "0.8125rem");
    sp(loginBtn, "font-weight", "500");
    sp(loginBtn, "color", "#2a2218");
    sp(loginBtn, "text-decoration", "none");
    sp(loginBtn, "padding", "0.4rem 1rem");
    sp(loginBtn, "border", "1px solid #c8b99a");
    sp(loginBtn, "background", "transparent");
    sp(loginBtn, "cursor", "pointer");
    sp(loginBtn, "box-sizing", "border-box");
    sp(loginBtn, "line-height", "1");
    loginBtn.addEventListener("mouseover", function() {
      this.style.setProperty("border-color", "#c8a060", "important");
      this.style.setProperty("background", "#f0ebe0", "important");
    });
    loginBtn.addEventListener("mouseout", function() {
      this.style.setProperty("border-color", "#c8b99a", "important");
      this.style.setProperty("background", "transparent", "important");
    });
    right.appendChild(loginBtn);
  }

  header.appendChild(left);
  header.appendChild(right);
  document.body.insertBefore(header, document.body.firstChild);
})();