MediaWiki:Common.js: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
 
(58 intermediate revisions by the same user not shown)
Line 176: Line 176:


   if ($("#home").length > 0) {
   if ($("#home").length > 0) {
    console.log("The #home element exists on this page.");
     // This code will only run only on the homepage.
     // This code will only run only on the homepage.
    // Show the block view container once everything is set up
     $(".home-block-view").show();
     $(".home-block-view").show();
     $(".home-chronicle-block-button, .home-block-view-button").addClass(
     $(".home-chronicle-block-button, .home-block-view-button").addClass(
Line 184: Line 182:
     );
     );


    // Initialization and Default Settings
     // Initially hide list view sorting buttons and set the default sorted view for block
     // Initially hide list view sorting buttons and set the default sorted view for block
     $(
     $(
Line 197: Line 194:


     $(".home-list-view-button").click(function () {
     $(".home-list-view-button").click(function () {
      console.log("List view button clicked.");
       $(".home-list-sorting-buttons").css("display", "flex");
       $(".home-list-sorting-buttons").css("display", "flex");
       // Switching view classes
       // Switching view classes
Line 882: Line 878:
   function openModal(cardElement, event) {
   function openModal(cardElement, event) {
     event.stopPropagation();
     event.stopPropagation();
    $("#print-chooser").hide();
    $("#show-article").removeClass("print-opts-open");
     var pageTitle = $(cardElement).data("page") || null; // e.g. "090"
     var pageTitle = $(cardElement).data("page") || null; // e.g. "090"
     window.currentEntryTitle = pageTitle;
     window.currentEntryTitle = pageTitle;
Line 1,223: Line 1,221:
   // closeModal function
   // closeModal function
   function closeModal() {
   function closeModal() {
    $("#print-chooser").hide();
    $("#show-article").removeClass("print-opts-open");
     if ($(".home-chronicle-list").is(":visible")) {
     if ($(".home-chronicle-list").is(":visible")) {
       $(".home-list-view").css("width", "100%");
       $(".home-list-view").css("width", "100%");
Line 1,260: Line 1,260:
   });
   });


   // --- PRINT HELPERS ---
   // HERE SHOULD BE THE NEW CODE!!!!
   // Warm the font cache in the *parent* document.
  /* ---------- Softwear PRINT (scoped, ES5-safe) ---------- */
   function preloadFontForPrint() {
 
   /* helpers */
   function swPrintPreloadFont() {
     var link = document.createElement("link");
     var link = document.createElement("link");
     link.rel = "preload";
     link.rel = "preload";
Line 1,270: Line 1,272:
     link.crossOrigin = "anonymous";
     link.crossOrigin = "anonymous";
     document.head.appendChild(link);
     document.head.appendChild(link);
    // keep it; no need to remove
   }
   }


  // Simple cache buster
   function swPrintCacheBust(url) {
   function cacheBust(url) {
     return url + (url.indexOf("?") > -1 ? "&" : "?") + "_=" + Date.now();
     return url + (url.indexOf("?") > -1 ? "&" : "?") + "_=" + Date.now();
   }
   }


   // Kill any previous print handlers
   function swEnsurePrintChooser() {
  $(document).off("click.print", "#print-button");
    var $chooser = jQuery("#print-chooser");
    if ($chooser.length) return $chooser;


  $(document).on("click.print", "#print-button", function () {
    $chooser = jQuery(
    // debounce to avoid double/racing prints
      '<div id="print-chooser" class="print-chooser" style="display:none;">' +
    var $btn = $("#print-button");
        '<a href="#" id="print-with-border" class="print-choice">show border</a> ' +
     if ($btn.data("busy")) return;
        '<a href="#" id="print-no-border" class="print-choice">hide border</a>' +
    $btn.data("busy", true);
        "</div>"
    );
     jQuery("#print-button").after($chooser);


     preloadFontForPrint();
     // Bind once on the chooser to catch nested elements
    if (!$chooser.data("swBound")) {
      function chooserFire(ev, where) {
        ev = ev || window.event;
        var t = ev && (ev.target || ev.srcElement);
        var a = t && t.closest ? t.closest("a[id]") : null;
        if (!a) return;
        var id = a.getAttribute("id");
        if (id !== "print-with-border" && id !== "print-no-border") return;
        if (ev.preventDefault) ev.preventDefault();
        if (ev.stopImmediatePropagation) ev.stopImmediatePropagation();
        if (ev.stopPropagation) ev.stopPropagation();
        swHandlePrintChoice(id, (window.jQuery && jQuery(a)) || null);
        return false;
      }
      $chooser.on("pointerdown", chooserFire);
      $chooser.on("touchstart", chooserFire);
      $chooser.on("mousedown", chooserFire);
      $chooser.on("click", chooserFire);
      $chooser.data("swBound", true);
    }
    return $chooser;
  }


     var title = window.currentEntryTitle; // e.g. "090"
  function swHidePrintUI() {
    if (!title) {
     jQuery("#print-chooser").hide();
       console.warn("[print] no currentEntryTitle");
    jQuery("#show-article").removeClass("print-opts-open");
      window.print();
  }
      $btn.data("busy", false);
 
       return;
  /* small boot probe */
     }
  (function () {
    try {
       console.log("[swprint] probe on load", {
        printButton: !!document.getElementById("print-button"),
        chooserExists: !!document.getElementById("print-chooser"),
        localPrintOnlyCount: jQuery(".print-only").length,
        showArticleExists: !!document.getElementById("show-article"),
       });
     } catch (e) {}
  })();


     var pageUrl = mw.util.getUrl(title);
  /* core: build iframe and print */
     var pageUrlFresh = cacheBust(pageUrl);
  function swBuildIframeAndPrint(printHtml, borderPref, $btn) {
     console.log("[print] fetching page HTML:", pageUrlFresh);
    // iframe
     var iframe = document.createElement("iframe");
     iframe.style.position = "fixed";
    iframe.style.right = "0";
    iframe.style.bottom = "0";
    iframe.style.width = "0";
    iframe.style.height = "0";
     iframe.style.border = "0";
    document.body.appendChild(iframe);


     $.get(pageUrlFresh)
     var doc = iframe.contentDocument || iframe.contentWindow.document;
      .done(function (html) {
    doc.open();
        var $tmp = $("<div>").html(html);
    doc.write(
        var $print = $tmp.find(".print-only").first();
      '<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>'
        console.log("[print] .print-only found:", $print.length);
    );
    doc.close();


        if (!$print.length) {
    // make relative URLs resolve
          console.warn("[print] no .print-only found; fallback print");
    var base = doc.createElement("base");
          window.print();
    base.href = location.origin + "/";
          $btn.data("busy", false);
    doc.head.appendChild(base);
          return;
        }


        // Build hidden iframe
    // print.css
        var iframe = document.createElement("iframe");
    var linkCss = doc.createElement("link");
        iframe.style.position = "fixed";
    linkCss.rel = "stylesheet";
        iframe.style.right = "0";
    linkCss.href = swPrintCacheBust(
        iframe.style.bottom = "0";
      "/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css"
        iframe.style.width = "0";
    );
        iframe.style.height = "0";
        iframe.style.border = "0";
        document.body.appendChild(iframe);


        var doc = iframe.contentDocument || iframe.contentWindow.document;
    var cssLoaded = new Promise(function (resolve) {
        doc.open();
      linkCss.onload = resolve;
        doc.write(
      linkCss.onerror = resolve;
          '<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>'
    });
        );
        doc.close();


        // Ensure relative URLs (fonts/images) resolve inside iframe
    // font preload (inside iframe)
        var base = doc.createElement("base");
    var linkFont = doc.createElement("link");
        base.href = location.origin + "/";
    linkFont.rel = "preload";
        doc.head.appendChild(base);
    linkFont.as = "font";
    linkFont.type = "font/woff2";
    linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820";
    linkFont.crossOrigin = "anonymous";


        // Inject PRINT CSS (cache-busted) and await it
    doc.head.appendChild(linkFont);
        var printCssUrl =
    doc.head.appendChild(linkCss);
          "/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css";
        var printCssFresh = cacheBust(printCssUrl);


        var linkCss = doc.createElement("link");
    // inject HTML
        linkCss.rel = "stylesheet";
    doc.body.innerHTML = printHtml;
        linkCss.href = printCssFresh;


        var cssLoaded = new Promise(function (resolve) {
    // sanitize: remove inner .print-no-border if user chose WITH border
          linkCss.onload = function () {
    (function () {
            resolve();
      var stray = doc.querySelectorAll(".print-no-border");
           };
      if (borderPref === "with" && stray.length) {
          linkCss.onerror = function () {
        Array.prototype.forEach.call(stray, function (el) {
             console.warn("[print] CSS failed to load");
           el.className = (el.className || "")
             resolve();
             .replace(/\bprint-no-border\b/g, "")
          }; // don't block
             .trim();
         });
         });
      }
    })();


        // Preload the font *inside* iframe (Chrome becomes much happier)
    // apply border preference to <html>
        var linkFont = doc.createElement("link");
    (function () {
         linkFont.rel = "preload";
      var htmlEl = doc.documentElement;
         linkFont.as = "font";
      if (borderPref === "without") {
         linkFont.type = "font/woff2";
         if (htmlEl.classList) htmlEl.classList.add("print-no-border");
         linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820";
         else if (
         linkFont.crossOrigin = "anonymous";
          (" " + htmlEl.className + " ").indexOf(" print-no-border ") === -1
         ) {
          htmlEl.className += " print-no-border";
         }
      } else {
        if (htmlEl.classList) htmlEl.classList.remove("print-no-border");
         else
          htmlEl.className = (htmlEl.className || "").replace(
            /\bprint-no-border\b/g,
            ""
          );
      }
    })();


        doc.head.appendChild(linkFont);
    // OPTIONAL: glue label + body together (extra safety vs. page breaks)
         doc.head.appendChild(linkCss);
    (function () {
      var style = doc.createElement("style");
      style.textContent =
         "@media print{.sw-keep{break-inside:avoid;page-break-inside:avoid;}}";
      doc.head.appendChild(style);


         // Inject the printable HTML
      var pairs = [
         doc.body.innerHTML = $print.prop("outerHTML");
         [".article-label-description", ".article-description"],
         [".article-label-reflection", ".article-reflection"],
        [".article-label-external-reference", ".article-external-reference"],
        [".article-label-quote", ".article-quote"],
        [".article-label-modification-date", ".article-modification-date"],
      ];


         // Wait helpers
      for (var i = 0; i < pairs.length; i++) {
         function waitImages() {
         var labelSel = pairs[i][0];
          var imgs = Array.from(doc.images || []);
         var bodySel = pairs[i][1];
          if (!imgs.length) return Promise.resolve();
        var labels = doc.querySelectorAll(labelSel);
           return Promise.all(
        for (var j = 0; j < labels.length; j++) {
            imgs.map(function (img) {
          var label = labels[j];
              if (img.decode) return img.decode().catch(function () {}); // ignore decode failures
           var body = label.nextElementSibling;
              return new Promise(function (res) {
          if (!body || !body.matches(bodySel)) continue;
                if (img.complete) return res();
          var wrap = doc.createElement("div");
                img.onload = img.onerror = function () {
          wrap.className = "sw-keep";
                  res();
          label.parentNode.insertBefore(wrap, label);
                };
          wrap.appendChild(label);
              });
           wrap.appendChild(body);
            })
           );
         }
         }
      }
    })();


        function waitFonts(timeoutMs) {
    // clean empty paragraphs
          if (!doc.fonts || !doc.fonts.ready) return Promise.resolve();
    (function () {
           var ready = doc.fonts.ready;
      var ps = doc.querySelectorAll("#article-content p");
           var t = new Promise(function (res) {
      Array.prototype.forEach.call(ps, function (p) {
            setTimeout(res, timeoutMs || 1200);
        var txt = (p.textContent || "").replace(/\u00a0/g, " ").trim();
           });
        var onlyBr =
           return Promise.race([ready, t]);
           p.children &&
          p.children.length === 1 &&
          p.firstElementChild &&
          p.firstElementChild.tagName === "BR";
        if (
           (!txt && !p.querySelector("img, a, strong, em, span:not(:empty)")) ||
          onlyBr
        ) {
          if (p.parentNode) p.parentNode.removeChild(p);
        }
      });
      var root = doc.getElementById("article-content");
      if (root) {
        var kids = Array.prototype.slice.call(root.childNodes);
        for (var k = 0; k < kids.length; k++) {
           var n = kids[k];
           if (n.nodeType === 3 && !n.textContent.replace(/\s+/g, "")) {
            root.removeChild(n);
          }
         }
         }
      }
    })();
    // inline micro-tweaks for print spacing
    (function () {
      var css =
        "@media print{" +
        "  .article-description p,.article-reflection p,.article-external-reference p,.article-quote p{margin:0 0 1.2mm!important;}" +
        "  .article-description p:last-child,.article-reflection p:last-child,.article-external-reference p:last-child,.article-quote p:last-child{margin-bottom:0!important;}" +
        "  .article-entry-number,.link-pdf,.article-type,.article-metadata,.article-images,.article-description,.article-reflection,.article-external-reference,.article-quote,.article-mod-line{padding-bottom:1mm!important;}" +
        "  .article-label-description + .article-description," +
        "  .article-label-reflection + .article-reflection," +
        "  .article-label-external-reference + .article-external-reference," +
        "  .article-label-quote + .article-quote," +
        "  .article-label-modification-date + .article-modification-date{margin-top:0!important;}" +
        "  .article-title-link{margin:0!important;padding:0!important;}" +
        "  .article-title-link > *{margin:0!important;}" +
        "  .link-pdf{margin-top:0!important;}" +
        "  #article-content > :last-child{padding-bottom:0!important;}" +
        "  #article-content > :last-child::after{content:none!important;}" +
        "}";
      var style = doc.createElement("style");
      style.type = "text/css";
      style.appendChild(doc.createTextNode(css));
      doc.head.appendChild(style);
    })();


        // **Load the specific face** so Chrome actually uses it
    // link tweaks (wrapping / underline)
        function waitSpecificFont(timeoutMs) {
    (function () {
          if (!doc.fonts || !doc.fonts.load) return Promise.resolve();
      var styleFix = doc.createElement("style");
          var p = Promise.all([
      styleFix.textContent =
            doc.fonts.load('400 16px "HALColant-TextRegular"'),
        "@media print {.article-external-reference a,.link-pdf a{white-space:nowrap!important;word-break:normal!important;overflow-wrap:normal!important;text-decoration:underline}.article-external-reference{overflow-wrap:anywhere;word-break:break-word}a[href]{position:relative}}";
            doc.fonts.load('normal 16px "HALColant-TextRegular"'),
      doc.head.appendChild(styleFix);
          ]);
 
           var t = new Promise(function (res) {
      var refs = doc.querySelectorAll(".article-external-reference a[href]");
             setTimeout(res, timeoutMs || 1200);
      Array.prototype.forEach.call(refs, function (a) {
           });
        var txt = (a.textContent || "").trim();
           return Promise.race([p, t]);
        var href = a.getAttribute("href") || "";
        var looksLongUrl = /^https?:\/\//i.test(txt) && txt.length > 60;
        if (looksLongUrl) {
           try {
            var u = new URL(href, doc.baseURI);
            var label =
              u.hostname + (u.pathname.replace(/\/$/, "") ? u.pathname : "");
             if (label.length > 40) label = label.slice(0, 37) + "…";
            a.textContent = label;
           } catch (e) {
            a.textContent = "Link";
           }
         }
         }
        a.style.whiteSpace = "nowrap";
        a.style.wordBreak = "normal";
        a.style.overflowWrap = "normal";
      });
    })();


         function nextFrame() {
    // waits
    function waitImages() {
      var imgs = [].slice.call(doc.images || []);
      if (!imgs.length) return Promise.resolve();
      return Promise.all(
         imgs.map(function (img) {
          if (img.decode) {
            try {
              return img.decode().catch(function () {});
            } catch (e) {}
          }
           return new Promise(function (res) {
           return new Promise(function (res) {
             (iframe.contentWindow.requestAnimationFrame || setTimeout)(res, 0);
             if (img.complete) return res();
            img.onload = img.onerror = function () {
              res();
            };
           });
           });
        })
      );
    }
    function waitFonts(timeoutMs) {
      if (!doc.fonts || !doc.fonts.ready) return Promise.resolve();
      var ready = doc.fonts.ready;
      var t = new Promise(function (res) {
        setTimeout(res, timeoutMs || 1200);
      });
      return Promise.race([ready, t]);
    }
    function waitSpecificFont(timeoutMs) {
      if (!doc.fonts || !doc.fonts.load) return Promise.resolve();
      var p = Promise.all([
        doc.fonts.load('400 16px "HALColant-TextRegular"'),
        doc.fonts.load('normal 16px "HALColant-TextRegular"'),
      ]);
      var t = new Promise(function (res) {
        setTimeout(res, timeoutMs || 1200);
      });
      return Promise.race([p, t]);
    }
    function nextFrame() {
      return new Promise(function (res) {
        (iframe.contentWindow.requestAnimationFrame || setTimeout)(res, 0);
      });
    }
    Promise.all([
      cssLoaded,
      waitImages(),
      waitFonts(1200),
      waitSpecificFont(1200),
      nextFrame(),
    ])
      .then(function () {
        // filename via document.title
        var entryNum = "";
        var numEl = doc.querySelector(".article-entry-number");
        if (numEl) {
          var m = (numEl.textContent || "").match(/\d+/);
          entryNum = m ? m[0] : "";
         }
         }
        var desiredTitle =
          (entryNum ? entryNum + "." : "") + "softwear.directory";
        var oldIframeTitle = doc.title;
        var oldParentTitle = document.title;


        // Extra cleanup guard (Chrome sometimes delays afterprint)
         iframe.contentWindow.onafterprint = function () {
         iframe.contentWindow.onafterprint = function () {
          try {
            doc.title = oldIframeTitle;
            document.title = oldParentTitle;
          } catch (e) {}
           setTimeout(function () {
           setTimeout(function () {
             if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
             if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
           }, 100);
           }, 100);
           $btn.data("busy", false);
           if ($btn && $btn.length) $btn.data("busy", false);
         };
         };


         Promise.all([
         doc.title = desiredTitle;
          cssLoaded,
        document.title = desiredTitle;
          waitImages(),
 
          waitFonts(1200),
        iframe.contentWindow.focus();
          waitSpecificFont(1200),
        iframe.contentWindow.print();
          nextFrame(), // settle layout
 
         ]).then(function () {
        // safety cleanup
         setTimeout(function () {
           try {
           try {
             iframe.contentWindow.focus();
             doc.title = oldIframeTitle;
            iframe.contentWindow.print();
            document.title = oldParentTitle;
          } finally {
          } catch (e) {}
            // fallback cleanup in case onafterprint doesn't fire
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
            setTimeout(function () {
          if ($btn && $btn.length) $btn.data("busy", false);
              if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        }, 1000);
              $btn.data("busy", false);
      })
            }, 1000);
      .catch(function () {
           }
        if ($btn && $btn.length) $btn.data("busy", false);
         });
      });
  }
 
  /* decide source & kick print */
  function swHandlePrintChoice(id, $btn) {
    if ($btn && $btn.data("busy")) return;
    if ($btn && $btn.length) $btn.data("busy", true);
 
    var borderPref = id === "print-no-border" ? "without" : "with";
    swPrintPreloadFont();
 
    // prefer local .print-only (Entry page)
    var localPrintOnly = jQuery(".print-only").first();
    if (localPrintOnly.length) {
      swHidePrintUI();
      swBuildIframeAndPrint(localPrintOnly.prop("outerHTML"), borderPref, $btn);
      return;
    }
 
    // otherwise fetch by title (modal/home)
    var title =
      window.currentEntryTitle ||
      (window.mw && mw.config && mw.config.get && mw.config.get("wgPageName"));
    if (!title) {
      window.print();
      if ($btn && $btn.length) $btn.data("busy", false);
      return;
    }
 
    var pageUrl =
      window.mw && mw.util && mw.util.getUrl
        ? mw.util.getUrl(title)
        : "/wiki/" + String(title);
 
    jQuery
      .get(swPrintCacheBust(pageUrl))
      .done(function (html) {
        var $tmp = jQuery("<div>").html(html);
        var $print = $tmp.find(".print-only").first();
        if (!$print.length) {
          window.print();
          if ($btn && $btn.length) $btn.data("busy", false);
           return;
        }
         swHidePrintUI();
        swBuildIframeAndPrint($print.prop("outerHTML"), borderPref, $btn);
       })
       })
       .fail(function (xhr) {
       .fail(function () {
        console.warn(
          "[print] fetch failed:",
          xhr && xhr.status,
          xhr && xhr.statusText
        );
         window.print();
         window.print();
         $("#print-button").data("busy", false);
         jQuery("#print-button").data("busy", false);
       });
       });
  }
  /* bind current choice anchors (defensive, for Entry pages) */
  function swBindChoiceAnchors() {
    var sel = "#print-with-border, #print-no-border";
    var els = document.querySelectorAll(sel);
    for (var i = 0; i < els.length; i++) {
      (function (el) {
        if (el.__swChoiceBound) return;
        el.__swChoiceBound = true;
        // ensure clickable/accessible
        try {
          el.style.pointerEvents = el.style.pointerEvents || "auto";
          if (!el.getAttribute("role")) el.setAttribute("role", "button");
          if (!el.getAttribute("tabindex")) el.setAttribute("tabindex", "0");
        } catch (e) {}
        function fire(ev) {
          if (ev && ev.preventDefault) ev.preventDefault();
          if (ev && ev.stopImmediatePropagation) ev.stopImmediatePropagation();
          if (ev && ev.stopPropagation) ev.stopPropagation();
          var $a = (window.jQuery && jQuery(el)) || null;
          swHandlePrintChoice(el.id, $a);
          return false;
        }
        // early + normal phases
        el.addEventListener("pointerdown", fire, true);
        el.addEventListener("touchstart", fire, true);
        el.addEventListener("mousedown", fire, true);
        el.addEventListener("click", fire, true);
        el.addEventListener("click", fire, false);
        if (!el.onclick) el.onclick = fire;
        // keyboard
        el.addEventListener(
          "keydown",
          function (e) {
            var k = e.key || e.keyCode;
            if (k === "Enter" || k === 13 || k === " " || k === 32) fire(e);
          },
          true
        );
      })(els[i]);
    }
  }
  /* early global catcher (minimal) */
  (function () {
    if (window.__swprintEarlyCatcher) return;
    window.__swprintEarlyCatcher = true;
    function routeEarly(ev) {
      var t = ev.target;
      if (!t || !t.closest) return;
      var a = t.closest("a#print-with-border, a#print-no-border");
      if (!a) return;
      if (ev.preventDefault) ev.preventDefault();
      if (ev.stopImmediatePropagation) ev.stopImmediatePropagation();
      if (ev.stopPropagation) ev.stopPropagation();
      swHandlePrintChoice(a.id, (window.jQuery && jQuery(a)) || null);
      return false;
    }
    window.addEventListener("pointerdown", routeEarly, true);
    window.addEventListener("touchstart", routeEarly, true);
    window.addEventListener("mousedown", routeEarly, true);
  })();
  /* wiring (namespaced) */
  jQuery(document).off("click.swprint");
  jQuery(document).on(
    "click.swprint",
    "#print-button, #print-chooser, #print-options",
    function (e) {
      // main [print] toggler
      if (jQuery(e.target).closest("#print-button").length) {
        e.preventDefault();
        var $chooser = swEnsurePrintChooser();
        $chooser.css({ position: "absolute", zIndex: 99999 });
        $chooser.toggle();
        var visible = $chooser.is(":visible");
        jQuery("#show-article").toggleClass("print-opts-open", visible);
        // ensure anchors are bound (important on Entry pages)
        swBindChoiceAnchors();
        return;
      }
      // click directly on a choice link (fallback path)
      var $choice = jQuery(e.target).closest(
        "a#print-with-border, a#print-no-border"
      );
      if (!$choice.length) return;
      e.preventDefault();
      swHandlePrintChoice($choice.attr("id"), $choice);
    }
  );
  // map any <button> inside chooser to its host anchor
  jQuery(document).on(
    "click.swprintChoiceBtn2",
    "#print-chooser button",
    function (e) {
      var host = this.closest(
        '[id="print-with-border"], [id="print-no-border"]'
      );
      if (!host) return;
      e.preventDefault();
      swHandlePrintChoice(host.id, (window.jQuery && jQuery(host)) || null);
    }
  );
  // hide choices on ESC
  jQuery(document).on("keydown.swprint", function (e) {
    if (e && e.keyCode === 27) swHidePrintUI();
   });
   });
  /* ---------- /Softwear PRINT ---------- */


   // Close modal with Close button
   // Close modal with Close button
   $("#close-button").on("click", function () {
   $("#close-button").on("click", function () {
    $("#print-chooser").hide();
    $("#show-article").removeClass("print-opts-open");
     $(".list-container").removeClass("fade-out");
     $(".list-container").removeClass("fade-out");
     closeModal();
     closeModal();
Line 1,512: Line 1,856:
   }
   }


   // NRS ENTRIES  ---------------------  SECTION //
   // paragraph-formatting block
  console.log("Document ready!"); // Check if document ready event is triggered
   if (jQuery("#show-article-wrapper-entry").length) {
 
   if ($("#show-article-wrapper-entry").length) {
    console.log("Element with id 'show-article-wrapper-entry' found!"); // Check if the target element exists
 
    // Your existing formatParagraphs function
     function formatParagraphs(text) {
     function formatParagraphs(text) {
       var paragraphs = text.split("\n").filter(function (p) {
      // split on newlines, drop empty lines, wrap each in <p>
         return p.trim() !== "";
       var parts = String(text || "").split("\n");
      });
      var out = [];
      return paragraphs
      for (var i = 0; i < parts.length; i++) {
         .map(function (p) {
         var p = parts[i].replace(/^\s+|\s+$/g, "");
          return "<p>" + p.trim() + "</p>";
         if (p) out.push("<p>" + p + "</p>");
        })
      }
        .join("");
      return out.join("");
     }
     }


     // Check if ".article-description" exists and format its text
     jQuery(
    if ($(".article-description").length) {
      "#show-article .article-description, #show-article .article-reflection"
       var descriptionText = $(".article-description").text();
    ).each(function () {
       var formattedDescription = formatParagraphs(descriptionText);
       var $el = jQuery(this);
      $(".article-description").html(formattedDescription); // Set the formatted text
       if ($el.children("p").length > 0) return; // already formatted by PageForms
    }
       var rawText = $el.text();
 
       $el.html(formatParagraphs(rawText));
    // Check if ".article-reflection" exists and format its text
     });
    if ($(".article-reflection").length) {
       var reflectionText = $(".article-reflection").text();
      var formattedReflection = formatParagraphs(reflectionText);
       $(".article-reflection").html(formattedReflection); // Set the formatted text
     }
   }
   }


Line 1,605: Line 1,939:
   // Check if #submit button exists and add event listener if it does
   // Check if #submit button exists and add event listener if it does
   var submitButton = document.querySelector("#submit");
   var submitButton = document.querySelector("#submit");
  console.log("Submit button:", submitButton);


   if (submitButton) {
   if (submitButton) {
    console.log("#submit button found.");
     // Add click event listener
     // Add click event listener
     submitButton.addEventListener("click", function (event) {
     submitButton.addEventListener("click", function (event) {
      console.log("Submit button clicked.");
       event.preventDefault(); // Prevent the default link behavior
       event.preventDefault(); // Prevent the default link behavior


Navigation menu