/* ========================================================================== jQuery plugin settings and other scripts ========================================================================== */ $(document).ready(function () { // FitVids init $("#main").fitVids(); // Follow menu drop down $(".author__urls-wrapper button").on("click", function () { $(".author__urls").toggleClass("is--visible"); $(".author__urls-wrapper").find("button").toggleClass("open"); }); // Close search screen with Esc key $(document).keyup(function (e) { if (e.keyCode === 27) { if ($(".initial-content").hasClass("is--hidden")) { $(".search-content").toggleClass("is--visible"); $(".initial-content").toggleClass("is--hidden"); } } }); // Search toggle $(".search__toggle").on("click", function () { $(".search-content").toggleClass("is--visible"); $(".initial-content").toggleClass("is--hidden"); // set focus on input setTimeout(function () { $(".search-content input").focus(); }, 400); }); // Smooth scrolling var scroll = new SmoothScroll('a[href*="#"]', { offset: 20, speed: 400, speedAsDuration: true, durationMax: 500, }); // Gumshoe scroll spy init if ($("nav.toc").length > 0) { var spy = new Gumshoe("nav.toc a", { // Active classes navClass: "active", // applied to the nav list item contentClass: "active", // applied to the content // Nested navigation nested: false, // if true, add classes to parents of active link nestedClass: "active", // applied to the parent items // Offset & reflow offset: 20, // how far from the top of the page to activate a content area reflow: true, // if true, listen for reflows // Event support events: true, // if true, emit custom events }); } // Auto scroll sticky ToC with content const scrollTocToContent = function (event) { var target = event.target; var scrollOptions = { behavior: "auto", block: "nearest", inline: "start" }; var tocElement = document.querySelector("aside.sidebar__right.sticky"); if (!tocElement) return; if (window.getComputedStyle(tocElement).position !== "sticky") return; if (target.parentElement.classList.contains("toc__menu") && target == target.parentElement.firstElementChild) { // Scroll to top instead document.querySelector("nav.toc header").scrollIntoView(scrollOptions); } else { target.scrollIntoView(scrollOptions); } }; // Has issues on Firefox, whitelist Chrome for now if (!!window.chrome) { document.addEventListener("gumshoeActivate", scrollTocToContent); } // add lightbox class to all image links $( "a[href$='.jpg'],a[href$='.jpeg'],a[href$='.JPG'],a[href$='.png'],a[href$='.gif'],a[href$='.webp']" ).has("> img").addClass("image-popup"); // Magnific-Popup options $(".image-popup").magnificPopup({ // disableOn: function() { // if( $(window).width() < 500 ) { // return false; // } // return true; // }, type: "image", tLoading: "Loading image #%curr%...", gallery: { enabled: true, navigateByImgClick: true, preload: [0, 1], // Will preload 0 - before current, and 1 after the current image }, image: { tError: 'Image #%curr% could not be loaded.', }, removalDelay: 500, // Delay in milliseconds before popup is removed // Class that is added to body when popup is open. // make it unique to apply your CSS animations just to this exact popup mainClass: "mfp-zoom-in", callbacks: { beforeOpen: function () { // just a hack that adds mfp-anim class to markup this.st.image.markup = this.st.image.markup.replace( "mfp-figure", "mfp-figure mfp-with-anim" ); }, }, closeOnContentClick: true, midClick: true, // allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source. }); // Add anchors for headings (function () { var pageContentElement = document.querySelector(".page__content"); if (!pageContentElement) return; pageContentElement .querySelectorAll("h1, h2, h3, h4, h5, h6") .forEach(function (element) { var id = element.getAttribute("id"); if (id) { var anchor = document.createElement("a"); anchor.className = "header-link"; anchor.href = "#" + id; anchor.innerHTML = 'Permalink'; anchor.title = "Permalink"; element.appendChild(anchor); } }); })(); // Add copy button for
 blocks
  var copyText = function (text) {
    if (document.queryCommandEnabled("copy") && navigator.clipboard) {
      navigator.clipboard.writeText(text).then(
        () => true,
        () => console.error("Failed to copy text to clipboard: " + text)
      );
      return true;
    } else {
      var isRTL = document.documentElement.getAttribute("dir") === "rtl";

      var textarea = document.createElement("textarea");
      textarea.className = "clipboard-helper";
      textarea.style[isRTL ? "right" : "left"] = "-9999px";
      // Move element to the same position vertically
      var yPosition = window.pageYOffset || document.documentElement.scrollTop;
      textarea.style.top = yPosition + "px";

      textarea.setAttribute("readonly", "");
      textarea.value = text;
      document.body.appendChild(textarea);

      var success = true;
      try {
        textarea.select();
        success = document.execCommand("copy");
      } catch (e) {
        success = false;
      }
      textarea.parentNode.removeChild(textarea);
      return success;
    }
  };

  var copyButtonEventListener = function (event) {
    var thisButton = event.target;

    // Locate the  element
    var codeBlock = thisButton.nextElementSibling;
    while (codeBlock && codeBlock.tagName.toLowerCase() !== "code") {
      codeBlock = codeBlock.nextElementSibling;
    }
    if (!codeBlock) {
      // No  found - wtf?
      console.warn(thisButton);
      throw new Error("No code block found for this button.");
    }

    // Skip line numbers if present (i.e. {% highlight lineno %})
    var realCodeBlock = codeBlock.querySelector("td.code, td.rouge-code");
    if (realCodeBlock) {
      codeBlock = realCodeBlock;
    }
    var result = copyText(codeBlock.innerText);
    // Restore the focus to the button
    thisButton.focus();
    if (result) {
      if (thisButton.interval !== null) {
        clearInterval(thisButton.interval);
      }
      thisButton.classList.add('copied');
      thisButton.interval = setTimeout(function () {
        thisButton.classList.remove('copied');
        clearInterval(thisButton.interval);
        thisButton.interval = null;
      }, 1500);
    }
    return result;
  };

  if (window.enable_copy_code_button) {
    document
      .querySelectorAll(".page__content pre.highlight > code")
      .forEach(function (element, index, parentList) {
        // Locate the 
 element
        var container = element.parentElement;
        // Sanity check - don't add an extra button if there's already one
        if (container.firstElementChild.tagName.toLowerCase() !== "code") {
          return;
        }
        var copyButton = document.createElement("button");
        copyButton.title = "Copy to clipboard";
        copyButton.className = "clipboard-copy-button";
        copyButton.innerHTML = 'Copy code';
        copyButton.addEventListener("click", copyButtonEventListener);
        container.prepend(copyButton);
      });
  }
});