SingleFile Archief

Version 1.1 by XWikiGuest on 2026/03/11 19:24
Warning
For security reasons, the document is displayed in restricted mode as it is not the current version. There may be differences and errors due to this.

SingleFile Archief

Opgeslagen webpagina's via SingleFile + Nextcloud WebDAV.

#sf-container {
  display: flex;
  height: 75vh;
  border: 1px solid #4e5d6c;
  border-radius: 4px;
  overflow: hidden;
  background: #1a2a3a;
}
#sf-filelist {
  width: 30%;
  min-width: 150px;
  max-width: 70%;
  overflow-y: auto;
  background: #2b3e50;
  border-right: none;
}
#sf-divider {
  width: 6px;
  background: #4e5d6c;
  cursor: col-resize;
  flex-shrink: 0;
  transition: background 0.2s;
}
#sf-divider:hover, #sf-divider.dragging {
  background: #df691a;
}
#sf-viewer {
  flex: 1;
  background: #fff;
  min-width: 200px;
}
#sf-viewer iframe {
  width: 100%;
  height: 100%;
  border: none;
}
#sf-filelist .sf-search {
  width: calc(100% - 16px);
  margin: 8px;
  padding: 6px 10px;
  background: #1a2a3a;
  color: #ebebeb;
  border: 1px solid #4e5d6c;
  border-radius: 4px;
  font-size: 14px;
}
#sf-filelist .sf-search::placeholder { color: #6b7c8d; }
#sf-filelist ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
#sf-filelist li {
  padding: 6px 12px;
  cursor: pointer;
  color: #5bc0de;
  font-size: 13px;
  border-bottom: 1px solid rgba(78,93,108,0.3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#sf-filelist li:hover { background: #3b4e60; }
#sf-filelist li.active { background: #4e5d6c; color: #df691a; font-weight: bold; }
#sf-filelist .sf-status { color: #6b7c8d; padding: 12px; font-size: 13px; }
#sf-viewer .sf-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #6b7c8d;
  font-size: 16px;
  background: #2b3e50;
}
Laden...
    Klik op een pagina om te bekijken
    (function() {
      var WEBDAV_BASE = 'https://cloud.rhebergen.org/remote.php/dav/files/jan_rhebergen/SingleFile/';
      var AUTH = 'Basic amFuX3JoZWJlcmdlbjpAWnMzUUwkJmZ4TVE=';
      var allFiles = [];
    
      // --- Load file list via PROPFIND ---
      function loadFiles() {
        var xhr = new XMLHttpRequest();
        xhr.open('PROPFIND', WEBDAV_BASE, true);
        xhr.setRequestHeader('Depth', '1');
        xhr.setRequestHeader('Authorization', AUTH);
        xhr.onload = function() {
          if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 207) {
            var parser = new DOMParser();
            var xml = parser.parseFromString(xhr.responseText, 'text/xml');
            var responses = xml.querySelectorAll('response');
            allFiles = [];
            responses.forEach(function(resp) {
              var href = resp.querySelector('href').textContent;
              var filename = decodeURIComponent(href.split('/').pop());
              if (!filename || filename === '') return;
              if (!filename.match(/\.html?$/i)) return;
              var lm = resp.querySelector('getlastmodified');
              var date = lm ? lm.textContent : '';
              allFiles.push({ name: filename, href: href, date: date });
            });
            allFiles.sort(function(a, b) { return b.date.localeCompare(a.date); });
            document.getElementById('sf-status').textContent = allFiles.length + ' pagina\'s';
            renderList(allFiles);
          } else {
            document.getElementById('sf-status').textContent = 'Fout: HTTP ' + xhr.status;
          }
        };
        xhr.onerror = function() {
          document.getElementById('sf-status').textContent = 'Verbindingsfout (CORS?)';
        };
        xhr.send('');
      }
    
      function renderList(files) {
        var ul = document.getElementById('sf-list');
        ul.innerHTML = '';
        files.forEach(function(f) {
          var li = document.createElement('li');
          var title = f.name.replace(/\.html?$/i, '').replace(/_/g, ' ');
          li.textContent = title;
          li.title = f.name + (f.date ? ' (' + new Date(f.date).toLocaleDateString('nl-NL') + ')' : '');
          li.onclick = function() {
            document.querySelectorAll('#sf-list li').forEach(function(el) { el.className = ''; });
            li.className = 'active';
            loadPage(f.name);
          };
          ul.appendChild(li);
        });
      }
    
      // --- Load and render a page ---
      function loadPage(filename) {
        var placeholder = document.getElementById('sf-placeholder');
        if (placeholder) placeholder.textContent = 'Laden...';
    
        fetch(WEBDAV_BASE + encodeURIComponent(filename), {
          headers: { 'Authorization': AUTH }
        })
        .then(function(r) { return r.text(); })
        .then(function(html) {
          var viewer = document.getElementById('sf-viewer');
          viewer.innerHTML = '';
          var iframe = document.createElement('iframe');
          iframe.sandbox = 'allow-same-origin';
          viewer.appendChild(iframe);
          iframe.srcdoc = html;
        })
        .catch(function(err) {
          var viewer = document.getElementById('sf-viewer');
          viewer.innerHTML = '
    Fout: ' + err.message + '
    '; }); } // --- Search filter --- window.sfFilter = function() { var q = document.getElementById('sf-search').value.toLowerCase(); if (!q) { renderList(allFiles); return; } renderList(allFiles.filter(function(f) { return f.name.toLowerCase().indexOf(q) >= 0; })); }; // --- Resizable divider --- var divider = document.getElementById('sf-divider'); var filelist = document.getElementById('sf-filelist'); var dragging = false; divider.addEventListener('mousedown', function(e) { dragging = true; divider.classList.add('dragging'); e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (!dragging) return; var container = document.getElementById('sf-container'); var rect = container.getBoundingClientRect(); var newWidth = e.clientX - rect.left; var minW = 150, maxW = rect.width * 0.7; if (newWidth >= minW && newWidth <= maxW) { filelist.style.width = newWidth + 'px'; } }); document.addEventListener('mouseup', function() { if (dragging) { dragging = false; divider.classList.remove('dragging'); } }); loadFiles(); })();