tiny-essentials 1.12.0 → 1.12.2
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.
- package/dist/legacy/firebase/index.mjs +5 -5
- package/dist/v1/TinyBasicsEs.js +1 -1257
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDragger.js +148 -43
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyEssentials.js +484 -189
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyUploadClicker.js +478 -190
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/basics/index.cjs +0 -23
- package/dist/v1/basics/index.d.mts +1 -23
- package/dist/v1/basics/index.mjs +1 -2
- package/dist/v1/fileManager/asyncFuncs.cjs +272 -0
- package/dist/v1/fileManager/asyncFuncs.d.mts +93 -0
- package/dist/v1/fileManager/asyncFuncs.mjs +236 -0
- package/dist/v1/fileManager/index.cjs +35 -0
- package/dist/v1/fileManager/index.d.mts +30 -0
- package/dist/v1/fileManager/index.mjs +3 -0
- package/dist/v1/{basics/fileManager.cjs → fileManager/normalFuncs.cjs} +10 -105
- package/dist/v1/{basics/fileManager.d.mts → fileManager/normalFuncs.d.mts} +3 -56
- package/dist/v1/{basics/fileManager.mjs → fileManager/normalFuncs.mjs} +48 -131
- package/dist/v1/index.cjs +30 -23
- package/dist/v1/index.d.mts +29 -23
- package/dist/v1/index.mjs +3 -2
- package/dist/v1/libs/TinyDragger.cjs +148 -43
- package/dist/v1/libs/TinyDragger.d.mts +18 -2
- package/dist/v1/libs/TinyDragger.mjs +132 -38
- package/dist/v1/libs/TinyUploadClicker.cjs +1 -0
- package/docs/v1/README.md +3 -1
- package/docs/v1/{basics/fileManager.md → fileManager/main.md} +12 -0
- package/docs/v1/libs/TinyDragger.md +15 -0
- package/package.json +5 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/******/ (() => { // webpackBootstrap
|
|
2
2
|
/******/ var __webpack_modules__ = ({
|
|
3
3
|
|
|
4
|
-
/***/
|
|
4
|
+
/***/ 133:
|
|
5
5
|
/***/ (() => {
|
|
6
6
|
|
|
7
7
|
/* (ignored) */
|
|
@@ -1924,6 +1924,13 @@ var hexSliceLookupTable = (function () {
|
|
|
1924
1924
|
})()
|
|
1925
1925
|
|
|
1926
1926
|
|
|
1927
|
+
/***/ }),
|
|
1928
|
+
|
|
1929
|
+
/***/ 370:
|
|
1930
|
+
/***/ (() => {
|
|
1931
|
+
|
|
1932
|
+
/* (ignored) */
|
|
1933
|
+
|
|
1927
1934
|
/***/ }),
|
|
1928
1935
|
|
|
1929
1936
|
/***/ 526:
|
|
@@ -2893,18 +2900,21 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
2893
2900
|
backupFile: () => (/* reexport */ backupFile),
|
|
2894
2901
|
checkObj: () => (/* reexport */ checkObj),
|
|
2895
2902
|
clearDirectory: () => (/* reexport */ clearDirectory),
|
|
2903
|
+
clearDirectoryAsync: () => (/* reexport */ clearDirectoryAsync),
|
|
2896
2904
|
cloneObjTypeOrder: () => (/* reexport */ cloneObjTypeOrder),
|
|
2897
2905
|
countObj: () => (/* reexport */ countObj),
|
|
2898
2906
|
dirExists: () => (/* reexport */ dirExists),
|
|
2899
2907
|
dirSize: () => (/* reexport */ dirSize),
|
|
2908
|
+
dirSizeAsync: () => (/* reexport */ dirSizeAsync),
|
|
2900
2909
|
documentIsFullScreen: () => (/* reexport */ documentIsFullScreen),
|
|
2901
2910
|
ensureCopyFile: () => (/* reexport */ ensureCopyFile),
|
|
2902
|
-
ensureDirectory: () => (/* reexport */
|
|
2911
|
+
ensureDirectory: () => (/* reexport */ normalFuncs_ensureDirectory),
|
|
2903
2912
|
exitFullScreen: () => (/* reexport */ exitFullScreen),
|
|
2904
2913
|
extendObjType: () => (/* reexport */ extendObjType),
|
|
2905
2914
|
fetchJson: () => (/* reexport */ fetchJson),
|
|
2906
|
-
fileExists: () => (/* reexport */
|
|
2915
|
+
fileExists: () => (/* reexport */ normalFuncs_fileExists),
|
|
2907
2916
|
fileSize: () => (/* reexport */ fileSize),
|
|
2917
|
+
fileSizeAsync: () => (/* reexport */ fileSizeAsync),
|
|
2908
2918
|
formatBytes: () => (/* reexport */ formatBytes),
|
|
2909
2919
|
formatCustomTimer: () => (/* reexport */ formatCustomTimer),
|
|
2910
2920
|
formatDayTimer: () => (/* reexport */ formatDayTimer),
|
|
@@ -2914,15 +2924,18 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
2914
2924
|
getHtmlElBordersWidth: () => (/* reexport */ getHtmlElBordersWidth),
|
|
2915
2925
|
getHtmlElMargin: () => (/* reexport */ getHtmlElMargin),
|
|
2916
2926
|
getHtmlElPadding: () => (/* reexport */ getHtmlElPadding),
|
|
2917
|
-
getLatestBackupPath: () => (/* reexport */
|
|
2927
|
+
getLatestBackupPath: () => (/* reexport */ normalFuncs_getLatestBackupPath),
|
|
2918
2928
|
getSimplePerc: () => (/* reexport */ getSimplePerc),
|
|
2919
2929
|
getTimeDuration: () => (/* reexport */ getTimeDuration),
|
|
2920
2930
|
isDirEmpty: () => (/* reexport */ isDirEmpty),
|
|
2931
|
+
isDirEmptyAsync: () => (/* reexport */ isDirEmptyAsync),
|
|
2921
2932
|
isFullScreenMode: () => (/* reexport */ isFullScreenMode),
|
|
2922
2933
|
isJsonObject: () => (/* reexport */ isJsonObject),
|
|
2923
2934
|
isScreenFilled: () => (/* reexport */ isScreenFilled),
|
|
2924
2935
|
listDirs: () => (/* reexport */ listDirs),
|
|
2936
|
+
listDirsAsync: () => (/* reexport */ listDirsAsync),
|
|
2925
2937
|
listFiles: () => (/* reexport */ listFiles),
|
|
2938
|
+
listFilesAsync: () => (/* reexport */ listFilesAsync),
|
|
2926
2939
|
objType: () => (/* reexport */ objType),
|
|
2927
2940
|
offFullScreenChange: () => (/* reexport */ offFullScreenChange),
|
|
2928
2941
|
onFullScreenChange: () => (/* reexport */ onFullScreenChange),
|
|
@@ -6612,10 +6625,10 @@ class TinyDragDropDetector {
|
|
|
6612
6625
|
/* harmony default export */ const libs_TinyDragDropDetector = (TinyDragDropDetector);
|
|
6613
6626
|
|
|
6614
6627
|
// EXTERNAL MODULE: fs (ignored)
|
|
6615
|
-
var fs_ignored_ = __webpack_require__(
|
|
6628
|
+
var fs_ignored_ = __webpack_require__(133);
|
|
6616
6629
|
// EXTERNAL MODULE: ./node_modules/path-browserify/index.js
|
|
6617
6630
|
var path_browserify = __webpack_require__(975);
|
|
6618
|
-
;// ./src/v1/
|
|
6631
|
+
;// ./src/v1/fileManager/normalFuncs.mjs
|
|
6619
6632
|
|
|
6620
6633
|
|
|
6621
6634
|
|
|
@@ -6631,8 +6644,8 @@ var path_browserify = __webpack_require__(975);
|
|
|
6631
6644
|
* @returns {any}
|
|
6632
6645
|
*/
|
|
6633
6646
|
function readJsonFile(filePath) {
|
|
6634
|
-
if (!fs_ignored_.existsSync(filePath)) throw new Error(`File not found: ${filePath}`);
|
|
6635
|
-
const content = fs_ignored_.readFileSync(filePath, 'utf-8');
|
|
6647
|
+
if (!(0,fs_ignored_.existsSync)(filePath)) throw new Error(`File not found: ${filePath}`);
|
|
6648
|
+
const content = (0,fs_ignored_.readFileSync)(filePath, 'utf-8');
|
|
6636
6649
|
return JSON.parse(content);
|
|
6637
6650
|
}
|
|
6638
6651
|
|
|
@@ -6645,32 +6658,7 @@ function readJsonFile(filePath) {
|
|
|
6645
6658
|
*/
|
|
6646
6659
|
function writeJsonFile(filePath, data, spaces = 2) {
|
|
6647
6660
|
const json = JSON.stringify(data, null, spaces);
|
|
6648
|
-
fs_ignored_.writeFileSync(filePath, json, 'utf-8');
|
|
6649
|
-
}
|
|
6650
|
-
|
|
6651
|
-
/**
|
|
6652
|
-
* Reads and parses a JSON file.
|
|
6653
|
-
* Throws an error if the file content is not valid JSON.
|
|
6654
|
-
* @param {string} filePath
|
|
6655
|
-
* @returns {Promise<any>}
|
|
6656
|
-
*/
|
|
6657
|
-
async function readJsonFileAsync(filePath) {
|
|
6658
|
-
if (!fs.existsSync(filePath)) throw new Error(`File not found: ${filePath}`);
|
|
6659
|
-
const content = await fs.promises.readFile(filePath, 'utf-8');
|
|
6660
|
-
return JSON.parse(content);
|
|
6661
|
-
}
|
|
6662
|
-
|
|
6663
|
-
/**
|
|
6664
|
-
* Saves an object as JSON to a file.
|
|
6665
|
-
* Automatically creates the directory if it does not exist.
|
|
6666
|
-
* @param {string} filePath
|
|
6667
|
-
* @param {any} data
|
|
6668
|
-
* @param {number} [spaces=2]
|
|
6669
|
-
* @returns {Promise<void>}
|
|
6670
|
-
*/
|
|
6671
|
-
function writeJsonFileAsync(filePath, data, spaces = 2) {
|
|
6672
|
-
const json = JSON.stringify(data, null, spaces);
|
|
6673
|
-
return fs.promises.writeFile(filePath, json, 'utf-8');
|
|
6661
|
+
(0,fs_ignored_.writeFileSync)(filePath, json, 'utf-8');
|
|
6674
6662
|
}
|
|
6675
6663
|
|
|
6676
6664
|
/*========================*
|
|
@@ -6681,9 +6669,9 @@ function writeJsonFileAsync(filePath, data, spaces = 2) {
|
|
|
6681
6669
|
* Ensures that the directory exists, creating it recursively if needed.
|
|
6682
6670
|
* @param {string} dirPath
|
|
6683
6671
|
*/
|
|
6684
|
-
function
|
|
6685
|
-
if (!fs_ignored_.existsSync(dirPath)) {
|
|
6686
|
-
fs_ignored_.mkdirSync(dirPath, { recursive: true });
|
|
6672
|
+
function normalFuncs_ensureDirectory(dirPath) {
|
|
6673
|
+
if (!(0,fs_ignored_.existsSync)(dirPath)) {
|
|
6674
|
+
(0,fs_ignored_.mkdirSync)(dirPath, { recursive: true });
|
|
6687
6675
|
}
|
|
6688
6676
|
}
|
|
6689
6677
|
|
|
@@ -6692,15 +6680,15 @@ function ensureDirectory(dirPath) {
|
|
|
6692
6680
|
* @param {string} dirPath
|
|
6693
6681
|
*/
|
|
6694
6682
|
function clearDirectory(dirPath) {
|
|
6695
|
-
if (!fs_ignored_.existsSync(dirPath)) return;
|
|
6696
|
-
const files = fs_ignored_.readdirSync(dirPath);
|
|
6683
|
+
if (!(0,fs_ignored_.existsSync)(dirPath)) return;
|
|
6684
|
+
const files = (0,fs_ignored_.readdirSync)(dirPath);
|
|
6697
6685
|
for (const file of files) {
|
|
6698
|
-
const fullPath = path_browserify.join(dirPath, file);
|
|
6699
|
-
const
|
|
6700
|
-
if (
|
|
6701
|
-
fs_ignored_.rmSync(fullPath, { recursive: true, force: true });
|
|
6686
|
+
const fullPath = (0,path_browserify.join)(dirPath, file);
|
|
6687
|
+
const statData = (0,fs_ignored_.lstatSync)(fullPath);
|
|
6688
|
+
if (statData.isDirectory()) {
|
|
6689
|
+
(0,fs_ignored_.rmSync)(fullPath, { recursive: true, force: true });
|
|
6702
6690
|
} else {
|
|
6703
|
-
fs_ignored_.unlinkSync(fullPath);
|
|
6691
|
+
(0,fs_ignored_.unlinkSync)(fullPath);
|
|
6704
6692
|
}
|
|
6705
6693
|
}
|
|
6706
6694
|
}
|
|
@@ -6714,8 +6702,8 @@ function clearDirectory(dirPath) {
|
|
|
6714
6702
|
* @param {string} filePath
|
|
6715
6703
|
* @returns {boolean}
|
|
6716
6704
|
*/
|
|
6717
|
-
function
|
|
6718
|
-
return fs_ignored_.existsSync(filePath) && fs_ignored_.lstatSync(filePath).isFile();
|
|
6705
|
+
function normalFuncs_fileExists(filePath) {
|
|
6706
|
+
return (0,fs_ignored_.existsSync)(filePath) && (0,fs_ignored_.lstatSync)(filePath).isFile();
|
|
6719
6707
|
}
|
|
6720
6708
|
|
|
6721
6709
|
/**
|
|
@@ -6724,7 +6712,7 @@ function fileExists(filePath) {
|
|
|
6724
6712
|
* @returns {boolean}
|
|
6725
6713
|
*/
|
|
6726
6714
|
function dirExists(dirPath) {
|
|
6727
|
-
return fs_ignored_.existsSync(dirPath) && fs_ignored_.lstatSync(dirPath).isDirectory();
|
|
6715
|
+
return (0,fs_ignored_.existsSync)(dirPath) && (0,fs_ignored_.lstatSync)(dirPath).isDirectory();
|
|
6728
6716
|
}
|
|
6729
6717
|
|
|
6730
6718
|
/**
|
|
@@ -6733,7 +6721,7 @@ function dirExists(dirPath) {
|
|
|
6733
6721
|
* @returns {boolean}
|
|
6734
6722
|
*/
|
|
6735
6723
|
function isDirEmpty(dirPath) {
|
|
6736
|
-
return
|
|
6724
|
+
return (0,fs_ignored_.readdirSync)(dirPath).length === 0;
|
|
6737
6725
|
}
|
|
6738
6726
|
|
|
6739
6727
|
/*========================*
|
|
@@ -6747,8 +6735,8 @@ function isDirEmpty(dirPath) {
|
|
|
6747
6735
|
* @param {number} [mode]
|
|
6748
6736
|
*/
|
|
6749
6737
|
function ensureCopyFile(src, dest, mode) {
|
|
6750
|
-
|
|
6751
|
-
fs_ignored_.copyFileSync(src, dest, mode);
|
|
6738
|
+
normalFuncs_ensureDirectory((0,path_browserify.dirname)(dest));
|
|
6739
|
+
(0,fs_ignored_.copyFileSync)(src, dest, mode);
|
|
6752
6740
|
}
|
|
6753
6741
|
|
|
6754
6742
|
/**
|
|
@@ -6757,33 +6745,8 @@ function ensureCopyFile(src, dest, mode) {
|
|
|
6757
6745
|
* @returns {boolean}
|
|
6758
6746
|
*/
|
|
6759
6747
|
function tryDeleteFile(filePath) {
|
|
6760
|
-
if (
|
|
6761
|
-
fs_ignored_.unlinkSync(filePath);
|
|
6762
|
-
return true;
|
|
6763
|
-
}
|
|
6764
|
-
return false;
|
|
6765
|
-
}
|
|
6766
|
-
|
|
6767
|
-
/**
|
|
6768
|
-
* Copies a file to a destination.
|
|
6769
|
-
* @param {string} src
|
|
6770
|
-
* @param {string} dest
|
|
6771
|
-
* @param {number} [mode]
|
|
6772
|
-
* @returns {Promise<void>}
|
|
6773
|
-
*/
|
|
6774
|
-
function ensureCopyFileAsync(src, dest, mode) {
|
|
6775
|
-
ensureDirectory(path.dirname(dest));
|
|
6776
|
-
return fs.promises.copyFile(src, dest, mode);
|
|
6777
|
-
}
|
|
6778
|
-
|
|
6779
|
-
/**
|
|
6780
|
-
* Deletes a file (If the file exists).
|
|
6781
|
-
* @param {string} filePath
|
|
6782
|
-
* @returns {Promise<boolean>}
|
|
6783
|
-
*/
|
|
6784
|
-
async function tryDeleteFileAsync(filePath) {
|
|
6785
|
-
if (fileExists(filePath)) {
|
|
6786
|
-
await fs.promises.unlink(filePath);
|
|
6748
|
+
if (normalFuncs_fileExists(filePath)) {
|
|
6749
|
+
(0,fs_ignored_.unlinkSync)(filePath);
|
|
6787
6750
|
return true;
|
|
6788
6751
|
}
|
|
6789
6752
|
return false;
|
|
@@ -6797,25 +6760,12 @@ async function tryDeleteFileAsync(filePath) {
|
|
|
6797
6760
|
* Writes text to a file (Ensures that the directory exists, creating it recursively if needed).
|
|
6798
6761
|
* @param {string} filePath
|
|
6799
6762
|
* @param {string} content
|
|
6800
|
-
* @param {fs.WriteFileOptions} [ops='utf-8']
|
|
6763
|
+
* @param {import('fs').WriteFileOptions} [ops='utf-8']
|
|
6801
6764
|
*/
|
|
6802
6765
|
function writeTextFile(filePath, content, ops = 'utf-8') {
|
|
6803
|
-
const dir = path_browserify.dirname(filePath);
|
|
6804
|
-
|
|
6805
|
-
fs_ignored_.writeFileSync(filePath, content, ops);
|
|
6806
|
-
}
|
|
6807
|
-
|
|
6808
|
-
/**
|
|
6809
|
-
* Writes text to a file (Ensures that the directory exists, creating it recursively if needed).
|
|
6810
|
-
* @param {string} filePath
|
|
6811
|
-
* @param {string} content
|
|
6812
|
-
* @param {fs.WriteFileOptions} [ops='utf-8']
|
|
6813
|
-
* @returns {Promise<void>}
|
|
6814
|
-
*/
|
|
6815
|
-
function writeTextFileAsync(filePath, content, ops = 'utf-8') {
|
|
6816
|
-
const dir = path.dirname(filePath);
|
|
6817
|
-
ensureDirectory(dir);
|
|
6818
|
-
return fs.promises.writeFile(filePath, content, ops);
|
|
6766
|
+
const dir = (0,path_browserify.dirname)(filePath);
|
|
6767
|
+
normalFuncs_ensureDirectory(dir);
|
|
6768
|
+
(0,fs_ignored_.writeFileSync)(filePath, content, ops);
|
|
6819
6769
|
}
|
|
6820
6770
|
|
|
6821
6771
|
/*========================*
|
|
@@ -6833,11 +6783,11 @@ function listFiles(dirPath, recursive = false) {
|
|
|
6833
6783
|
const results = { files: [], dirs: [] };
|
|
6834
6784
|
if (!dirExists(dirPath)) return results;
|
|
6835
6785
|
|
|
6836
|
-
const entries = fs_ignored_.readdirSync(dirPath);
|
|
6786
|
+
const entries = (0,fs_ignored_.readdirSync)(dirPath);
|
|
6837
6787
|
for (const entry of entries) {
|
|
6838
|
-
const fullPath = path_browserify.join(dirPath, entry);
|
|
6839
|
-
const
|
|
6840
|
-
if (
|
|
6788
|
+
const fullPath = (0,path_browserify.join)(dirPath, entry);
|
|
6789
|
+
const statData = (0,fs_ignored_.lstatSync)(fullPath);
|
|
6790
|
+
if (statData.isDirectory()) {
|
|
6841
6791
|
results.dirs.push(fullPath);
|
|
6842
6792
|
if (recursive) {
|
|
6843
6793
|
const results2 = listFiles(fullPath, true);
|
|
@@ -6862,11 +6812,11 @@ function listDirs(dirPath, recursive = false) {
|
|
|
6862
6812
|
const results = [];
|
|
6863
6813
|
if (!dirExists(dirPath)) return results;
|
|
6864
6814
|
|
|
6865
|
-
const entries = fs_ignored_.readdirSync(dirPath);
|
|
6815
|
+
const entries = (0,fs_ignored_.readdirSync)(dirPath);
|
|
6866
6816
|
for (const entry of entries) {
|
|
6867
|
-
const fullPath = path_browserify.join(dirPath, entry);
|
|
6868
|
-
const
|
|
6869
|
-
if (
|
|
6817
|
+
const fullPath = (0,path_browserify.join)(dirPath, entry);
|
|
6818
|
+
const statData = (0,fs_ignored_.lstatSync)(fullPath);
|
|
6819
|
+
if (statData.isDirectory()) {
|
|
6870
6820
|
results.push(fullPath);
|
|
6871
6821
|
if (recursive) {
|
|
6872
6822
|
results.push(...listDirs(fullPath, true));
|
|
@@ -6886,8 +6836,8 @@ function listDirs(dirPath, recursive = false) {
|
|
|
6886
6836
|
* @returns {number}
|
|
6887
6837
|
*/
|
|
6888
6838
|
function fileSize(filePath) {
|
|
6889
|
-
if (!
|
|
6890
|
-
const stats = fs_ignored_.statSync(filePath);
|
|
6839
|
+
if (!normalFuncs_fileExists(filePath)) return 0;
|
|
6840
|
+
const stats = (0,fs_ignored_.statSync)(filePath);
|
|
6891
6841
|
return stats.size;
|
|
6892
6842
|
}
|
|
6893
6843
|
|
|
@@ -6915,7 +6865,7 @@ function dirSize(dirPath) {
|
|
|
6915
6865
|
* @param {string} [ext='bak']
|
|
6916
6866
|
*/
|
|
6917
6867
|
function backupFile(filePath, ext = 'bak') {
|
|
6918
|
-
if (!
|
|
6868
|
+
if (!normalFuncs_fileExists(filePath)) return;
|
|
6919
6869
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
6920
6870
|
const backupPath = `${filePath}.${ext}.${timestamp}`;
|
|
6921
6871
|
ensureCopyFile(filePath, backupPath);
|
|
@@ -6927,17 +6877,17 @@ function backupFile(filePath, ext = 'bak') {
|
|
|
6927
6877
|
* @param {string} [ext='bak']
|
|
6928
6878
|
* @returns {string} Full path to the most recent backup
|
|
6929
6879
|
*/
|
|
6930
|
-
function
|
|
6931
|
-
const dir = path_browserify.dirname(filePath);
|
|
6932
|
-
const baseName = path_browserify.basename(filePath);
|
|
6933
|
-
const backups = fs_ignored_.readdirSync(dir)
|
|
6880
|
+
function normalFuncs_getLatestBackupPath(filePath, ext = 'bak') {
|
|
6881
|
+
const dir = (0,path_browserify.dirname)(filePath);
|
|
6882
|
+
const baseName = (0,path_browserify.basename)(filePath);
|
|
6883
|
+
const backups = (0,fs_ignored_.readdirSync)(dir)
|
|
6934
6884
|
.filter((name) => name.startsWith(`${baseName}.${ext}.`))
|
|
6935
6885
|
.sort()
|
|
6936
6886
|
.reverse();
|
|
6937
6887
|
|
|
6938
6888
|
if (backups.length === 0) throw new Error(`No backups found for ${filePath}`);
|
|
6939
6889
|
|
|
6940
|
-
return path_browserify.join(dir, backups[0]);
|
|
6890
|
+
return (0,path_browserify.join)(dir, backups[0]);
|
|
6941
6891
|
}
|
|
6942
6892
|
|
|
6943
6893
|
/**
|
|
@@ -6946,34 +6896,10 @@ function getLatestBackupPath(filePath, ext = 'bak') {
|
|
|
6946
6896
|
* @param {string} [ext='bak']
|
|
6947
6897
|
*/
|
|
6948
6898
|
function restoreLatestBackup(filePath, ext = 'bak') {
|
|
6949
|
-
const latestBackup =
|
|
6899
|
+
const latestBackup = normalFuncs_getLatestBackupPath(filePath, ext);
|
|
6950
6900
|
ensureCopyFile(latestBackup, filePath);
|
|
6951
6901
|
}
|
|
6952
6902
|
|
|
6953
|
-
/**
|
|
6954
|
-
* Restores the most recent backup of a file.
|
|
6955
|
-
* @param {string} filePath
|
|
6956
|
-
* @param {string} [ext='bak']
|
|
6957
|
-
* @returns {Promise<void>}
|
|
6958
|
-
*/
|
|
6959
|
-
function restoreLatestBackupAsync(filePath, ext = 'bak') {
|
|
6960
|
-
const latestBackup = getLatestBackupPath(filePath, ext);
|
|
6961
|
-
return ensureCopyFileAsync(latestBackup, filePath);
|
|
6962
|
-
}
|
|
6963
|
-
|
|
6964
|
-
/**
|
|
6965
|
-
* Creates a backup copy of a file with .bak timestamp suffix.
|
|
6966
|
-
* @param {string} filePath
|
|
6967
|
-
* @param {string} [ext='bak']
|
|
6968
|
-
* @returns {Promise<void>}
|
|
6969
|
-
*/
|
|
6970
|
-
async function backupFileAsync(filePath, ext = 'bak') {
|
|
6971
|
-
if (!fileExists(filePath)) return;
|
|
6972
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
6973
|
-
const backupPath = `${filePath}.${ext}.${timestamp}`;
|
|
6974
|
-
return ensureCopyFileAsync(filePath, backupPath);
|
|
6975
|
-
}
|
|
6976
|
-
|
|
6977
6903
|
/*========================*
|
|
6978
6904
|
* Rename Utilities
|
|
6979
6905
|
*========================*/
|
|
@@ -6992,7 +6918,7 @@ function renameFileBatch(dirPath, renameFn, extensions = []) {
|
|
|
6992
6918
|
if (typeof dirPath !== 'string') throw new TypeError('dirPath must be a string');
|
|
6993
6919
|
if (typeof renameFn !== 'function') throw new TypeError('renameFn must be a function');
|
|
6994
6920
|
if (!Array.isArray(extensions)) throw new TypeError('extensions must be an array of strings');
|
|
6995
|
-
if (!fs_ignored_.existsSync(dirPath) || !fs_ignored_.statSync(dirPath).isDirectory())
|
|
6921
|
+
if (!(0,fs_ignored_.existsSync)(dirPath) || !(0,fs_ignored_.statSync)(dirPath).isDirectory())
|
|
6996
6922
|
throw new Error(`Directory not found or invalid: ${dirPath}`);
|
|
6997
6923
|
for (const ext of extensions) {
|
|
6998
6924
|
if (typeof ext !== 'string' || !ext.startsWith('.'))
|
|
@@ -7003,16 +6929,16 @@ function renameFileBatch(dirPath, renameFn, extensions = []) {
|
|
|
7003
6929
|
let index = 0;
|
|
7004
6930
|
|
|
7005
6931
|
for (const file of files) {
|
|
7006
|
-
const ext = path_browserify.extname(file);
|
|
6932
|
+
const ext = (0,path_browserify.extname)(file);
|
|
7007
6933
|
if (extensions.length && !extensions.includes(ext)) continue;
|
|
7008
6934
|
|
|
7009
|
-
const originalName = path_browserify.basename(file);
|
|
6935
|
+
const originalName = (0,path_browserify.basename)(file);
|
|
7010
6936
|
const newName = renameFn(originalName, index++);
|
|
7011
|
-
const newPath = path_browserify.join(dirPath, newName);
|
|
6937
|
+
const newPath = (0,path_browserify.join)(dirPath, newName);
|
|
7012
6938
|
|
|
7013
6939
|
if (originalName === newName) continue;
|
|
7014
6940
|
|
|
7015
|
-
fs_ignored_.renameSync(file, newPath);
|
|
6941
|
+
(0,fs_ignored_.renameSync)(file, newPath);
|
|
7016
6942
|
}
|
|
7017
6943
|
}
|
|
7018
6944
|
|
|
@@ -7027,8 +6953,8 @@ function renameFileRegex(dirPath, pattern, replacement, extensions = []) {
|
|
|
7027
6953
|
renameFileBatch(
|
|
7028
6954
|
dirPath,
|
|
7029
6955
|
(filename) => {
|
|
7030
|
-
const ext = path_browserify.extname(filename);
|
|
7031
|
-
const name = path_browserify.basename(filename, ext).replace(pattern, replacement);
|
|
6956
|
+
const ext = (0,path_browserify.extname)(filename);
|
|
6957
|
+
const name = (0,path_browserify.basename)(filename, ext).replace(pattern, replacement);
|
|
7032
6958
|
return `${name}${ext}`;
|
|
7033
6959
|
},
|
|
7034
6960
|
extensions,
|
|
@@ -7045,8 +6971,8 @@ function renameFileAddPrefixSuffix(dirPath, { prefix = '', suffix = '' }, extens
|
|
|
7045
6971
|
renameFileBatch(
|
|
7046
6972
|
dirPath,
|
|
7047
6973
|
(filename) => {
|
|
7048
|
-
const ext = path_browserify.extname(filename);
|
|
7049
|
-
const name = path_browserify.basename(filename, ext);
|
|
6974
|
+
const ext = (0,path_browserify.extname)(filename);
|
|
6975
|
+
const name = (0,path_browserify.basename)(filename, ext);
|
|
7050
6976
|
return `${prefix}${name}${suffix}${ext}`;
|
|
7051
6977
|
},
|
|
7052
6978
|
extensions,
|
|
@@ -7083,9 +7009,9 @@ function renameFileNormalizeCase(
|
|
|
7083
7009
|
else return text;
|
|
7084
7010
|
};
|
|
7085
7011
|
|
|
7086
|
-
const rawExt = path_browserify.extname(filename);
|
|
7012
|
+
const rawExt = (0,path_browserify.extname)(filename);
|
|
7087
7013
|
const ext = normalizeExt ? changeToMode(rawExt) : rawExt;
|
|
7088
|
-
const name = changeToMode(path_browserify.basename(filename, rawExt));
|
|
7014
|
+
const name = changeToMode((0,path_browserify.basename)(filename, rawExt));
|
|
7089
7015
|
return `${name}${ext}`;
|
|
7090
7016
|
},
|
|
7091
7017
|
extensions,
|
|
@@ -7108,6 +7034,266 @@ function renameFilePadNumbers(dirPath, totalDigits = 3, extensions = []) {
|
|
|
7108
7034
|
);
|
|
7109
7035
|
}
|
|
7110
7036
|
|
|
7037
|
+
// EXTERNAL MODULE: fs/promises (ignored)
|
|
7038
|
+
var promises_ignored_ = __webpack_require__(370);
|
|
7039
|
+
;// ./src/v1/fileManager/asyncFuncs.mjs
|
|
7040
|
+
|
|
7041
|
+
|
|
7042
|
+
|
|
7043
|
+
|
|
7044
|
+
|
|
7045
|
+
/*========================*
|
|
7046
|
+
* JSON Operations
|
|
7047
|
+
*========================*/
|
|
7048
|
+
|
|
7049
|
+
/**
|
|
7050
|
+
* Reads and parses a JSON file.
|
|
7051
|
+
* Throws an error if the file content is not valid JSON.
|
|
7052
|
+
* @param {string} filePath
|
|
7053
|
+
* @returns {Promise<any>}
|
|
7054
|
+
*/
|
|
7055
|
+
async function readJsonFileAsync(filePath) {
|
|
7056
|
+
if (!existsSync(filePath)) throw new Error(`File not found: ${filePath}`);
|
|
7057
|
+
const content = await readFile(filePath, 'utf-8');
|
|
7058
|
+
return JSON.parse(content);
|
|
7059
|
+
}
|
|
7060
|
+
|
|
7061
|
+
/**
|
|
7062
|
+
* Saves an object as JSON to a file.
|
|
7063
|
+
* Automatically creates the directory if it does not exist.
|
|
7064
|
+
* @param {string} filePath
|
|
7065
|
+
* @param {any} data
|
|
7066
|
+
* @param {number} [spaces=2]
|
|
7067
|
+
* @returns {Promise<void>}
|
|
7068
|
+
*/
|
|
7069
|
+
function writeJsonFileAsync(filePath, data, spaces = 2) {
|
|
7070
|
+
const json = JSON.stringify(data, null, spaces);
|
|
7071
|
+
return writeFile(filePath, json, 'utf-8');
|
|
7072
|
+
}
|
|
7073
|
+
|
|
7074
|
+
/*========================*
|
|
7075
|
+
* Directory Management
|
|
7076
|
+
*========================*/
|
|
7077
|
+
|
|
7078
|
+
/**
|
|
7079
|
+
* Clears all contents inside a directory but keeps the directory.
|
|
7080
|
+
* @param {string} dirPath
|
|
7081
|
+
*/
|
|
7082
|
+
async function clearDirectoryAsync(dirPath) {
|
|
7083
|
+
if (!(0,fs_ignored_.existsSync)(dirPath)) return;
|
|
7084
|
+
const files = await (0,promises_ignored_.readdir)(dirPath);
|
|
7085
|
+
|
|
7086
|
+
/** @type {Record<string, import('fs').Stats>} */
|
|
7087
|
+
const dataList = {};
|
|
7088
|
+
const promises = [];
|
|
7089
|
+
|
|
7090
|
+
for (const file of files) {
|
|
7091
|
+
const fullPath = (0,path_browserify.join)(dirPath, file);
|
|
7092
|
+
const lsResult = (0,promises_ignored_.lstat)(fullPath);
|
|
7093
|
+
|
|
7094
|
+
lsResult.then((statData) => {
|
|
7095
|
+
dataList[fullPath] = statData;
|
|
7096
|
+
return statData;
|
|
7097
|
+
});
|
|
7098
|
+
promises.push(lsResult);
|
|
7099
|
+
}
|
|
7100
|
+
|
|
7101
|
+
await Promise.all(promises);
|
|
7102
|
+
const promises2 = [];
|
|
7103
|
+
for (const fullPath in dataList) {
|
|
7104
|
+
const statData = dataList[fullPath];
|
|
7105
|
+
if (statData.isDirectory()) {
|
|
7106
|
+
promises2.push((0,promises_ignored_.rm)(fullPath, { recursive: true, force: true }));
|
|
7107
|
+
} else {
|
|
7108
|
+
promises2.push((0,promises_ignored_.unlink)(fullPath));
|
|
7109
|
+
}
|
|
7110
|
+
}
|
|
7111
|
+
|
|
7112
|
+
await Promise.all(promises2);
|
|
7113
|
+
}
|
|
7114
|
+
|
|
7115
|
+
/*========================*
|
|
7116
|
+
* File Checks
|
|
7117
|
+
*========================*/
|
|
7118
|
+
|
|
7119
|
+
/**
|
|
7120
|
+
* Checks whether a directory is empty.
|
|
7121
|
+
* @param {string} dirPath
|
|
7122
|
+
* @returns {Promise<boolean>}
|
|
7123
|
+
*/
|
|
7124
|
+
async function isDirEmptyAsync(dirPath) {
|
|
7125
|
+
const data = await (0,promises_ignored_.readdir)(dirPath);
|
|
7126
|
+
return data.length === 0;
|
|
7127
|
+
}
|
|
7128
|
+
|
|
7129
|
+
/*========================*
|
|
7130
|
+
* File Operations
|
|
7131
|
+
*========================*/
|
|
7132
|
+
|
|
7133
|
+
/**
|
|
7134
|
+
* Copies a file to a destination.
|
|
7135
|
+
* @param {string} src
|
|
7136
|
+
* @param {string} dest
|
|
7137
|
+
* @param {number} [mode]
|
|
7138
|
+
* @returns {Promise<void>}
|
|
7139
|
+
*/
|
|
7140
|
+
function ensureCopyFileAsync(src, dest, mode) {
|
|
7141
|
+
ensureDirectory(dirname(dest));
|
|
7142
|
+
return copyFile(src, dest, mode);
|
|
7143
|
+
}
|
|
7144
|
+
|
|
7145
|
+
/**
|
|
7146
|
+
* Deletes a file (If the file exists).
|
|
7147
|
+
* @param {string} filePath
|
|
7148
|
+
* @returns {Promise<boolean>}
|
|
7149
|
+
*/
|
|
7150
|
+
async function tryDeleteFileAsync(filePath) {
|
|
7151
|
+
if (fileExists(filePath)) {
|
|
7152
|
+
await unlink(filePath);
|
|
7153
|
+
return true;
|
|
7154
|
+
}
|
|
7155
|
+
return false;
|
|
7156
|
+
}
|
|
7157
|
+
|
|
7158
|
+
/*========================*
|
|
7159
|
+
* Text Operations
|
|
7160
|
+
*========================*/
|
|
7161
|
+
|
|
7162
|
+
/**
|
|
7163
|
+
* Writes text to a file (Ensures that the directory exists, creating it recursively if needed).
|
|
7164
|
+
* @param {string} filePath
|
|
7165
|
+
* @param {string} content
|
|
7166
|
+
* @param {import('fs').WriteFileOptions} [ops='utf-8']
|
|
7167
|
+
* @returns {Promise<void>}
|
|
7168
|
+
*/
|
|
7169
|
+
function writeTextFileAsync(filePath, content, ops = 'utf-8') {
|
|
7170
|
+
const dir = dirname(filePath);
|
|
7171
|
+
ensureDirectory(dir);
|
|
7172
|
+
return writeFile(filePath, content, ops);
|
|
7173
|
+
}
|
|
7174
|
+
|
|
7175
|
+
/*========================*
|
|
7176
|
+
* Directory Listings
|
|
7177
|
+
*========================*/
|
|
7178
|
+
|
|
7179
|
+
/**
|
|
7180
|
+
* Lists all files and dirs in a directory (optionally recursive).
|
|
7181
|
+
* @param {string} dirPath
|
|
7182
|
+
* @param {boolean} [recursive=false]
|
|
7183
|
+
* @returns {Promise<{ files: string[]; dirs: string[] }>}
|
|
7184
|
+
*/
|
|
7185
|
+
async function listFilesAsync(dirPath, recursive = false) {
|
|
7186
|
+
/** @type {{ files: string[]; dirs: string[] }} */
|
|
7187
|
+
const results = { files: [], dirs: [] };
|
|
7188
|
+
if (!dirExists(dirPath)) return results;
|
|
7189
|
+
|
|
7190
|
+
const entries = await (0,promises_ignored_.readdir)(dirPath);
|
|
7191
|
+
for (const entry of entries) {
|
|
7192
|
+
const fullPath = (0,path_browserify.join)(dirPath, entry);
|
|
7193
|
+
const statData = await (0,promises_ignored_.lstat)(fullPath);
|
|
7194
|
+
if (statData.isDirectory()) {
|
|
7195
|
+
results.dirs.push(fullPath);
|
|
7196
|
+
if (recursive) {
|
|
7197
|
+
const results2 = await listFilesAsync(fullPath, true);
|
|
7198
|
+
results.files.push(...results2.files);
|
|
7199
|
+
results.dirs.push(...results2.dirs);
|
|
7200
|
+
}
|
|
7201
|
+
} else {
|
|
7202
|
+
results.files.push(fullPath);
|
|
7203
|
+
}
|
|
7204
|
+
}
|
|
7205
|
+
return results;
|
|
7206
|
+
}
|
|
7207
|
+
|
|
7208
|
+
/**
|
|
7209
|
+
* Lists all directories in a directory (optionally recursive).
|
|
7210
|
+
* @param {string} dirPath
|
|
7211
|
+
* @param {boolean} [recursive=false]
|
|
7212
|
+
* @returns {Promise<string[]>}
|
|
7213
|
+
*/
|
|
7214
|
+
async function listDirsAsync(dirPath, recursive = false) {
|
|
7215
|
+
/** @type {string[]} */
|
|
7216
|
+
const results = [];
|
|
7217
|
+
if (!dirExists(dirPath)) return results;
|
|
7218
|
+
|
|
7219
|
+
const entries = await (0,promises_ignored_.readdir)(dirPath);
|
|
7220
|
+
for (const entry of entries) {
|
|
7221
|
+
const fullPath = (0,path_browserify.join)(dirPath, entry);
|
|
7222
|
+
const statData = await (0,promises_ignored_.lstat)(fullPath);
|
|
7223
|
+
if (statData.isDirectory()) {
|
|
7224
|
+
results.push(fullPath);
|
|
7225
|
+
if (recursive) {
|
|
7226
|
+
results.push(...(await listDirsAsync(fullPath, true)));
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
return results;
|
|
7231
|
+
}
|
|
7232
|
+
|
|
7233
|
+
/*========================*
|
|
7234
|
+
* File Info
|
|
7235
|
+
*========================*/
|
|
7236
|
+
|
|
7237
|
+
/**
|
|
7238
|
+
* Returns the size of a file in bytes.
|
|
7239
|
+
* @param {string} filePath
|
|
7240
|
+
* @returns {Promise<number>}
|
|
7241
|
+
*/
|
|
7242
|
+
async function fileSizeAsync(filePath) {
|
|
7243
|
+
if (!normalFuncs_fileExists(filePath)) return 0;
|
|
7244
|
+
const stats = await (0,promises_ignored_.stat)(filePath);
|
|
7245
|
+
return stats.size;
|
|
7246
|
+
}
|
|
7247
|
+
|
|
7248
|
+
/**
|
|
7249
|
+
* Returns the total size of a directory in bytes.
|
|
7250
|
+
* @param {string} dirPath
|
|
7251
|
+
* @returns {Promise<number>}
|
|
7252
|
+
*/
|
|
7253
|
+
async function dirSizeAsync(dirPath) {
|
|
7254
|
+
let total = 0;
|
|
7255
|
+
const { files } = await listFilesAsync(dirPath, true);
|
|
7256
|
+
const promises = [];
|
|
7257
|
+
for (const file of files) {
|
|
7258
|
+
const result = fileSizeAsync(file);
|
|
7259
|
+
result.then((item) => {
|
|
7260
|
+
total += item;
|
|
7261
|
+
return item;
|
|
7262
|
+
});
|
|
7263
|
+
promises.push(result);
|
|
7264
|
+
}
|
|
7265
|
+
await Promise.all(promises);
|
|
7266
|
+
return total;
|
|
7267
|
+
}
|
|
7268
|
+
|
|
7269
|
+
/*========================*
|
|
7270
|
+
* Backup Utilities
|
|
7271
|
+
*========================*/
|
|
7272
|
+
|
|
7273
|
+
/**
|
|
7274
|
+
* Restores the most recent backup of a file.
|
|
7275
|
+
* @param {string} filePath
|
|
7276
|
+
* @param {string} [ext='bak']
|
|
7277
|
+
* @returns {Promise<void>}
|
|
7278
|
+
*/
|
|
7279
|
+
function restoreLatestBackupAsync(filePath, ext = 'bak') {
|
|
7280
|
+
const latestBackup = getLatestBackupPath(filePath, ext);
|
|
7281
|
+
return ensureCopyFileAsync(latestBackup, filePath);
|
|
7282
|
+
}
|
|
7283
|
+
|
|
7284
|
+
/**
|
|
7285
|
+
* Creates a backup copy of a file with .bak timestamp suffix.
|
|
7286
|
+
* @param {string} filePath
|
|
7287
|
+
* @param {string} [ext='bak']
|
|
7288
|
+
* @returns {Promise<void>}
|
|
7289
|
+
*/
|
|
7290
|
+
async function backupFileAsync(filePath, ext = 'bak') {
|
|
7291
|
+
if (!fileExists(filePath)) return;
|
|
7292
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
7293
|
+
const backupPath = `${filePath}.${ext}.${timestamp}`;
|
|
7294
|
+
return ensureCopyFileAsync(filePath, backupPath);
|
|
7295
|
+
}
|
|
7296
|
+
|
|
7111
7297
|
;// ./src/v1/libs/TinyDragger.mjs
|
|
7112
7298
|
|
|
7113
7299
|
|
|
@@ -7132,6 +7318,7 @@ class TinyDragger {
|
|
|
7132
7318
|
#offsetY = 0;
|
|
7133
7319
|
#offsetX = 0;
|
|
7134
7320
|
|
|
7321
|
+
#multiCollision = false;
|
|
7135
7322
|
#lockInsideJail = false;
|
|
7136
7323
|
#revertOnDrop = false;
|
|
7137
7324
|
#dragging = false;
|
|
@@ -7176,6 +7363,7 @@ class TinyDragger {
|
|
|
7176
7363
|
* @param {string} [options.classDragCollision='dragging-collision'] - CSS class applied to collision element.
|
|
7177
7364
|
* @param {boolean} [options.lockInsideJail=false] - Restrict movement within the jail container.
|
|
7178
7365
|
* @param {boolean} [options.dropInJailOnly=false] - Restrict drop within the jail container.
|
|
7366
|
+
* @param {boolean} [options.multiCollision=false] - Enables returning multiple collided elements.
|
|
7179
7367
|
* @param {VibrationPatterns|false} [options.vibration=false] - Vibration feedback configuration.
|
|
7180
7368
|
* @param {boolean} [options.revertOnDrop=false] - Whether to return to original position on drop.
|
|
7181
7369
|
* @param {string} [options.classHidden='drag-hidden'] - CSS class to hide original element during dragging.
|
|
@@ -7222,6 +7410,7 @@ class TinyDragger {
|
|
|
7222
7410
|
validateBoolean(options.lockInsideJail, 'lockInsideJail');
|
|
7223
7411
|
validateBoolean(options.dropInJailOnly, 'dropInJailOnly');
|
|
7224
7412
|
validateBoolean(options.revertOnDrop, 'revertOnDrop');
|
|
7413
|
+
validateBoolean(options.multiCollision, 'multiCollision');
|
|
7225
7414
|
|
|
7226
7415
|
validateString(options.classDragging, 'classDragging');
|
|
7227
7416
|
validateString(options.classBodyDragging, 'classBodyDragging');
|
|
@@ -7255,6 +7444,7 @@ class TinyDragger {
|
|
|
7255
7444
|
if (typeof options.revertOnDrop === 'boolean') this.#revertOnDrop = options.revertOnDrop;
|
|
7256
7445
|
if (typeof options.lockInsideJail === 'boolean') this.#lockInsideJail = options.lockInsideJail;
|
|
7257
7446
|
if (typeof options.dropInJailOnly === 'boolean') this.#dropInJailOnly = options.dropInJailOnly;
|
|
7447
|
+
if (typeof options.multiCollision === 'boolean') this.#multiCollision = options.multiCollision;
|
|
7258
7448
|
|
|
7259
7449
|
/** @private */
|
|
7260
7450
|
this._onMouseDown = this.#startDrag.bind(this);
|
|
@@ -7446,22 +7636,67 @@ class TinyDragger {
|
|
|
7446
7636
|
this.#dispatchEvent('drag');
|
|
7447
7637
|
}
|
|
7448
7638
|
|
|
7639
|
+
/** @type {HTMLElement[]} */
|
|
7640
|
+
#collisionsMarked = [];
|
|
7641
|
+
|
|
7642
|
+
/**
|
|
7643
|
+
* Marks an element as currently collided by adding the collision CSS class.
|
|
7644
|
+
* The element is stored in an internal list for easy removal later.
|
|
7645
|
+
*
|
|
7646
|
+
* @param {HTMLElement|null} el - The element to mark as collided.
|
|
7647
|
+
*/
|
|
7648
|
+
#addCollision(el) {
|
|
7649
|
+
if (!el) return;
|
|
7650
|
+
el.classList.add(this.#classDragCollision);
|
|
7651
|
+
this.#collisionsMarked.push(el);
|
|
7652
|
+
}
|
|
7653
|
+
|
|
7654
|
+
/**
|
|
7655
|
+
* Removes the collision CSS class from all previously marked elements.
|
|
7656
|
+
* Also clears the last single collision element, if set.
|
|
7657
|
+
*
|
|
7658
|
+
*/
|
|
7659
|
+
#removeCollision() {
|
|
7660
|
+
while (this.#collisionsMarked.length > 0) {
|
|
7661
|
+
const el = this.#collisionsMarked.shift();
|
|
7662
|
+
if (el) el.classList.remove(this.#classDragCollision);
|
|
7663
|
+
}
|
|
7664
|
+
if (!this.#lastCollision) return;
|
|
7665
|
+
this.#lastCollision.classList.remove(this.#classDragCollision);
|
|
7666
|
+
}
|
|
7667
|
+
|
|
7449
7668
|
/**
|
|
7450
7669
|
* Handles dragging collision.
|
|
7451
7670
|
* @param {MouseEvent|Touch} event - The drag event.
|
|
7452
7671
|
*/
|
|
7453
7672
|
checkDragCollision(event) {
|
|
7454
|
-
const {
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7673
|
+
const { collidedElements } = this.execCollision(event);
|
|
7674
|
+
const first = collidedElements[0] || null;
|
|
7675
|
+
|
|
7676
|
+
// Removes old marking if necessary
|
|
7677
|
+
if (this.#lastCollision && !collidedElements.includes(this.#lastCollision)) {
|
|
7678
|
+
this.#removeCollision();
|
|
7679
|
+
}
|
|
7680
|
+
|
|
7681
|
+
// Adds Marking for All Colluded
|
|
7682
|
+
collidedElements.forEach((el) => this.#addCollision(el));
|
|
7683
|
+
|
|
7684
|
+
// Removes markings from who no longer collided
|
|
7685
|
+
this.#collidables.forEach((el) => {
|
|
7686
|
+
if (!collidedElements.includes(el)) {
|
|
7687
|
+
el.classList.remove(this.#classDragCollision);
|
|
7458
7688
|
}
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
this.#
|
|
7689
|
+
});
|
|
7690
|
+
|
|
7691
|
+
if (
|
|
7692
|
+
navigator.vibrate &&
|
|
7693
|
+
Array.isArray(this.#vibration.collide) &&
|
|
7694
|
+
collidedElements.length > 0
|
|
7695
|
+
) {
|
|
7696
|
+
navigator.vibrate(this.#vibration.collide);
|
|
7464
7697
|
}
|
|
7698
|
+
|
|
7699
|
+
this.#lastCollision = first;
|
|
7465
7700
|
}
|
|
7466
7701
|
|
|
7467
7702
|
/**
|
|
@@ -7508,37 +7743,48 @@ class TinyDragger {
|
|
|
7508
7743
|
/**
|
|
7509
7744
|
* Handles the collision of a drag.
|
|
7510
7745
|
* @param {MouseEvent|Touch} event - The release event.
|
|
7511
|
-
* @returns {{ inJail: boolean;
|
|
7746
|
+
* @returns {{ inJail: boolean; collidedElements: (HTMLElement | null)[] }}
|
|
7512
7747
|
*/
|
|
7513
7748
|
execCollision(event) {
|
|
7514
|
-
if (this.#destroyed || !this.#dragProxy) return { inJail: false,
|
|
7749
|
+
if (this.#destroyed || !this.#dragProxy) return { inJail: false, collidedElements: [] };
|
|
7515
7750
|
|
|
7516
|
-
let
|
|
7751
|
+
let collidedElements = [];
|
|
7517
7752
|
let inJail = true;
|
|
7518
7753
|
const jailRect = this.#jail?.getBoundingClientRect();
|
|
7754
|
+
|
|
7519
7755
|
if (this.#collisionByMouse) {
|
|
7520
7756
|
const x = event.clientX;
|
|
7521
7757
|
const y = event.clientY;
|
|
7758
|
+
|
|
7522
7759
|
if (this.#dropInJailOnly && this.#jail && jailRect) {
|
|
7523
7760
|
inJail =
|
|
7524
7761
|
x >= jailRect.left && x <= jailRect.right && y >= jailRect.top && y <= jailRect.bottom;
|
|
7525
7762
|
}
|
|
7526
7763
|
|
|
7527
|
-
|
|
7764
|
+
collidedElements = inJail
|
|
7765
|
+
? this.#multiCollision
|
|
7766
|
+
? this.getAllCollidedElements(x, y)
|
|
7767
|
+
: [this.getCollidedElement(x, y)].filter(Boolean)
|
|
7768
|
+
: [];
|
|
7528
7769
|
} else {
|
|
7529
|
-
const
|
|
7770
|
+
const rect = this.#dragProxy.getBoundingClientRect();
|
|
7771
|
+
|
|
7530
7772
|
if (this.#dropInJailOnly && this.#jail && jailRect) {
|
|
7531
7773
|
inJail =
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7774
|
+
rect.left >= jailRect.left &&
|
|
7775
|
+
rect.right <= jailRect.right &&
|
|
7776
|
+
rect.top >= jailRect.top &&
|
|
7777
|
+
rect.bottom <= jailRect.bottom;
|
|
7536
7778
|
}
|
|
7537
7779
|
|
|
7538
|
-
|
|
7780
|
+
collidedElements = inJail
|
|
7781
|
+
? this.#multiCollision
|
|
7782
|
+
? this.getAllCollidedElementsByRect(rect)
|
|
7783
|
+
: [this.getCollidedElementByRect(rect)].filter(Boolean)
|
|
7784
|
+
: [];
|
|
7539
7785
|
}
|
|
7540
7786
|
|
|
7541
|
-
return { inJail,
|
|
7787
|
+
return { inJail, collidedElements };
|
|
7542
7788
|
}
|
|
7543
7789
|
|
|
7544
7790
|
/**
|
|
@@ -7561,7 +7807,7 @@ class TinyDragger {
|
|
|
7561
7807
|
|
|
7562
7808
|
document.removeEventListener('touchmove', this._onTouchMove);
|
|
7563
7809
|
document.removeEventListener('touchend', this._onTouchEnd);
|
|
7564
|
-
const {
|
|
7810
|
+
const { collidedElements } = this.execCollision(event);
|
|
7565
7811
|
|
|
7566
7812
|
if (navigator.vibrate && Array.isArray(this.#vibration.end)) {
|
|
7567
7813
|
navigator.vibrate(this.#vibration.end);
|
|
@@ -7574,7 +7820,7 @@ class TinyDragger {
|
|
|
7574
7820
|
this.#dragProxy = null;
|
|
7575
7821
|
}
|
|
7576
7822
|
|
|
7577
|
-
if (this.#lastCollision) this.#
|
|
7823
|
+
if (this.#lastCollision) this.#removeCollision();
|
|
7578
7824
|
this.#lastCollision = null;
|
|
7579
7825
|
|
|
7580
7826
|
this.#target.classList.remove(this.#dragHiddenClass);
|
|
@@ -7585,13 +7831,50 @@ class TinyDragger {
|
|
|
7585
7831
|
|
|
7586
7832
|
const dropEvent = new CustomEvent('drop', {
|
|
7587
7833
|
detail: {
|
|
7588
|
-
|
|
7834
|
+
targets: collidedElements,
|
|
7835
|
+
first: collidedElements[0] || null,
|
|
7589
7836
|
},
|
|
7590
7837
|
});
|
|
7591
|
-
|
|
7592
7838
|
this.#target.dispatchEvent(dropEvent);
|
|
7593
7839
|
}
|
|
7594
7840
|
|
|
7841
|
+
/**
|
|
7842
|
+
* Checks if the provided element intersects with the given bounding rectangle.
|
|
7843
|
+
*
|
|
7844
|
+
* @param {HTMLElement} el - The element to test for collision.
|
|
7845
|
+
* @param {DOMRect} rect - The bounding rectangle to check against.
|
|
7846
|
+
* @returns {boolean} True if the element intersects with the rectangle.
|
|
7847
|
+
*/
|
|
7848
|
+
#getCollidedElementByRect(el, rect) {
|
|
7849
|
+
const elRect = el.getBoundingClientRect();
|
|
7850
|
+
return !(
|
|
7851
|
+
rect.right < elRect.left ||
|
|
7852
|
+
rect.left > elRect.right ||
|
|
7853
|
+
rect.bottom < elRect.top ||
|
|
7854
|
+
rect.top > elRect.bottom
|
|
7855
|
+
);
|
|
7856
|
+
}
|
|
7857
|
+
|
|
7858
|
+
/**
|
|
7859
|
+
* Returns all elements currently colliding with the given rectangle.
|
|
7860
|
+
*
|
|
7861
|
+
* @param {DOMRect} rect - Bounding rectangle of the dragged proxy.
|
|
7862
|
+
* @returns {HTMLElement[]} A list of all collided elements.
|
|
7863
|
+
* @throws {Error} If the input is not a valid DOMRect with numeric bounds.
|
|
7864
|
+
*/
|
|
7865
|
+
getAllCollidedElementsByRect(rect) {
|
|
7866
|
+
this.#checkDestroy();
|
|
7867
|
+
if (
|
|
7868
|
+
!(rect instanceof DOMRect) ||
|
|
7869
|
+
typeof rect.left !== 'number' ||
|
|
7870
|
+
typeof rect.right !== 'number' ||
|
|
7871
|
+
typeof rect.top !== 'number' ||
|
|
7872
|
+
typeof rect.bottom !== 'number'
|
|
7873
|
+
)
|
|
7874
|
+
throw new Error('getCollidedElementByRect expects a valid DOMRect object.');
|
|
7875
|
+
return this.#collidables.filter((el) => this.#getCollidedElementByRect(el, rect));
|
|
7876
|
+
}
|
|
7877
|
+
|
|
7595
7878
|
/**
|
|
7596
7879
|
* Detects collision based on rectangle intersection.
|
|
7597
7880
|
* @param {DOMRect} rect - Bounding rectangle of the dragged proxy.
|
|
@@ -7608,18 +7891,32 @@ class TinyDragger {
|
|
|
7608
7891
|
typeof rect.bottom !== 'number'
|
|
7609
7892
|
)
|
|
7610
7893
|
throw new Error('getCollidedElementByRect expects a valid DOMRect object.');
|
|
7894
|
+
return this.#collidables.find((el) => this.#getCollidedElementByRect(el, rect)) || null;
|
|
7895
|
+
}
|
|
7611
7896
|
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7897
|
+
/**
|
|
7898
|
+
* Checks whether a given (x, y) coordinate is inside the bounding rectangle of an element.
|
|
7899
|
+
*
|
|
7900
|
+
* @param {HTMLElement} el - The element to test for collision.
|
|
7901
|
+
* @param {number} x - Horizontal screen coordinate.
|
|
7902
|
+
* @param {number} y - Vertical screen coordinate.
|
|
7903
|
+
* @returns {boolean} True if the point is within the element's bounds.
|
|
7904
|
+
*/
|
|
7905
|
+
#getCollidedElement(el, x, y) {
|
|
7906
|
+
const rect = el.getBoundingClientRect();
|
|
7907
|
+
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
7908
|
+
}
|
|
7909
|
+
|
|
7910
|
+
/**
|
|
7911
|
+
* @param {number} x - Horizontal screen coordinate.
|
|
7912
|
+
* @param {number} y - Vertical screen coordinate.
|
|
7913
|
+
* @returns {HTMLElement[]} The collided element or null.
|
|
7914
|
+
*/
|
|
7915
|
+
getAllCollidedElements(x, y) {
|
|
7916
|
+
this.#checkDestroy();
|
|
7917
|
+
if (typeof x !== 'number' || typeof y !== 'number')
|
|
7918
|
+
throw new Error('getCollidedElement expects numeric x and y coordinates.');
|
|
7919
|
+
return this.#collidables.filter((el) => this.#getCollidedElement(el, x, y));
|
|
7623
7920
|
}
|
|
7624
7921
|
|
|
7625
7922
|
/**
|
|
@@ -7632,13 +7929,7 @@ class TinyDragger {
|
|
|
7632
7929
|
this.#checkDestroy();
|
|
7633
7930
|
if (typeof x !== 'number' || typeof y !== 'number')
|
|
7634
7931
|
throw new Error('getCollidedElement expects numeric x and y coordinates.');
|
|
7635
|
-
|
|
7636
|
-
return (
|
|
7637
|
-
this.#collidables.find((el) => {
|
|
7638
|
-
const rect = el.getBoundingClientRect();
|
|
7639
|
-
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
7640
|
-
}) || null
|
|
7641
|
-
);
|
|
7932
|
+
return this.#collidables.find((el) => this.#getCollidedElement(el, x, y)) || null;
|
|
7642
7933
|
}
|
|
7643
7934
|
|
|
7644
7935
|
/**
|
|
@@ -7888,7 +8179,7 @@ class TinyDragger {
|
|
|
7888
8179
|
document.removeEventListener('touchmove', this._onTouchMove);
|
|
7889
8180
|
document.removeEventListener('touchend', this._onTouchEnd);
|
|
7890
8181
|
|
|
7891
|
-
if (this.#lastCollision) this.#
|
|
8182
|
+
if (this.#lastCollision) this.#removeCollision();
|
|
7892
8183
|
if (this.#dragProxy) {
|
|
7893
8184
|
this.#dragProxy.remove();
|
|
7894
8185
|
this.#dragProxy = null;
|
|
@@ -7926,6 +8217,10 @@ class TinyDragger {
|
|
|
7926
8217
|
|
|
7927
8218
|
|
|
7928
8219
|
|
|
8220
|
+
|
|
8221
|
+
|
|
8222
|
+
|
|
8223
|
+
|
|
7929
8224
|
|
|
7930
8225
|
|
|
7931
8226
|
|