vimd 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
var STORAGE_KEY_SIDEBAR_WIDTH = 'vimd-sidebar-width';
|
|
10
10
|
var STORAGE_KEY_STATE = 'vimd-folder-mode-state';
|
|
11
11
|
|
|
12
|
+
// Supported file extensions for link navigation
|
|
13
|
+
var SUPPORTED_EXTENSIONS = ['.md', '.tex', '.latex'];
|
|
14
|
+
|
|
12
15
|
// State
|
|
13
16
|
var fileTree = [];
|
|
14
17
|
var ws = null;
|
|
@@ -274,6 +277,95 @@
|
|
|
274
277
|
return search(fileTree);
|
|
275
278
|
}
|
|
276
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Get file extension from path
|
|
282
|
+
*/
|
|
283
|
+
function getExtension(path) {
|
|
284
|
+
// Remove query string and hash
|
|
285
|
+
var cleanPath = path.split('?')[0].split('#')[0];
|
|
286
|
+
var lastDot = cleanPath.lastIndexOf('.');
|
|
287
|
+
if (lastDot === -1) {
|
|
288
|
+
return '';
|
|
289
|
+
}
|
|
290
|
+
return cleanPath.substring(lastDot).toLowerCase();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Check if href is an internal link to a supported file
|
|
295
|
+
*/
|
|
296
|
+
function isInternalLink(href) {
|
|
297
|
+
// Ignore external links (http://, https://, //, mailto:, etc.)
|
|
298
|
+
if (/^(https?:)?\/\/|^mailto:|^tel:|^javascript:/i.test(href)) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Ignore anchor links
|
|
303
|
+
if (href.startsWith('#')) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Check if it's a supported file extension
|
|
308
|
+
var ext = getExtension(href);
|
|
309
|
+
return SUPPORTED_EXTENSIONS.indexOf(ext) !== -1;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Resolve relative path
|
|
314
|
+
*/
|
|
315
|
+
function resolvePath(basePath, relativePath) {
|
|
316
|
+
// Handle absolute paths (starting with /)
|
|
317
|
+
if (relativePath.startsWith('/')) {
|
|
318
|
+
return relativePath.substring(1);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Combine base and relative
|
|
322
|
+
var combined = basePath + relativePath;
|
|
323
|
+
|
|
324
|
+
// Normalize path (handle ../ and ./)
|
|
325
|
+
var parts = combined.split('/');
|
|
326
|
+
var result = [];
|
|
327
|
+
|
|
328
|
+
for (var i = 0; i < parts.length; i++) {
|
|
329
|
+
var part = parts[i];
|
|
330
|
+
if (part === '..') {
|
|
331
|
+
result.pop();
|
|
332
|
+
} else if (part !== '.' && part !== '') {
|
|
333
|
+
result.push(part);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return result.join('/');
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Handle internal link click
|
|
342
|
+
*/
|
|
343
|
+
function handleInternalLink(href) {
|
|
344
|
+
// Get current file's directory
|
|
345
|
+
var currentFile = state.panels[state.activePanel].file;
|
|
346
|
+
var currentDir = '';
|
|
347
|
+
|
|
348
|
+
if (currentFile) {
|
|
349
|
+
var lastSlash = currentFile.lastIndexOf('/');
|
|
350
|
+
if (lastSlash !== -1) {
|
|
351
|
+
currentDir = currentFile.substring(0, lastSlash + 1);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Resolve relative path
|
|
356
|
+
var targetPath = resolvePath(currentDir, href);
|
|
357
|
+
|
|
358
|
+
// Remove query string and hash for file selection
|
|
359
|
+
targetPath = targetPath.split('?')[0].split('#')[0];
|
|
360
|
+
|
|
361
|
+
// Check if file exists in tree
|
|
362
|
+
if (fileExists(targetPath)) {
|
|
363
|
+
selectFile(targetPath);
|
|
364
|
+
} else {
|
|
365
|
+
console.warn('[vimd] File not found:', targetPath);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
277
369
|
/**
|
|
278
370
|
* Handle file deleted event
|
|
279
371
|
*/
|
|
@@ -714,6 +806,24 @@
|
|
|
714
806
|
}
|
|
715
807
|
}
|
|
716
808
|
});
|
|
809
|
+
|
|
810
|
+
// Preview content link handler (event delegation)
|
|
811
|
+
preview.addEventListener('click', function(e) {
|
|
812
|
+
var target = e.target;
|
|
813
|
+
|
|
814
|
+
// Find closest anchor element
|
|
815
|
+
while (target && target !== preview) {
|
|
816
|
+
if (target.tagName === 'A') {
|
|
817
|
+
var href = target.getAttribute('href');
|
|
818
|
+
if (href && isInternalLink(href)) {
|
|
819
|
+
e.preventDefault();
|
|
820
|
+
handleInternalLink(href);
|
|
821
|
+
}
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
target = target.parentElement;
|
|
825
|
+
}
|
|
826
|
+
});
|
|
717
827
|
}
|
|
718
828
|
|
|
719
829
|
/**
|