mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-06-19 09:35:42 +02:00
168 lines
5.3 KiB
TypeScript
168 lines
5.3 KiB
TypeScript
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
|
|
import { PanelProvider } from './../panelWebView/PanelProvider';
|
|
import { Uri, window } from 'vscode';
|
|
import { dirname, extname, join } from 'path';
|
|
import { Field } from '../models';
|
|
import { existsSync } from 'fs';
|
|
import { Folders } from '../commands/Folders';
|
|
import { parseWinPath } from './parseWinPath';
|
|
import { Preview } from '../commands';
|
|
import { ArticleHelper } from './ArticleHelper';
|
|
|
|
export class ImageHelper {
|
|
/**
|
|
* Parse all images to use absolute paths
|
|
* @param field
|
|
* @param value
|
|
* @returns
|
|
*/
|
|
public static allRelToAbs(field: Field, value: string | string[] | undefined) {
|
|
let filePath =
|
|
window.activeTextEditor?.document.uri.fsPath ||
|
|
Preview.filePath ||
|
|
ArticleHelper.getActiveFile();
|
|
if (!filePath) {
|
|
return;
|
|
}
|
|
|
|
let previewUri = null;
|
|
|
|
if (field.multiple) {
|
|
if (Array.isArray(value)) {
|
|
previewUri = value.map((v) => ({
|
|
original: v,
|
|
absPath: v.startsWith('http') ? v : ImageHelper.relToAbs(filePath as string, v)
|
|
}));
|
|
}
|
|
} else {
|
|
if (typeof value === 'string') {
|
|
return {
|
|
original: value,
|
|
absPath: value.startsWith('http') ? value : ImageHelper.relToAbs(filePath, value)
|
|
};
|
|
}
|
|
}
|
|
|
|
return previewUri;
|
|
}
|
|
|
|
/**
|
|
* Parse relative path to absolute path
|
|
* @param filePath
|
|
* @param value
|
|
* @returns
|
|
*/
|
|
public static relToAbs(filePath: string, value: string) {
|
|
const wsFolder = Folders.getWorkspaceFolder();
|
|
let staticFolder = Folders.getStaticFolderRelativePath();
|
|
|
|
if (staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
|
|
const editor = window.activeTextEditor;
|
|
if (editor) {
|
|
const document = editor.document;
|
|
const filePath = parseWinPath(document.fileName);
|
|
const pathWithoutExtension = filePath.replace(extname(filePath), '');
|
|
const assetFilePath = join(pathWithoutExtension, value);
|
|
|
|
if (existsSync(assetFilePath)) {
|
|
return Uri.file(assetFilePath);
|
|
}
|
|
}
|
|
}
|
|
|
|
const staticPath = join(parseWinPath(wsFolder?.fsPath || ''), staticFolder || '', value);
|
|
const contentFolderPath = filePath ? join(dirname(filePath), value) : null;
|
|
const workspaceFolderPath = wsFolder ? join(wsFolder.fsPath, value) : null;
|
|
|
|
if (existsSync(staticPath)) {
|
|
return Uri.file(staticPath);
|
|
} else if (contentFolderPath && existsSync(contentFolderPath)) {
|
|
return Uri.file(contentFolderPath);
|
|
} else if (workspaceFolderPath && existsSync(workspaceFolderPath)) {
|
|
return Uri.file(workspaceFolderPath);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Parse absolute path to relative path
|
|
* @param imgValue
|
|
* @returns
|
|
*/
|
|
public static absToRel(imgValue: string) {
|
|
const wsFolder = Folders.getWorkspaceFolder();
|
|
const staticFolder = Folders.getStaticFolderRelativePath();
|
|
|
|
let relPath = imgValue || '';
|
|
if (imgValue) {
|
|
relPath = imgValue.split(parseWinPath(wsFolder?.fsPath || '')).pop() || '';
|
|
relPath = imgValue.split(staticFolder || '').pop() || '';
|
|
}
|
|
return relPath;
|
|
}
|
|
|
|
/**
|
|
* Process the image fields in the content type
|
|
* @param updatedMetadata
|
|
* @param fields
|
|
* @param parents
|
|
*/
|
|
public static processImageFields(updatedMetadata: any, fields: Field[], parents: string[] = []) {
|
|
const imageFields = fields.filter((field) => field.type === 'image');
|
|
const panel = PanelProvider.getInstance();
|
|
|
|
// Support multi-level fields
|
|
let parentObj = updatedMetadata;
|
|
for (const parent of parents || []) {
|
|
parentObj = parentObj[parent];
|
|
}
|
|
|
|
// Process image fields
|
|
if (parentObj) {
|
|
for (const field of imageFields) {
|
|
if (parentObj[field.name]) {
|
|
const imageData = ImageHelper.allRelToAbs(field, parentObj[field.name]);
|
|
|
|
if (imageData) {
|
|
if (field.multiple && imageData instanceof Array) {
|
|
const preview = imageData.map((preview) =>
|
|
preview && preview.absPath
|
|
? {
|
|
...preview,
|
|
webviewUrl:
|
|
typeof preview.absPath === 'string'
|
|
? preview.absPath
|
|
: panel.getWebview()?.asWebviewUri(preview.absPath).toString()
|
|
}
|
|
: null
|
|
);
|
|
|
|
parentObj[field.name] = preview || [];
|
|
} else if (!field.multiple && !Array.isArray(imageData) && imageData.absPath) {
|
|
const preview =
|
|
typeof imageData.absPath === 'string'
|
|
? imageData.absPath
|
|
: panel.getWebview()?.asWebviewUri(imageData.absPath);
|
|
parentObj[field.name] = {
|
|
...imageData,
|
|
webviewUrl: preview ? preview.toString() : null
|
|
};
|
|
}
|
|
} else {
|
|
parentObj[field.name] = field.multiple ? [] : '';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if there are sub-fields to process
|
|
const subFields = fields.filter((field) => field.type === 'fields');
|
|
if (subFields?.length > 0) {
|
|
for (const field of subFields) {
|
|
this.processImageFields(updatedMetadata, field.fields || [], [...parents, field.name]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|