@whitesev/pops
Version:
弹窗库,包含了alert、confirm、prompt、drawer、folder、loading、iframe、panel、tooltip、searchSuggestion、rightClickMenu组件
984 lines (947 loc) • 35.7 kB
text/typescript
import { GlobalConfig } from "../../config/GlobalConfig";
import { EventEmiter } from "../../event/EventEmiter";
import { PopsElementHandler } from "../../handler/PopsElementHandler";
import { PopsHandler } from "../../handler/PopsHandler";
import { PopsInstHandler } from "../../handler/PopsInstHandler";
import { PopsCSS } from "../../PopsCSS";
import type { EventMap } from "../../types/EventEmitter";
import type { PopsType } from "../../types/main";
import { popsDOMUtils } from "../../utils/PopsDOMUtils";
import { PopsSafeUtils } from "../../utils/PopsSafeUtils";
import { popsUtils } from "../../utils/PopsUtils";
import { PopsLoading } from "../loading";
import { PopsFolderDefaultConfig } from "./defaultConfig";
import { Folder_ICON } from "./folderIcon";
import type { PopsFolderConfig, PopsFolderDataConfig, PopsFolderDownloadOption } from "./types";
export const PopsFolder = {
init(__config__: PopsFolderConfig) {
const guid = popsUtils.getRandomGUID();
// 设置当前类型
const popsType: PopsType = "folder";
let config = PopsFolderDefaultConfig();
config = popsUtils.assign(config, GlobalConfig.getGlobalConfig());
config = popsUtils.assign(config, __config__);
config = PopsHandler.handleOnly(popsType, config);
const emitter = config.emitter ?? new EventEmiter<EventMap>(popsType);
const { $shadowContainer, $shadowRoot } = PopsHandler.handlerShadow(config);
PopsHandler.handleInit($shadowRoot, [
{
name: "index",
css: PopsCSS.index,
},
{
name: "ninePalaceGridPosition",
css: PopsCSS.ninePalaceGridPosition,
},
{
name: "scrollbar",
css: PopsCSS.scrollbar,
},
{
name: "button",
css: PopsCSS.button,
},
{
name: "anim",
css: PopsCSS.anim,
},
{
name: "common",
css: PopsCSS.common,
},
{
name: "skeleton",
css: PopsCSS.skeletonCSS,
},
{
name: "folderCSS",
css: PopsCSS.folderCSS,
},
]);
// 办公几件套
Reflect.set(Folder_ICON, "docx", Folder_ICON.doc);
Reflect.set(Folder_ICON, "rtf", Folder_ICON.doc);
Reflect.set(Folder_ICON, "xlsx", Folder_ICON.xls);
Reflect.set(Folder_ICON, "pptx", Folder_ICON.ppt);
Reflect.set(Folder_ICON, "dmg", Folder_ICON.ipa);
Reflect.set(Folder_ICON, "json", Folder_ICON.js);
// 压缩包
const zipIconList = [
"rar",
"7z",
"arj",
"bz2",
"cab",
"iso",
"jar",
"lz",
"lzh",
"tar",
"uue",
"xz",
"z",
"zipx",
"zst",
"001",
];
// 图片
const imageIconList = ["jpg", "jpeg", "ico", "webp"];
// 代码语言
const codeLanguageIconList = ["htm", "py", "vue", "bat", "sh", "vbs", "java", "kt"];
// Android安装包
const androidIconList = ["apk", "apkm", "xapk"];
zipIconList.forEach((keyName) => {
Folder_ICON[keyName as keyof typeof Folder_ICON] = Folder_ICON.zip;
});
imageIconList.forEach((keyName) => {
Folder_ICON[keyName as keyof typeof Folder_ICON] = Folder_ICON.png;
});
codeLanguageIconList.forEach((keyName) => {
Folder_ICON[keyName as keyof typeof Folder_ICON] = Folder_ICON.html;
});
androidIconList.forEach((keyName) => {
Folder_ICON[keyName as keyof typeof Folder_ICON] = Folder_ICON.apk;
});
if (config?.folder) {
Reflect.set(config, "folder", config.folder);
}
// 先把z-index提取出来
const zIndex = PopsHandler.getTargerOrFunctionValue(config.zIndex);
const maskHTML = PopsElementHandler.createMask(guid, zIndex);
const headerBtnHTML = PopsElementHandler.createHeader(popsType, config);
const bottomBtnHTML = PopsElementHandler.createBottom(popsType, config);
const { headerStyle, headerPStyle } = PopsElementHandler.createHeaderStyle(popsType, config);
const animHTML = PopsElementHandler.createAnim(
guid,
popsType,
config,
/*html*/ `
<div class="pops-title pops-${popsType}-title" style="text-align: ${
config.title.position
};${headerStyle}">${
config.title.html
? config.title.text
: `<p pops class="pops-${popsType}-title-text" style="${headerPStyle}">${config.title.text}</p>`
}${headerBtnHTML}</div>
<div class="pops-content pops-${popsType}-content ${popsUtils.isPhone() ? "pops-mobile-folder-content" : ""}">
<div class="pops-folder-list">
<div class="pops-folder-file-list-breadcrumb">
<div class="pops-folder-file-list-breadcrumb-primary">
<span class="pops-folder-file-list-breadcrumb-allFiles cursor-p" title="全部文件">
<a>全部文件</a>
</span>
</div>
</div>
<div class="pops-folder-list-table__header-div">
<table class="pops-folder-list-table__header">
<colgroup>
<col width="52%">
<col width="24%">
<col width="16%">
</colgroup>
<thead>
<tr class="pops-folder-list-table__header-row">
<th class="pops-folder-list-table__header-th cursor-p">
<div class="text-ellip content flex-a-i-center">
<span>文件名</span>
<div class="pops-folder-list-table__sort" data-sort="fileName">
<div class="pops-folder-icon-arrow" data-sort="按文件名排序">
<svg
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg">
<path
d="M509.624392 5.882457 57.127707 458.379143 962.121078 458.379143Z"
class="pops-folder-icon-arrow-up"></path>
<path
d="M509.624392 1024 962.121078 571.503314 57.127707 571.503314Z"
class="pops-folder-icon-arrow-down"></path>
</svg>
</div>
</div>
</div>
</th>
<th class="pops-folder-list-table__header-th cursor-p">
<div class="text-ellip content flex-a-i-center">
<span>修改时间</span>
<div class="pops-folder-list-table__sort" data-sort="latestTime">
<div class="pops-folder-icon-arrow" title="按修改时间排序">
<svg
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg">
<path
d="M509.624392 5.882457 57.127707 458.379143 962.121078 458.379143Z"
class="pops-folder-icon-arrow-up"></path>
<path
d="M509.624392 1024 962.121078 571.503314 57.127707 571.503314Z"
class="pops-folder-icon-arrow-down"></path>
</svg>
</div>
</div>
</div>
</th>
<th class="pops-folder-list-table__header-th cursor-p">
<div class="text-ellip content flex-a-i-center">
<span>大小</span>
<div class="pops-folder-list-table__sort" data-sort="fileSize">
<div class="pops-folder-icon-arrow" title="按大小排序">
<svg
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg">
<path
d="M509.624392 5.882457 57.127707 458.379143 962.121078 458.379143Z"
class="pops-folder-icon-arrow-up"></path>
<path
d="M509.624392 1024 962.121078 571.503314 57.127707 571.503314Z"
class="pops-folder-icon-arrow-down"></path>
</svg>
</div>
</div>
</div>
</th>
</tr>
</thead>
</table>
</div>
<div class="pops-folder-list-table__body-div">
<table class="pops-folder-list-table__body">
<colgroup>
${
popsUtils.isPhone()
? `<col width="100%">`
: `
<col width="52%">
<col width="24%">
<col width="16%">`
}
</colgroup>
<tbody></tbody>
</table>
</div>
</div>
</div>${bottomBtnHTML}`,
bottomBtnHTML,
zIndex
);
/**
* 弹窗的主元素,包括动画层
*/
const $anim = PopsElementHandler.parseElement<HTMLDivElement>(animHTML);
const {
$pops: $pops,
$title: $title,
$content: $content,
// folderListElement,
// folderListHeaderElement,
// folderListHeaderRowElement,
$folderTbody: folderListBodyElement,
$folderHeaderBreadcrumbPrimary: folderFileListBreadcrumbPrimaryElement,
$headerBtnClose: $btnCloseBtn,
$btnOk: btnOkElement,
$btnCancel: btnCancelElement,
$btnOther: btnOtherElement,
$folderSortFileName: folderListSortFileNameElement,
$folderSortLatestTime: folderListSortLatestTimeElement,
$folderSortFileSize: folderListSortFileSizeElement,
} = PopsHandler.handleQueryElement($anim, popsType);
/**
* 遮罩层元素
*/
let $mask: HTMLDivElement | undefined = void 0;
/**
* 已创建的元素列表
*/
const $elList: HTMLElement[] = [$anim];
if (config.mask.enable) {
const handleMask = PopsHandler.handleMask({
type: popsType,
guid: guid,
config: config,
animElement: $anim,
maskHTML: maskHTML,
});
$mask = handleMask.maskElement;
$elList.push($mask);
}
// 事件
const evtConfig = PopsHandler.handleEventConfig(
config,
guid,
$shadowContainer,
$shadowRoot,
popsType,
$anim,
$pops,
emitter,
$mask
);
const result = PopsHandler.handleResultConfig(evtConfig);
PopsHandler.handleClickEvent("close", $btnCloseBtn, evtConfig, config.btn.close.callback);
PopsHandler.handleClickEvent("ok", btnOkElement, evtConfig, config.btn.ok.callback);
PopsHandler.handleClickEvent("cancel", btnCancelElement, evtConfig, config.btn.cancel.callback);
PopsHandler.handleClickEvent("other", btnOtherElement, evtConfig, config.btn.other.callback);
// 创建到页面中
popsDOMUtils.append($shadowRoot, $elList);
emitter.emit("pops:before-append-to-page", $shadowRoot, $shadowContainer);
popsDOMUtils.appendBody($shadowContainer);
if ($mask != null) {
$anim.after($mask);
}
class PopsFolder {
init() {
config.folder.sort();
this.initFolderView(config.folder);
// 将数据存到全部文件的属性_config_中
const $allFiles = folderFileListBreadcrumbPrimaryElement.querySelector<HTMLDivElement>(
".pops-folder-list .pops-folder-file-list-breadcrumb-allFiles:first-child"
)!;
Reflect.set($allFiles, "data-config", config.folder);
// 设置点击顶部的全部文件事件
popsDOMUtils.on<MouseEvent | PointerEvent>($allFiles, "click", (event) => {
this.setBreadcrumbClickEvent(event, true, config.folder);
});
// 文件名的点击排序
popsDOMUtils.on<MouseEvent | PointerEvent>(
folderListSortFileNameElement.closest("th"),
"click",
(event) => {
this.arrowToSortFolderInfoView(folderListSortFileNameElement, event, "fileName");
},
{
capture: true,
}
);
// 修改事件的点击排序
popsDOMUtils.on(
folderListSortLatestTimeElement.closest("th"),
"click",
(event) => {
this.arrowToSortFolderInfoView(folderListSortLatestTimeElement, event, "latestTime");
},
{
capture: true,
}
);
// 文件大小的点击排序
popsDOMUtils.on(
folderListSortFileSizeElement.closest("th"),
"click",
(event) => {
this.arrowToSortFolderInfoView(folderListSortFileSizeElement, event, "fileSize");
},
{
capture: true,
}
);
// 设置默认触发的arrow
if (config.sort.name === "fileName") {
popsDOMUtils.emit(folderListSortFileNameElement, "click", {
notChangeSortRule: true,
});
} else if (config.sort.name === "latestTime") {
popsDOMUtils.emit(folderListSortLatestTimeElement, "click", {
notChangeSortRule: true,
});
} else if (config.sort.name === "fileSize") {
popsDOMUtils.emit(folderListSortFileSizeElement, "click", {
notChangeSortRule: true,
});
}
}
/**
* 在创建文件|文件夹创建元素前处理东西
*/
handlerWithBeforeCreateFileOrFolderInfoNode(folderData: PopsFolderDataConfig) {
let { fileSize } = folderData;
const { fileName, latestTime, isFolder = false } = folderData;
folderData.latestTime = folderData.latestTime ?? "-";
folderData.fileSize = folderData.fileSize ?? "-";
const $folder = popsDOMUtils.createElement("tr");
const $fileName = popsDOMUtils.createElement("td");
const $fileTime = popsDOMUtils.createElement("td");
const $fileFormatSize = popsDOMUtils.createElement("td");
let show_latestTime = "";
let show_fileSize = "";
let fileType = "";
let fileIcon = "";
if (isFolder) {
// 文件夹
fileType = "";
fileIcon = Folder_ICON.folder;
show_latestTime = "";
fileSize = "";
show_fileSize = "";
} else {
// 文件
if (typeof latestTime === "function") {
const timeRet = latestTime();
show_latestTime = timeRet.showText;
} else if (typeof latestTime === "number") {
show_latestTime = popsUtils.formatTime(latestTime);
} else if (typeof latestTime === "string") {
show_latestTime = latestTime;
}
if (typeof fileSize === "number") {
show_fileSize = popsUtils.formatByteToSize(fileSize, true);
} else if (typeof fileSize === "string") {
show_fileSize = fileSize;
}
// 找到对应的图标
const findIconKeyName = Object.keys(Folder_ICON).find((keyName) => {
if (fileName.toLowerCase().endsWith("." + keyName)) {
fileType = keyName;
fileIcon = Reflect.get(Folder_ICON, keyName);
return true;
}
});
if (findIconKeyName) {
fileIcon = Reflect.get(Folder_ICON, findIconKeyName);
fileType = findIconKeyName;
} else {
fileType = "Null";
fileIcon = Folder_ICON.Null;
}
}
if (typeof folderData.fileIcon === "string") {
// 强制使用自定义
fileIcon = folderData.fileIcon;
}
$folder.className = "pops-folder-list-table__body-row";
$fileName.className = "pops-folder-list-table__body-td";
$fileTime.className = "pops-folder-list-table__body-td";
$fileFormatSize.className = "pops-folder-list-table__body-td";
return {
$folder,
$fileName,
$fileTime,
$fileFormatSize,
/** 经过处理后的数据 */
data: {
fileType,
fileIcon,
show_latestTime,
show_fileSize,
},
};
}
/**
* 创建文件夹元素
* @param fileName 文件名
* @param latestTime 修改时间
* @param [fileSize="-"] 文件大小
* @param isFolder 是否是文件夹
*/
createFolderRowElement(folderData: PopsFolderDataConfig) {
const { $folder, $fileName, $fileTime, $fileFormatSize, data } =
this.handlerWithBeforeCreateFileOrFolderInfoNode(folderData);
const { fileName } = folderData;
PopsSafeUtils.setSafeHTML(
$fileName,
/*html*/ `
<div class="pops-folder-list-file-name cursor-p">
<div>
<img src="${data.fileIcon}" alt="${data.fileType}" class="pops-folder-list-file-icon u-file-icon u-file-icon--list">
<a href="javascript:;" title="${fileName}" class="pops-folder-list-file-name-title-text inline-block-v-middle text-ellip list-name-text">${fileName}</a>
</div>
</div>`
);
PopsSafeUtils.setSafeHTML(
$fileTime,
/*html*/ `
<div class="pops-folder-list__time">
<span>${data.show_latestTime}</span>
</div>`
);
PopsSafeUtils.setSafeHTML(
$fileFormatSize,
/*html*/ `
<div class="pops-folder-list-format-size">
<span>${data.show_fileSize}</span>
</div>`
);
Reflect.set($fileName, "__value__", folderData);
Reflect.set($fileTime, "__value__", folderData);
Reflect.set($fileFormatSize, "__value__", folderData);
Reflect.set($folder, "__value__", folderData);
$folder.appendChild($fileName);
$folder.appendChild($fileTime);
$folder.appendChild($fileFormatSize);
return {
folderElement: $folder,
fileNameElement: $fileName,
fileTimeElement: $fileTime,
fileFormatSize: $fileFormatSize,
};
}
/**
* 创建移动端文件夹元素
* @param fileName 文件名
* @param latestTime 创建时间
* @param [fileSize="-"] 文件大小
* @param isFolder 是否是文件夹
*/
createFolderRowElementByMobile(folderData: PopsFolderDataConfig) {
const { $folder, $fileName, data } = this.handlerWithBeforeCreateFileOrFolderInfoNode(folderData);
const { fileName } = folderData;
PopsSafeUtils.setSafeHTML(
$fileName,
/*html*/ `
<div class="pops-folder-list-file-name pops-mobile-folder-list-file-name cursor-p">
<img src="${data.fileIcon}" alt="${data.fileType}" class="pops-folder-list-file-icon u-file-icon u-file-icon--list">
<div>
<a title="${fileName}" class="pops-folder-list-file-name-title-text inline-block-v-middle text-ellip list-name-text">${fileName}</a>
<span>${data.show_latestTime} ${data.show_fileSize}</span>
</div>
</div>`
);
// 存储原来的值
Reflect.set($fileName, "__value__", folderData);
Reflect.set($folder, "__value__", folderData);
$folder.appendChild($fileName);
return {
folderElement: $folder,
/**
* 超链接标签的容器
*/
fileNameElement: $fileName,
};
}
/**
* 清空文件夹信息页面
*/
clearFolderInfoView() {
PopsSafeUtils.setSafeHTML(folderListBodyElement, "");
}
/**
* 创建顶部导航的箭头图标
*/
createHeaderArrowIcon() {
const $arrowIcon = popsDOMUtils.createElement("div", {
className: "iconArrow",
});
return $arrowIcon;
}
/**
* 添加顶部导航元素
* @param folderName 文件夹名
* @param folderDataConfig 文件夹配置
*/
createBreadcrumb(
folderName: string,
folderDataConfig: PopsFolderDownloadOption | PopsFolderDataConfig[] | null | undefined | void
) {
const $breadcrumb = popsDOMUtils.createElement(
"span",
{
className: "pops-folder-file-list-breadcrumb-allFiles cursor-p",
innerHTML: `<a>${folderName}</a>`,
"data-config": folderDataConfig,
},
{
title: folderName,
}
);
return $breadcrumb;
}
/**
* 顶部导航的点击事件
* @param clickEvent
* @param isTop 是否是全部文件按钮
* @param dataConfigList 配置
*/
setBreadcrumbClickEvent(
clickEvent: MouseEvent | PointerEvent,
isTop: boolean,
dataConfigList: PopsFolderDataConfig[]
) {
this.clearFolderInfoView();
// 获取当前的导航元素
const $click = clickEvent.target as HTMLElement;
const currentBreadcrumb = $click.closest<HTMLSpanElement>("span.pops-folder-file-list-breadcrumb-allFiles");
if (currentBreadcrumb) {
while (currentBreadcrumb.nextElementSibling) {
popsDOMUtils.remove(currentBreadcrumb.nextElementSibling);
}
} else {
console.error("获取导航按钮失败");
}
const loadingMask = PopsLoading.init({
$parent: $content,
content: {
text: "获取文件列表中...",
},
mask: {
enable: true,
clickEvent: {
toClose: false,
toHide: false,
},
},
addIndexCSS: false,
});
this.initFolderView(dataConfigList);
loadingMask.close();
}
/**
* 文件夹的点击事件 - 进入文件夹
*
* 先情况页面元素
* @param clickEvent
* @param dataConfig
*/
async enterFolder(clickEvent: MouseEvent | PointerEvent, dataConfig: PopsFolderDataConfig) {
this.clearFolderInfoView();
const loadingMask = PopsLoading.init({
$parent: $content,
content: {
text: "获取文件列表中...",
},
mask: {
enable: true,
},
addIndexCSS: false,
});
let childConfig: PopsFolderDataConfig[] | undefined;
if (typeof dataConfig.clickEvent === "function") {
const result = await dataConfig.clickEvent(clickEvent, dataConfig);
if (Array.isArray(result)) {
childConfig = result;
}
} else if (Array.isArray(dataConfig.clickEvent)) {
childConfig = dataConfig.clickEvent;
}
if (childConfig) {
// 添加顶部导航的箭头
folderFileListBreadcrumbPrimaryElement.appendChild(this.createHeaderArrowIcon());
// 添加顶部导航的链接文字
const $breadcrumbAllFiles = this.createBreadcrumb(dataConfig.fileName, childConfig);
folderFileListBreadcrumbPrimaryElement.appendChild($breadcrumbAllFiles);
// 设置顶部导航点击事件
popsDOMUtils.on<MouseEvent | PointerEvent>($breadcrumbAllFiles, "click", (event) => {
this.setBreadcrumbClickEvent(event, false, childConfig as PopsFolderDataConfig[]);
});
this.initFolderView(childConfig as PopsFolderDataConfig[]);
}
loadingMask.close();
}
/**
* 更新文件的显示的链接信息
*
* 这里主要用于鼠标中键或者右键触发,左键触发方式会根据mode进行处理
* @returns 更新的文件的下载链接
*/
updateFileLink($row: HTMLElement, downloadInfo: PopsFolderDownloadOption) {
const downloadUrl = typeof downloadInfo?.url === "string" ? downloadInfo.url.trim() : "";
if (downloadUrl !== "" && downloadUrl !== "null" && downloadUrl !== "undefined") {
const $link = $row.querySelector("a")!;
$link.setAttribute("href", downloadUrl);
return downloadUrl;
}
}
/**
* 文件的点击事件 - 下载文件
* @param evt 点击事件
* @param $row 列表项
* @param dataConfig
*/
async onFileClick(evt: MouseEvent | PointerEvent, $row: HTMLElement, dataConfig: PopsFolderDataConfig) {
let downloadInfo: PopsFolderDownloadOption | undefined;
if (typeof dataConfig.clickEvent === "function") {
const result = await dataConfig.clickEvent(evt, dataConfig);
if (typeof result === "object" && result != null && !Array.isArray(result)) {
downloadInfo = result;
}
} else if (
typeof dataConfig.clickEvent === "object" &&
dataConfig.clickEvent != null &&
!Array.isArray(dataConfig.clickEvent)
) {
downloadInfo = dataConfig.clickEvent;
}
if (downloadInfo) {
const downloadUrl = this.updateFileLink($row, downloadInfo);
if (downloadUrl) {
if (typeof downloadInfo.mode === "string") {
if (downloadInfo.mode === "a" || downloadInfo.mode === "aBlank") {
// a标签下载
const $anchor = popsDOMUtils.createElement("a");
if (downloadInfo.mode === "aBlank") {
$anchor.setAttribute("target", "_blank");
}
$anchor.href = downloadUrl;
$anchor.click();
} else if (downloadInfo.mode === "open" || downloadInfo.mode === "openBlank") {
// window.open下载
if (downloadInfo.mode === "openBlank") {
globalThis.open(downloadUrl, "_blank");
} else {
globalThis.open(downloadUrl);
}
} else if (downloadInfo.mode === "iframe") {
// iframe下载
const $downloadIframe = popsDOMUtils.createElement("iframe");
$downloadIframe.src = downloadUrl;
$downloadIframe.onload = function () {
popsUtils.setTimeout(() => {
popsDOMUtils.remove($downloadIframe);
}, 1000);
};
$shadowRoot.appendChild($downloadIframe);
popsUtils.setTimeout(
() => {
popsDOMUtils.remove($downloadIframe);
},
3 * 60 * 1000
);
} else {
console.error("未知的下载模式", downloadInfo);
}
}
}
}
}
/**
* 对配置进行排序
* @param folderDataConfigList
* @param sortName 比较的属性,默认fileName
* @param isDesc 是否降序,默认false(升序)
*/
sortFolderConfig(
folderDataConfigList: PopsFolderDataConfig[],
sortName: "fileName" | "fileSize" | "latestTime" = "fileName",
isDesc = false
) {
// 文件夹
const onlyFolderDataConfigList = folderDataConfigList.filter((value) => {
return value.isFolder;
});
// 文件
const onlyFileDataConfigList = folderDataConfigList.filter((value) => {
return !value.isFolder;
});
if (sortName === "fileName") {
// 文件夹排序
onlyFolderDataConfigList.sort((leftConfig, rightConfig) => {
const beforeVal = leftConfig[sortName].toString();
const afterVal = rightConfig[sortName].toString();
let compareVal = beforeVal.localeCompare(afterVal);
if (isDesc) {
// 降序
if (compareVal > 0) {
compareVal = -1;
} else if (compareVal < 0) {
compareVal = 1;
}
}
return compareVal;
});
// 文件名排序
onlyFileDataConfigList.sort((leftConfig, rightConfig) => {
const beforeVal = leftConfig[sortName].toString();
const afterVal = rightConfig[sortName].toString();
let compareVal = beforeVal.localeCompare(afterVal);
if (isDesc) {
// 降序
if (compareVal > 0) {
compareVal = -1;
} else if (compareVal < 0) {
compareVal = 1;
}
}
return compareVal;
});
} else {
// 文件夹排序
onlyFolderDataConfigList.sort((beforeConfig, afterConfig) => {
let beforeVal = beforeConfig[sortName];
let afterVal = afterConfig[sortName];
if (typeof beforeVal === "function") {
beforeVal = beforeVal().timeStamp;
}
if (typeof afterVal === "function") {
afterVal = afterVal().timeStamp;
}
if (sortName === "fileSize") {
// 文件大小,进行Float转换
beforeVal = parseFloat(beforeVal.toString());
afterVal = parseFloat(afterVal.toString());
} else if (sortName === "latestTime") {
// 文件时间
beforeVal = new Date(beforeVal || "").getTime();
afterVal = new Date(afterVal || "").getTime();
}
if (beforeVal > afterVal) {
if (isDesc) {
// 降序
return -1;
} else {
return 1;
}
} else if (beforeVal < afterVal) {
if (isDesc) {
// 降序
return 1;
} else {
return -1;
}
} else {
return 0;
}
});
// 文件排序
onlyFileDataConfigList.sort((beforeConfig, afterConfig) => {
let beforeVal = beforeConfig[sortName];
let afterVal = afterConfig[sortName];
if (typeof beforeVal === "function") {
beforeVal = beforeVal().timeStamp;
}
if (typeof afterVal === "function") {
afterVal = afterVal().timeStamp;
}
if (sortName === "fileSize") {
// 文件大小,进行Float转换
beforeVal = parseFloat(beforeVal.toString());
afterVal = parseFloat(afterVal.toString());
} else if (sortName === "latestTime") {
// 文件时间
beforeVal = new Date(beforeVal).getTime();
afterVal = new Date(afterVal).getTime();
}
if (beforeVal > afterVal) {
if (isDesc) {
// 降序
return -1;
} else {
return 1;
}
} else if (beforeVal < afterVal) {
if (isDesc) {
// 降序
return 1;
} else {
return -1;
}
} else {
return 0;
}
});
}
// 文件夹始终优先放前面
return [...onlyFolderDataConfigList, ...onlyFileDataConfigList];
}
/**
* 添加文件夹/文件行元素
* @param dataConfig 配置
*/
initFolderView(dataConfig: PopsFolderDataConfig[]) {
// 先对文件夹、文件进行排序
const sortedConfigList = this.sortFolderConfig(dataConfig, config.sort.name, config.sort.isDesc);
sortedConfigList.forEach((item) => {
if (item.isFolder) {
const { folderElement, fileNameElement } = popsUtils.isPhone()
? this.createFolderRowElementByMobile(item)
: this.createFolderRowElement(item);
// 文件夹 - 点击事件
popsDOMUtils.on<MouseEvent | PointerEvent>(fileNameElement, "click", (event) => {
// 进入文件夹
this.enterFolder(event, item);
});
folderListBodyElement.appendChild(folderElement);
} else {
const { folderElement, fileNameElement } = popsUtils.isPhone()
? this.createFolderRowElementByMobile(item)
: this.createFolderRowElement(item);
// 文件 - 点击事件
popsDOMUtils.on<MouseEvent | PointerEvent>(fileNameElement, "click", (event) => {
// 下载文件
popsDOMUtils.preventEvent(event);
this.onFileClick(event, fileNameElement, item);
});
// 如果clickEvent不是函数,那么现在就可以进行配置
if (typeof item.clickEvent === "object" && item.clickEvent !== null && !Array.isArray(item.clickEvent)) {
// {} 单文件配置
this.updateFileLink(fileNameElement, item.clickEvent);
}
folderListBodyElement.appendChild(folderElement);
}
});
}
/**
* 移除所有箭头的被访问状态
*/
removeArrowActiveStatus() {
[
...Array.from(folderListSortFileNameElement.querySelectorAll<HTMLElement>(".pops-folder-icon-active")),
...Array.from(folderListSortLatestTimeElement.querySelectorAll<HTMLElement>(".pops-folder-icon-active")),
...Array.from(folderListSortFileSizeElement.querySelectorAll<HTMLElement>(".pops-folder-icon-active")),
].forEach(($elItem) => popsDOMUtils.removeClassName($elItem, "pops-folder-icon-active"));
}
/**
* 修改导航箭头的状态
* @param arrowUp ↑
* @param arrowDown ↓
* @param isDesc 是否逆反
*/
changeArrowActive(arrowUp: HTMLElement, arrowDown: HTMLElement, isDesc: boolean) {
this.removeArrowActiveStatus();
const activeClassName = "pops-folder-icon-active";
popsDOMUtils.addClassName(isDesc ? arrowDown : arrowUp, activeClassName);
}
/**
* 排序按钮的点击事件
* @param $target
* @param event
* @param sortName
*/
arrowToSortFolderInfoView($target: HTMLDivElement, event: MouseEvent | PointerEvent, sortName: string) {
const notChangeSortRule = Reflect.get(event, "notChangeSortRule");
if (!notChangeSortRule) {
config.sort.name = sortName as PopsFolderConfig["sort"]["name"];
config.sort.isDesc = !config.sort.isDesc;
}
const $arrowUp = $target.querySelector<HTMLDivElement>(".pops-folder-icon-arrow-up")!;
const $arrowDown = $target.querySelector<HTMLDivElement>(".pops-folder-icon-arrow-down")!;
this.changeArrowActive($arrowUp, $arrowDown, config.sort.isDesc);
if (
typeof config.sort.callback === "function" &&
config.sort.callback($target, event, config.sort.name, config.sort.isDesc)
) {
return;
}
const childrenList: PopsFolderDataConfig[] = [];
Array.from(folderListBodyElement.children).forEach(($tr) => {
const __value__ = Reflect.get($tr, "__value__");
Reflect.set(__value__, "target", $tr);
childrenList.push(__value__);
});
const sortedConfigList = this.sortFolderConfig(childrenList, config.sort.name, config.sort.isDesc);
sortedConfigList.forEach((item) => {
folderListBodyElement.appendChild((item as any).target);
});
}
}
const popsFolder = new PopsFolder();
popsFolder.init();
Reflect.set($pops, "data-pops-folder", popsFolder);
// 拖拽
if (config.drag) {
PopsInstHandler.drag($pops, {
dragElement: $title,
limit: config.dragLimit,
extraDistance: config.dragExtraDistance,
moveCallBack: config.dragMoveCallBack,
endCallBack: config.dragEndCallBack,
});
}
PopsHandler.handlePush(popsType, {
guid: guid,
$anim: $anim,
$pops: $pops,
$mask: $mask!,
$shadowContainer: $shadowContainer,
$shadowRoot: $shadowRoot,
config: config,
emitter,
});
return result;
},
};