Help with javascript code and permalinks

Hi,

I am using this javascript code to hide elements of my Publish web site and activate a reader version of the site. I can activate the view using the “r” key, a button or by adding ?reader=true to the end of the url. Everything works fine.

Now I would like to activate the view directly from the document. In the future it is my goal to do it through cssClass but for the moment I got a partial working (in my web I use sliding view and the instances can be multiple). Until I solve it, I’m trying adding the ?reader=true to the permalink slug but it doesn’t work either. Does anyone have any suggestions?

Here an example.

Thanks a lot!

I have changed the code, now the script uses cssClass. You can activate the “read view” (i.e. hide Publish page elements, including sidebars for reading or for a clean image browsing) in 4 different ways:

  • using a button
  • pressing the “r” key
  • by defining the reader-view class in the cssClass property in the frontmatter
  • adding ?reader=true to the url of the page.

Demo: normal site or reader-view

Problem with sliding-window

In the normal version of Publish it works perfectly, but there is a wrong behavior in the sliding-window version: browsing the web with the “reader-view” activated, when clicking the name of the site to return to the home page, it removes the class and returns to the “normal” state, although in localStorage the “reader-view” state persists. In fact, once returned to the home page from the web logo, and reload page, it reads the localStorage and reactivates the “reader-view”.

I don’t know if I’ve explained myself well… maybe someone will want to get their hands on it at some point…

JS


// READER VIEW

// Iconos SVG para los estados visible y oculto
const iconVisible = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize-2"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" x2="14" y1="3" y2="10"/><line x1="3" x2="10" y1="21" y2="14"/></svg>`; // SVG para cuando las sidebars están visibles
const iconHidden = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minimize-2"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" x2="21" y1="10" y2="3"/><line x1="3" x2="10" y1="21" y2="14"/></svg>`; // SVG para cuando las sidebars están ocultas

// Función para alternar la clase 'reader-view' en todas las instancias de .markdown-preview-view
function toggleReaderView() {
  const markdownPreviews = document.querySelectorAll('.markdown-preview-view');
  const toggleButton = document.querySelector('#toggle-sidebar-btn');

  if (markdownPreviews.length > 0 && toggleButton) {
    const isReaderView = Array.from(markdownPreviews).some(preview => preview.classList.contains('reader-view'));

    markdownPreviews.forEach(preview => {
      if (isReaderView) {
        preview.classList.remove('reader-view');
      } else {
        preview.classList.add('reader-view');
      }
    });

    // Cambia el icono del botón según el estado de la clase 'reader-view'
    toggleButton.innerHTML = isReaderView ? iconVisible : iconHidden;

    // Guardar el estado en localStorage
    localStorage.setItem('readerView', !isReaderView);
  }
}

// Añadir un evento de escucha para la tecla "r"
document.addEventListener('keydown', function(event) {
  const activeElement = document.activeElement;
  const isSearchInputFocused = activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA');

  if (event.key === 'r' && !event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey && !isSearchInputFocused) {
    toggleReaderView();
  }
});

// Función para verificar y aplicar el estado de visibilidad inicial
function applyInitialVisibilityState() {
  const markdownPreviews = document.querySelectorAll('.markdown-preview-view');
  const toggleButton = document.querySelector('#toggle-sidebar-btn');

  // Obtener el estado de localStorage
  const isReaderView = localStorage.getItem('readerView') === 'true';

  markdownPreviews.forEach(preview => {
    if (isReaderView) {
      preview.classList.add('reader-view');
    } else {
      preview.classList.remove('reader-view');
    }
  });

  toggleButton.innerHTML = isReaderView ? iconHidden : iconVisible;
}

// Función para crear y añadir el botón de alternar al .site-body-center-column
function addToggleButton() {
  const siteBodyCenterColumn = document.querySelector('.site-body-center-column');
  if (siteBodyCenterColumn) {
    // Crea el botón
    const toggleButton = document.createElement('button');
    toggleButton.id = 'toggle-sidebar-btn';
    toggleButton.setAttribute('aria-label', 'Toggle reader view');

    // Establece el icono inicial del botón
    toggleButton.innerHTML = iconVisible;

    // Añade el evento de clic al botón
    toggleButton.addEventListener('click', toggleReaderView);

    // Añade el botón al .site-body-center-column
    siteBodyCenterColumn.appendChild(toggleButton);
  }
}

// Función para iniciar el observador de mutaciones
function waitForSiteBodyCenterColumn() {
  const observer = new MutationObserver((mutations, obs) => {
    if (document.querySelector('.site-body-center-column')) {
      addToggleButton();
      applyInitialVisibilityState(); // Aplica el estado de visibilidad inicial
      obs.disconnect(); // Detiene el observador una vez que el .site-body-center-column ha sido encontrado
    }
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true,
  });
}

// Función para verificar el parámetro de la URL y activar el reader-view si es necesario
function checkURLParameter() {
  const urlParams = new URLSearchParams(window.location.search);
  if (urlParams.get('reader') === 'true') {
    const markdownPreviews = document.querySelectorAll('.markdown-preview-view');
    markdownPreviews.forEach(preview => {
      preview.classList.add('reader-view');
    });

    // Actualizar el icono del botón
    const toggleButton = document.querySelector('#toggle-sidebar-btn');
    if (toggleButton) {
      toggleButton.innerHTML = iconHidden;
    }

    // Guardar el estado en localStorage
    localStorage.setItem('readerView', true);
  }
}

// Función para restablecer el estado de la vista de lectura después de la navegación
function resetReaderViewAfterNavigation() {
  document.addEventListener('click', (event) => {
    if (event.target.closest('.site-body-left-column-site-logo, .nav-file-title, .nav-folder-title, .nav-file, .nav-folder')) {
      setTimeout(applyInitialVisibilityState, 100); // Espera un momento para que la navegación se complete
    }
  });
}

// Función para restablecer el estado de la vista de lectura después de la carga completa de la página
function resetReaderViewOnLoad() {
  window.addEventListener('load', applyInitialVisibilityState);
}

// Ejecuta la función waitForSiteBodyCenterColumn cuando el script se carga
waitForSiteBodyCenterColumn();

// Verifica el parámetro de la URL al cargar la página
checkURLParameter();

// Restablece el estado de la vista de lectura después de la navegación
resetReaderViewAfterNavigation();

// Restablece el estado de la vista de lectura después de la carga completa de la página
resetReaderViewOnLoad();

// END TOGGLE READER VIEW

CSS

/************************  READER ************************/

@media screen and (min-width: 751px) {
    #toggle-sidebar-btn {
        margin: 0px;
        width: 30px;
        background: none;
        padding: 5px;
        position: fixed;
        right: 5px;
        top: 5px;
        background: none;
        border-radius: 50%;
        background: var(--background-primary);
        opacity: 1;
        color: var(--component-title-color);
        z-index: 100;
    }
    .sliding-windows #toggle-sidebar-btn {
        right: 287px;
        top: 25px;
    }

    #toggle-sidebar-btn:hover {
        color: var(--color-base-100);
        background: var(--background-secondary);
    }

    #toggle-sidebar-btn:hover {
        cursor: pointer;
    }
    .theme-dark #toggle-sidebar-btn {
        top: 25px;
    }


    .site-body:has(.reader-view) #toggle-sidebar-btn {
        color: var(--component-title-color);
    }
    .site-body:has(.reader-view) #toggle-sidebar-btn::before {
        content: "Press r to switch view";
        position: absolute;
        right: 33px;
        color: var(--text-faint);
        font-size: var(--font-smaller);
    }

    .site-body:has(.reader-view) .page-header {
        display: none
    }

    .site-body:has(.reader-view) .published-container .markdown-rendered h1 {
        margin-top: 0px;
    }
    .site-body:has(.reader-view) .markdown-preview-view {
        font-size: calc(0.8rem + 0.30vw);
    }

    .site-body:has(.reader-view) #toggle-sidebar-btn {
        top: 5px;
        background: transparent;
    }

    .site-body:has(.reader-view) #toggle-sidebar-btn:hover {
        background: none;
    }


    .sliding-windows .site-body:has(.reader-view) #toggle-sidebar-btn {
        right: 5px;
    }

    .published-container.has-navigation:has(.reader-view) .site-header {
        display: block;
        position: fixed;
        top: 63px;
        right: -49px;
        transform: rotate(90deg);
        z-index: 10;
    }
    .sliding-windows .site-body:has(.reader-view) .markdown-preview-view {
        padding-top:40px;
    }
    .published-container.has-navigation:has(.reader-view) .site-header .site-header-text::after {
        display: none;
    }

    .sliding-windows:has(.reader-view) .publish-renderer,
    .sliding-windows:has(.reader-view) .render-container,
    body:has(.reader-view) {
        background-color: var(--background-reader);
    }
    .site-body:has(.reader-view) .render-container-inner {
        margin: 0 auto;
    }

    body:not(.sliding-windows):has(.reader-view) .is-readable-line-width.has-outline.has-navigation .publish-renderer > .markdown-preview-view > .markdown-preview-sizer {
        margin-right: inherit;
    }
    body:not(.sliding-windows):has(.reader-view) .publish-renderer > .markdown-preview-view > .markdown-preview-sizer {
        margin: 0 auto;
    }

    .sliding-windows .publish-renderer:has(.reader-view)  {
        position: sticky;
        width: 800px;
        flex: 0 0 800px;
    }

    .sliding-windows div.hover-popover.is-loaded .publish-renderer {
        width: inherit!important;
        flex:inherit!important;
    }

    .sliding-windows .site-body:has(.reader-view) .site-body-center-column,
    .sliding-windows .published-container.has-graph .site-body:has(.reader-view) .site-body-center-column {
        padding-right: 40px;
    }
    .site-body:has(.reader-view) .site-body-center-column {
        box-shadow: none;    
        padding-left: 0px;
    }
    .site-body:has(.reader-view) .site-body-center-column {
        box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.1);
        margin-top: 0px;
    }
    .theme-dark .site-body:has(.reader-view) .site-body-center-column {
        border-top: 1px solid var(--divider-color);
    }
    .site-body:has(.reader-view) .mod-footer,
    .site-body:has(.reader-view) .outline-view-outer,
    .site-body:has(.reader-view) .graph-view-outer .published-section-header,
    .site-body:has(.reader-view) .site-footer,
    .site-body:has(.reader-view) .search-view-container,
    .site-body:has(.reader-view) .nav-view-outer,
    .site-body:has(.reader-view) .site-body-right-column,
    .site-body:has(.reader-view) .site-body-left-column-site-name,
    .site-body:has(.reader-view) .site-body-left-column-site-logo,
    .site-body:has(.reader-view) .site-body-left-column {
        display: none;
    }

}

@media screen and (max-width: 750px) {
    #toggle-sidebar-btn {
        display: none;
    }
    .site-body:has(.reader-view) .site-body-left-column {
        display: flex!important;
    }
}
@media screen and (max-width: 1024px) {
    #toggle-sidebar-btn {
        right: 10px;
    }
}

/************************  READER END ************************/

Yes! I solved the bug with sliding windows by replacing the .markdown-preview-view class with .node-insert-event. Now the script works perfectly in both Publish navigation systems.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.