Wiki source code of Linkding + SingleFile Archief

Version 13.1 by XWikiGuest on 2026/03/11 21:02

Hide last authors
XWikiGuest 13.1 1 = Linkding + SingleFile Archief =
XWikiGuest 1.1 2
XWikiGuest 13.1 3 Bookmarks uit Linkding met inline archief-viewer. Klik op 📄 om de opgeslagen versie te bekijken.
XWikiGuest 1.1 4
5 {{html clean="false"}}
6 <style>
XWikiGuest 12.1 7 #ldsf-container {
XWikiGuest 1.1 8 display: flex;
XWikiGuest 12.1 9 height: 75vh;
10 border: 1px solid #4e5d6c;
11 border-radius: 4px;
12 overflow: hidden;
13 }
14 #ldsf-left {
15 width: 35%;
16 min-width: 200px;
17 max-width: 60%;
18 overflow-y: auto;
19 background: #2b3e50;
20 display: flex;
XWikiGuest 1.1 21 flex-direction: column;
22 }
XWikiGuest 12.1 23 #ldsf-divider {
24 width: 6px;
25 background: #4e5d6c;
26 cursor: col-resize;
27 flex-shrink: 0;
28 transition: background 0.2s;
XWikiGuest 1.1 29 }
XWikiGuest 12.1 30 #ldsf-divider:hover, #ldsf-divider.dragging { background: #df691a; }
31 #ldsf-right {
32 flex: 1;
33 min-width: 200px;
34 display: flex;
35 flex-direction: column;
XWikiGuest 1.1 36 }
XWikiGuest 13.1 37 #ldsf-status {
38 color: #6b7c8d;
39 font-size: 13px;
40 padding: 8px 12px;
41 flex-shrink: 0;
42 }
43 #ldsf-bookmarks {
44 overflow-y: auto;
45 flex: 1;
46 }
47 #ldsf-bookmarks ul {
48 list-style: none;
49 padding: 0;
50 margin: 0;
51 }
XWikiGuest 1.1 52 #ldsf-bookmarks li {
53 padding: 6px 12px;
XWikiGuest 12.1 54 border-bottom: 1px solid rgba(78,93,108,0.3);
XWikiGuest 1.1 55 display: flex;
56 align-items: center;
57 gap: 8px;
58 }
59 #ldsf-bookmarks li:hover { background: #3b4e60; }
XWikiGuest 12.1 60 #ldsf-bookmarks a {
61 color: #5bc0de;
62 text-decoration: none;
63 overflow: hidden;
64 text-overflow: ellipsis;
XWikiGuest 13.1 65 white-space: nowrap;
XWikiGuest 12.1 66 font-size: 13px;
67 }
XWikiGuest 1.1 68 #ldsf-bookmarks a:hover { color: #df691a; }
XWikiGuest 13.1 69 .sf-btn {
XWikiGuest 1.1 70 cursor: pointer;
71 background: #4e5d6c;
72 border: none;
73 color: #5bc0de;
XWikiGuest 12.1 74 padding: 2px 6px;
XWikiGuest 1.1 75 border-radius: 3px;
XWikiGuest 12.1 76 font-size: 13px;
XWikiGuest 1.1 77 flex-shrink: 0;
78 }
XWikiGuest 13.1 79 .sf-btn:hover { background: #df691a; color: #fff; }
XWikiGuest 12.1 80 #ldsf-viewer-bar {
XWikiGuest 1.1 81 display: none;
82 justify-content: space-between;
83 align-items: center;
XWikiGuest 12.1 84 padding: 4px 12px;
XWikiGuest 1.1 85 background: #2b3e50;
XWikiGuest 13.1 86 color: #ebebeb;
XWikiGuest 12.1 87 font-size: 12px;
88 flex-shrink: 0;
89 border-bottom: 1px solid #4e5d6c;
XWikiGuest 1.1 90 }
91 #ldsf-viewer-bar .close-btn {
92 cursor: pointer;
93 color: #d9534f;
94 font-size: 18px;
95 padding: 0 4px;
96 }
97 #ldsf-viewer-bar .close-btn:hover { color: #ff6b6b; }
98 #ldsf-viewer-frame {
99 width: 100%;
XWikiGuest 12.1 100 flex: 1;
XWikiGuest 1.1 101 border: none;
102 background: #fff;
XWikiGuest 13.1 103 display: none;
XWikiGuest 1.1 104 }
XWikiGuest 12.1 105 #ldsf-placeholder {
106 display: flex;
107 align-items: center;
108 justify-content: center;
109 flex: 1;
110 color: #6b7c8d;
XWikiGuest 13.1 111 font-size: 15px;
XWikiGuest 12.1 112 background: #2b3e50;
113 }
XWikiGuest 1.1 114 </style>
115
XWikiGuest 12.1 116 <div id="ldsf-container">
117 <div id="ldsf-left">
118 <div id="ldsf-status">Laden...</div>
119 <div id="ldsf-bookmarks"></div>
120 </div>
121 <div id="ldsf-divider"></div>
122 <div id="ldsf-right">
XWikiGuest 1.1 123 <div id="ldsf-viewer-bar">
XWikiGuest 13.1 124 <span id="ldsf-viewer-title"></span>
XWikiGuest 12.1 125 <span class="close-btn" data-sfclose="1">&times;</span>
XWikiGuest 1.1 126 </div>
XWikiGuest 13.1 127 <div id="ldsf-placeholder">Klik op &#128196; om een archief te bekijken</div>
128 <iframe id="ldsf-viewer-frame" sandbox="allow-same-origin"></iframe>
XWikiGuest 1.1 129 </div>
130 </div>
131
132 <script>
XWikiGuest 13.1 133 /* --- Configuration --- */
134 var LDSF = {
135 linkding: 'https://bookmarks.rhebergen.org/api/bookmarks/',
136 token: '3b7443e0f84e2b2b269adebb96d7475e4a5e653e',
137 tag: 'Nuclear-&-Energy',
138 count: 20,
139 share: 'eT2X9ttBHK5GoEY',
140 webdav: 'https://cloud.rhebergen.org/public.php/webdav/'
141 };
142 LDSF.auth = 'Basic ' + btoa(LDSF.share + ':');
143
144 /* --- State --- */
XWikiGuest 6.1 145 var ldsf_urlToFile = {};
XWikiGuest 13.1 146 var ldsf_fileMap = {};
XWikiGuest 1.1 147
XWikiGuest 13.1 148 /* --- URL matching (exact, with/without slash, without query string) --- */
149 function ldsfMatch(url) {
150 var tries = [url, url.replace(/\/$/, ''), url + '/', url.replace(/\?.*$/, '')];
151 for (var i = 0; i < tries.length; i++) {
152 if (ldsf_urlToFile[tries[i]]) return ldsf_urlToFile[tries[i]];
153 }
XWikiGuest 6.1 154 return null;
155 }
XWikiGuest 1.1 156
XWikiGuest 13.1 157 /* --- Show archived page in viewer --- */
158 function ldsfShow(filename) {
XWikiGuest 6.1 159 document.getElementById('ldsf-viewer-title').textContent = filename.replace(/\.html?$/i, '');
XWikiGuest 12.1 160 document.getElementById('ldsf-viewer-bar').style.display = 'flex';
161 document.getElementById('ldsf-placeholder').style.display = 'none';
XWikiGuest 6.1 162 var frame = document.getElementById('ldsf-viewer-frame');
XWikiGuest 12.1 163 frame.style.display = 'block';
XWikiGuest 13.1 164 frame.srcdoc = '<p style="padding:20px;color:#888">Laden...</p>';
165 fetch(LDSF.webdav + encodeURIComponent(filename), { headers: { 'Authorization': LDSF.auth } })
166 .then(function(r) { return r.text(); })
167 .then(function(html) { frame.srcdoc = html; })
168 .catch(function(e) { frame.srcdoc = '<p style="padding:20px;color:#d9534f">Fout: ' + e.message + '</p>'; });
XWikiGuest 6.1 169 }
XWikiGuest 2.1 170
XWikiGuest 13.1 171 /* --- Close viewer --- */
172 function ldsfClose() {
XWikiGuest 12.1 173 document.getElementById('ldsf-viewer-bar').style.display = 'none';
174 document.getElementById('ldsf-viewer-frame').style.display = 'none';
175 document.getElementById('ldsf-placeholder').style.display = 'flex';
XWikiGuest 6.1 176 }
177
XWikiGuest 13.1 178 /* --- Render bookmark list --- */
179 function ldsfRender(data) {
180 var total = data.count || 0, archived = 0;
181 var container = document.getElementById('ldsf-bookmarks');
182 var html = '<ul>';
183 (data.results || []).forEach(function(bm, i) {
184 var title = bm.title || bm.website_title || bm.url;
185 var file = ldsfMatch(bm.url);
186 if (file) { archived++; ldsf_fileMap[i] = file; }
187 html += '<li>';
188 if (file) html += '<span class="sf-btn" data-sf="' + i + '" title="Archief bekijken">&#128196;</span>';
189 html += '<a href="' + bm.url + '" target="_blank">' + title + '</a></li>';
190 });
191 container.innerHTML = html + '</ul>';
192 document.getElementById('ldsf-status').textContent = total + ' bookmarks, ' + archived + ' met archief';
XWikiGuest 6.1 193 }
XWikiGuest 1.1 194
XWikiGuest 13.1 195 /* --- Click handler (event delegation, works in XWiki html macro) --- */
XWikiGuest 11.1 196 document.addEventListener('click', function(e) {
XWikiGuest 13.1 197 var t = e.target;
198 if (!t || !t.getAttribute) return;
199 var sf = t.getAttribute('data-sf');
200 if (sf !== null && ldsf_fileMap[sf]) ldsfShow(ldsf_fileMap[sf]);
201 if (t.getAttribute('data-sfclose') !== null) ldsfClose();
XWikiGuest 11.1 202 }, true);
203
XWikiGuest 13.1 204 /* --- Draggable divider --- */
205 var ldsf_drag = false;
206 document.getElementById('ldsf-divider').addEventListener('mousedown', function(e) {
207 ldsf_drag = true;
208 this.classList.add('dragging');
XWikiGuest 12.1 209 e.preventDefault();
XWikiGuest 8.1 210 });
XWikiGuest 12.1 211 document.addEventListener('mousemove', function(e) {
XWikiGuest 13.1 212 if (!ldsf_drag) return;
213 var box = document.getElementById('ldsf-container').getBoundingClientRect();
214 var w = e.clientX - box.left;
215 if (w >= 200 && w <= box.width * 0.6)
216 document.getElementById('ldsf-left').style.width = w + 'px';
XWikiGuest 12.1 217 });
218 document.addEventListener('mouseup', function() {
XWikiGuest 13.1 219 if (ldsf_drag) {
220 ldsf_drag = false;
221 document.getElementById('ldsf-divider').classList.remove('dragging');
222 }
XWikiGuest 12.1 223 });
XWikiGuest 8.1 224
XWikiGuest 13.1 225 /* --- Load index, then bookmarks --- */
226 fetch(LDSF.webdav + 'index.json', { headers: { 'Authorization': LDSF.auth } })
227 .then(function(r) { return r.ok ? r.json() : {}; })
228 .then(function(idx) {
229 for (var f in idx) { if (idx.hasOwnProperty(f)) ldsf_urlToFile[idx[f]] = f; }
230 })
231 .catch(function() {})
232 .then(function() {
233 return fetch(LDSF.linkding + '?limit=' + LDSF.count + '&q=%23' + encodeURIComponent(LDSF.tag),
234 { headers: { 'Authorization': 'Token ' + LDSF.token } });
235 })
236 .then(function(r) { return r.json(); })
237 .then(ldsfRender)
238 .catch(function(e) {
239 document.getElementById('ldsf-status').textContent = 'Fout: ' + e.message;
240 });
XWikiGuest 1.1 241 </script>
242 {{/html}}
243