kopia lustrzana https://github.com/mifi/lossless-cut
move to pathToFileURL
rodzic
1206ecbdb5
commit
e9bf49c319
|
@ -39,6 +39,8 @@ export * as configStore from './configStore.js';
|
||||||
|
|
||||||
export { isLinux, isWindows, isMac, platform } from './util.js';
|
export { isLinux, isWindows, isMac, platform } from './util.js';
|
||||||
|
|
||||||
|
export { pathToFileURL } from 'node:url';
|
||||||
|
|
||||||
|
|
||||||
// https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz
|
// https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz
|
||||||
// todo This should not be necessary anymore since v23.0.0
|
// todo This should not be necessary anymore since v23.0.0
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
|
import { test, expect, describe } from 'vitest';
|
||||||
|
|
||||||
|
import { pathToFileURL } from 'node:url';
|
||||||
|
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
describe('file uri windows only', () => {
|
||||||
|
test('converts path to file url', () => {
|
||||||
|
expect(pathToFileURL('C:\\Users\\sindresorhus\\dev\\te^st.jpg').href).toEqual('file:///C:/Users/sindresorhus/dev/te^st.jpg');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
describe('file uri non-windows', () => {
|
||||||
|
// https://github.com/mifi/lossless-cut/issues/1941
|
||||||
|
test('file with backslash', () => {
|
||||||
|
expect(pathToFileURL('/has/back\\slash').href).toEqual('file:///has/back%5Cslash');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from https://github.com/sindresorhus/file-url
|
||||||
|
describe('file uri both platforms', () => {
|
||||||
|
test('converts path to file url', () => {
|
||||||
|
expect(pathToFileURL('/test.jpg').href).toMatch(/file:\/{3}test\.jpg/);
|
||||||
|
|
||||||
|
expect(pathToFileURL('/Users/sindresorhus/dev/te^st.jpg').href).toEqual('file:///Users/sindresorhus/dev/te^st.jpg');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('escapes more special characters in path', () => {
|
||||||
|
expect(pathToFileURL('/a^?!@#$%&\'";<>').href).toEqual('file:///a^%3F!@%23$%25&\'%22;%3C%3E');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('escapes whitespace characters in path', () => {
|
||||||
|
expect(pathToFileURL('/file with\r\nnewline').href).toEqual('file:///file%20with%0D%0Anewline');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('relative path', () => {
|
||||||
|
expect(pathToFileURL('relative/test.jpg').href).toMatch(/^file:\/{3}.*\/relative\/test\.jpg$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('slash', () => {
|
||||||
|
expect(pathToFileURL('/').href).toEqual('file:///');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('empty', () => {
|
||||||
|
expect(pathToFileURL('').href).toMatch(/^file:\/{3}.*$/);
|
||||||
|
});
|
||||||
|
});
|
|
@ -70,7 +70,7 @@ import {
|
||||||
isStoreBuild, dragPreventer,
|
isStoreBuild, dragPreventer,
|
||||||
havePermissionToReadFile, resolvePathIfNeeded, getPathReadAccessError, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
|
havePermissionToReadFile, resolvePathIfNeeded, getPathReadAccessError, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
|
||||||
deleteFiles, isOutOfSpaceError, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle, getOutFileExtension, getSuffixedFileName, mustDisallowVob, readVideoTs, readDirRecursively, getImportProjectType,
|
deleteFiles, isOutOfSpaceError, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle, getOutFileExtension, getSuffixedFileName, mustDisallowVob, readVideoTs, readDirRecursively, getImportProjectType,
|
||||||
calcShouldShowWaveform, calcShouldShowKeyframes, mediaSourceQualities, isWindows,
|
calcShouldShowWaveform, calcShouldShowKeyframes, mediaSourceQualities,
|
||||||
} from './util';
|
} from './util';
|
||||||
import { toast, errorToast } from './swal';
|
import { toast, errorToast } from './swal';
|
||||||
import { formatDuration } from './util/duration';
|
import { formatDuration } from './util/duration';
|
||||||
|
@ -89,14 +89,13 @@ import isDev from './isDev';
|
||||||
import { ChromiumHTMLVideoElement, EdlFileType, FfmpegCommandLog, FormatTimecode, PlaybackMode, SegmentColorIndex, SegmentTags, SegmentToExport, StateSegment, Thumbnail, TunerType } from './types';
|
import { ChromiumHTMLVideoElement, EdlFileType, FfmpegCommandLog, FormatTimecode, PlaybackMode, SegmentColorIndex, SegmentTags, SegmentToExport, StateSegment, Thumbnail, TunerType } from './types';
|
||||||
import { CaptureFormat, KeyboardAction, Html5ifyMode } from '../../../types';
|
import { CaptureFormat, KeyboardAction, Html5ifyMode } from '../../../types';
|
||||||
import { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../../ffprobe';
|
import { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../../ffprobe';
|
||||||
import filePathToUrl from './util/fileUri';
|
|
||||||
|
|
||||||
const electron = window.require('electron');
|
const electron = window.require('electron');
|
||||||
const { exists } = window.require('fs-extra');
|
const { exists } = window.require('fs-extra');
|
||||||
const { lstat } = window.require('fs/promises');
|
const { lstat } = window.require('fs/promises');
|
||||||
const { parse: parsePath, join: pathJoin, basename, dirname } = window.require('path');
|
const { parse: parsePath, join: pathJoin, basename, dirname } = window.require('path');
|
||||||
|
|
||||||
const { focusWindow, hasDisabledNetworking, quitApp } = window.require('@electron/remote').require('./index.js');
|
const { focusWindow, hasDisabledNetworking, quitApp, pathToFileURL } = window.require('@electron/remote').require('./index.js');
|
||||||
|
|
||||||
|
|
||||||
const videoStyle: CSSProperties = { width: '100%', height: '100%', objectFit: 'contain' };
|
const videoStyle: CSSProperties = { width: '100%', height: '100%', objectFit: 'contain' };
|
||||||
|
@ -449,7 +448,7 @@ function App() {
|
||||||
const effectiveFilePath = previewFilePath || filePath;
|
const effectiveFilePath = previewFilePath || filePath;
|
||||||
const fileUri = useMemo(() => {
|
const fileUri = useMemo(() => {
|
||||||
if (!effectiveFilePath) return ''; // Setting video src="" prevents memory leak in chromium
|
if (!effectiveFilePath) return ''; // Setting video src="" prevents memory leak in chromium
|
||||||
const uri = filePathToUrl(effectiveFilePath, isWindows);
|
const uri = pathToFileURL(effectiveFilePath).href;
|
||||||
// https://github.com/mifi/lossless-cut/issues/1674
|
// https://github.com/mifi/lossless-cut/issues/1674
|
||||||
if (cacheBuster !== 0) {
|
if (cacheBuster !== 0) {
|
||||||
const qs = new URLSearchParams();
|
const qs = new URLSearchParams();
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { test, expect, describe } from 'vitest';
|
|
||||||
|
|
||||||
import fileUriRaw from './fileUri.js';
|
|
||||||
|
|
||||||
|
|
||||||
describe('file uri windows only', () => {
|
|
||||||
test('converts path to file url', () => {
|
|
||||||
expect(fileUriRaw('C:\\Users\\sindresorhus\\dev\\te^st.jpg', true)).toEqual('file:///C:/Users/sindresorhus/dev/te%5Est.jpg');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('file uri non-windows', () => {
|
|
||||||
// https://github.com/mifi/lossless-cut/issues/1941
|
|
||||||
test('file with backslash', () => {
|
|
||||||
expect(fileUriRaw('/has/back\\slash', false)).toEqual('file:///has/back%5Cslash');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// taken from https://github.com/sindresorhus/file-url
|
|
||||||
describe.each([{ isWindows: false }, { isWindows: true }])('file uri both platforms isWindows=$isWindows', ({ isWindows }) => {
|
|
||||||
const fileUri = (path) => fileUriRaw(path, isWindows);
|
|
||||||
|
|
||||||
test('converts path to file url', () => {
|
|
||||||
expect(fileUri('/test.jpg')).toMatch(/file:\/{3}test\.jpg/);
|
|
||||||
|
|
||||||
expect(fileUri('/Users/sindresorhus/dev/te^st.jpg')).toEqual('file:///Users/sindresorhus/dev/te%5Est.jpg');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('escapes more special characters in path', () => {
|
|
||||||
expect(fileUri('/a?!@#$%^&\'";<>')).toEqual('file:///a%3F!@%23$%25%5E&\'%22;%3C%3E');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('escapes whitespace characters in path', () => {
|
|
||||||
expect(fileUri('/file with\r\nnewline')).toEqual('file:///file%20with%0D%0Anewline');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('relative path', () => {
|
|
||||||
expect(fileUri('relative/test.jpg')).toEqual('file:///relative/test.jpg');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('empty', () => {
|
|
||||||
expect(fileUri('')).toEqual('file:///');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('slash', () => {
|
|
||||||
expect(fileUri('/')).toEqual('file:///');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,17 +0,0 @@
|
||||||
export default function fileUri(filePath: string, isWindows: boolean) {
|
|
||||||
let pathName = filePath;
|
|
||||||
|
|
||||||
if (isWindows) {
|
|
||||||
pathName = pathName.replaceAll('\\', '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windows drive letter must be prefixed with a slash.
|
|
||||||
// also relative paths will be converted to absolute
|
|
||||||
if (pathName[0] !== '/') {
|
|
||||||
pathName = `/${pathName}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape required characters for path components.
|
|
||||||
// See: https://tools.ietf.org/html/rfc3986#section-3.3
|
|
||||||
return encodeURI(`file://${pathName}`).replaceAll(/[#?]/g, encodeURIComponent);
|
|
||||||
}
|
|
Ładowanie…
Reference in New Issue