faim
Version:
Element Plus & Element UI isomorphic UI component library, more than Element.
299 lines (298 loc) • 9.45 kB
JavaScript
import { at, isPlainObject } from "lodash-es";
import isBase64 from "validator/es/lib/isBase64";
import isURL from "validator/es/lib/isURL";
import { isVue3 } from "vue-demi";
import { conclude, getLocalListeners } from "vue-global-config";
import FaMessageBox from "./components/MessageBox/index.mjs";
export const MB = 1024 ** 2;
export const KB = 1024;
export function getListeners(globalListeners) {
if (isVue3) {
return {};
}
for (const k in globalListeners) {
globalListeners[k] = globalListeners[k].bind(this);
}
return conclude([getLocalListeners(this.$listeners)], {
default: globalListeners,
mergeFunction: (localEventListener, globalEventListener) => (...args) => {
localEventListener(...args);
globalEventListener(...args);
}
});
}
export function isGlobalSlot(slot) {
return typeof slot === "function" && slot.name.startsWith("#");
}
export function isEmpty(value) {
return {
object: () => value === null || Array.isArray(value) && value.length === 0 || isPlainObject(value) && Object.getOwnPropertyNames(value).length === 0,
number: () => Number.isNaN(value),
string: () => value === "",
undefined: () => true,
boolean: () => value === false,
symbol: () => false,
bigint: () => false,
function: () => true
}[typeof value]();
}
export function notEmpty(value) {
return !isEmpty(value);
}
export function isObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
export function isBase64WithScheme(str, mediaType) {
if (!str || typeof str !== "string") {
return false;
}
if (mediaType && !str.startsWith(`data:${mediaType}`)) {
return false;
} else {
const base64WithoutScheme = str.split(",")[1];
return base64WithoutScheme ? isBase64(base64WithoutScheme) : false;
}
}
export function blobLikeToBase64(binary) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onerror = (e) => {
reject(e);
};
fileReader.onload = (e) => {
resolve(e.target?.result);
};
fileReader.readAsDataURL(binary);
});
}
export async function toBlobLike(source) {
if (typeof source === "string") {
if (isURL(source) || isBase64WithScheme(source, "image/") || source.startsWith("blob:")) {
return await (await fetch(source)).blob();
}
return Promise.reject(new Error("Error parsing image"));
}
return Promise.resolve(source);
}
export async function toLocalURL(source) {
if (typeof source === "string") {
if (source.startsWith("blob:")) {
return Promise.resolve(source);
}
if (isURL(source)) {
return blobLikeToBase64(await toBlobLike(source));
}
if (isBase64WithScheme(source, "image/")) {
return Promise.resolve(source);
}
return Promise.reject(new Error("Error parsing image"));
}
return blobLikeToBase64(source);
}
export async function toImageTag(src) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onerror = (e) => {
reject(e);
};
image.onload = () => {
resolve(image);
};
image.src = src;
});
}
export function unwrap(value, srcAt) {
if (!(value && srcAt)) {
return value;
}
switch (typeof srcAt) {
case "string":
return at(value, srcAt)[0];
case "function":
return srcAt(value);
case "symbol":
if (isPlainObject(value)) {
return value[srcAt];
}
}
}
const isPositiveNumber = (number) => typeof number === "number" && !Number.isNaN(number) && number > 0;
export function handleNumericalProp({
config,
labelTip,
createTitleTextOfNotMatched,
createTitleTextOfMinExceeded,
createTitleTextOfMaxExceeded,
withUnit = (value) => value.toLocaleString(),
getValue = (value) => value
}) {
const value = conclude(config, {
validator: (value2) => {
if (isPlainObject(value2)) {
const min2 = getValue(value2.min);
const max2 = getValue(value2.max);
const minIsValid = isPositiveNumber(min2);
const maxIsValid = isPositiveNumber(max2);
return minIsValid && maxIsValid && min2 < max2 || minIsValid && max2 === void 0 || min2 === void 0 && maxIsValid || min2 === void 0 && max2 === void 0;
} else if (Array.isArray(value2)) {
for (const v of value2) {
if (!isPositiveNumber(getValue(v))) {
return false;
}
}
return value2.length > 0;
} else {
return isPositiveNumber(getValue(value2));
}
}
});
let tip;
let titleTextOfNotMatched;
let titleTextOfMinExceeded;
let titleTextOfMaxExceeded;
let min;
let minLabel;
let max;
let maxLabel;
let options;
let optionsLabel;
let target;
let targetLabel;
if (isPlainObject(value)) {
min = getValue(value.min);
max = getValue(value.max);
if (min && max) {
minLabel = withUnit(value.min);
maxLabel = withUnit(value.max);
tip = `${labelTip} ${minLabel} ~ ${maxLabel}`;
titleTextOfMinExceeded = createTitleTextOfMinExceeded(minLabel);
titleTextOfMaxExceeded = createTitleTextOfMaxExceeded(maxLabel);
} else if (max) {
maxLabel = withUnit(value.max);
tip = `${labelTip} \u2264 ${maxLabel}`;
titleTextOfMaxExceeded = createTitleTextOfMaxExceeded(maxLabel);
} else if (min) {
minLabel = withUnit(value.min);
tip = `${labelTip} \u2265 ${minLabel}`;
titleTextOfMinExceeded = createTitleTextOfMinExceeded(minLabel);
}
} else if (Array.isArray(value)) {
options = value.map(getValue);
optionsLabel = value.map(withUnit).join(" / ");
tip = `${labelTip} ${optionsLabel}`;
titleTextOfNotMatched = createTitleTextOfNotMatched(optionsLabel);
} else if (value !== void 0) {
target = getValue(value);
targetLabel = withUnit(value);
tip = `${labelTip} ${targetLabel}`;
titleTextOfNotMatched = createTitleTextOfNotMatched(targetLabel);
}
function validate(v) {
let titleText;
if (max && v > max) {
titleText = titleTextOfMaxExceeded;
} else if (min && v < min) {
titleText = titleTextOfMinExceeded;
} else if (options && !options.includes(v)) {
titleText = titleTextOfNotMatched;
} else if (target && v !== target) {
titleText = titleTextOfNotMatched;
}
if (titleText) {
FaMessageBox.warning({
titleText,
timer: 5e3
});
}
return !titleText;
}
return { tip, validate, min, minLabel, max, maxLabel, options, optionsLabel, target, targetLabel };
}
export function getVideoMetadata(source) {
const url = source instanceof Blob ? URL.createObjectURL(source) : source;
return new Promise((resolve, reject) => {
const video = document.createElement("video");
video.addEventListener("error", (e) => {
reject(e);
});
video.addEventListener("loadedmetadata", () => {
if (source instanceof Blob) {
URL.revokeObjectURL(url);
}
resolve(video);
});
video.src = url;
});
}
export function getAudioMetadata(source) {
const url = source instanceof Blob ? URL.createObjectURL(source) : source;
return new Promise((resolve, reject) => {
const audio = document.createElement("audio");
audio.addEventListener("error", (e) => {
reject(e);
});
audio.addEventListener("loadedmetadata", () => {
if (source instanceof Blob) {
URL.revokeObjectURL(url);
}
resolve(audio);
});
audio.src = url;
});
}
export function secondsToHHMMSS(seconds) {
let Seconds = Number.parseInt(String(seconds), 10);
const Hours = Math.floor(Seconds / 3600);
const Minutes = Math.floor(Seconds / 60) % 60;
Seconds %= 60;
return [Hours, Minutes, Seconds].map((v) => v < 10 ? `0${v}` : v).filter((v, i) => v !== "00" || i > 0).join(":");
}
export function sizeToLabel(bytes) {
if (bytes >= MB) {
return `${Number.parseFloat((bytes / MB).toFixed(1))}M`;
} else if (bytes >= KB) {
return `${(bytes / KB).toFixed(0)}K`;
} else {
return `${bytes.toFixed(0)}B`;
}
}
export function getOrigin(url) {
if (url.startsWith("//")) {
return `//${new URL(window.location.protocol + url).host}`;
} else if (!url.startsWith("http")) {
return new URL(`${window.location.protocol}//${url}`).host;
}
const urlObj = new URL(url);
return `${urlObj.protocol}//${urlObj.host}`;
}
export async function fileToBlob(file) {
return file instanceof File ? new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onerror = (e) => {
reject(e);
};
fileReader.onload = (e) => {
resolve(e.target?.result ? new Blob([e.target.result], { type: file.type }) : null);
};
fileReader.readAsArrayBuffer(file);
}) : Promise.resolve(file);
}
export async function blobLikeToArrayBuffer(blobLike) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onerror = (e) => {
reject(e);
};
fileReader.onload = (e) => {
resolve(e.target?.result);
};
fileReader.readAsArrayBuffer(blobLike);
});
}
export function blobToFile(blob, fileName, fileType) {
if (!fileName) {
const extension = blob.type.split("/")[1];
fileName = `${(/* @__PURE__ */ new Date()).getTime().toString()}.${extension}`;
}
return blob instanceof File ? blob : new File([blob], fileName, { type: fileType || blob.type });
}