@xlou/webtools
Version:
Frontend Development Tools
378 lines (374 loc) • 12.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.tools = factory());
})(this, (function () { 'use strict';
/* Transcoding and decoding of Base64 */
class Base64 {
constructor(key) {
if (key)
this.key = key;
}
key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
encode(input) {
let output = "";
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
let i = 0;
input = this.utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
}
else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + this.key.charAt(enc1) + this.key.charAt(enc2) + this.key.charAt(enc3) + this.key.charAt(enc4);
}
return output;
}
decode(input) {
let output = "";
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this.key.indexOf(input.charAt(i++));
enc2 = this.key.indexOf(input.charAt(i++));
enc3 = this.key.indexOf(input.charAt(i++));
enc4 = this.key.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this.utf8_decode(output).replace(/\u0000/g, "");
return output;
}
utf8_encode(str) {
str = str.replace(/\r\n/g, "\n");
let utftext = "";
for (let n = 0; n < str.length; n++) {
let c = str.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
utf8_decode(utftext) {
let str = "";
let i = 0;
let c = 0, c1 = 0, c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
str += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i + 1);
str += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
}
else {
c1 = utftext.charCodeAt(i + 1);
c2 = utftext.charCodeAt(i + 2);
str += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return str;
}
}
/* Deep copy of reference data types */
function deepCopy(obj, set = new Set()) {
if (typeof obj !== 'object' || obj === null)
return obj;
if (set.has(obj))
return obj; // 防止爆栈
set.add(obj);
let res;
switch (obj.constructor) {
case Array: {
res = [];
for (let item of obj) {
res.push(deepCopy(item, set));
}
break;
}
case Set: {
res = new Set();
obj.forEach(item => {
res.add(deepCopy(item, set));
});
break;
}
case Map: {
res = new Map();
obj.forEach((item, i) => {
res.set(deepCopy(i, set), deepCopy(item, set));
});
break;
}
default: {
res = {};
for (let i in obj) {
res[i] = deepCopy(obj[i], set);
}
}
}
return res;
}
/* Filter object properties and return a new object */
function filterObject(obj, str, bol) {
let res = {};
if (!str)
return Object.assign(res, obj);
let arr = str.split(",");
if (bol === undefined)
bol = true;
if (bol) {
for (let item of arr) {
item = item.trim();
obj[item] && (res[item] = obj[item]);
}
}
else {
Object.assign(res, obj);
for (let item of arr) {
delete res[item];
}
}
return res;
}
/* Convert URL parameters to an object */
function getQuery(href = window.location.href) {
let qobj = {};
let start = href.indexOf("?");
if (start === -1)
return qobj;
let end = href.indexOf("#");
if (end === -1 || start > end) {
end = undefined;
}
let search = href.slice(start + 1, end);
if (search === "")
return qobj;
let qarr = search.split("&");
for (let item of qarr) {
if (!item)
continue;
let itemarr = item.split("=");
qobj[decodeURIComponent(itemarr[0])] = decodeURIComponent((itemarr[1] || ""));
}
return qobj;
}
/* Convert an object to URL parameters */
function queryString(obj, bol = false) {
let arr = [];
for (let i in obj) {
if (obj[i] === null || obj[i] === undefined)
obj[i] = "";
arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]));
}
let str = arr.join('&');
return (str && bol) ? '?' + str : str;
}
/* Round to a specified number of decimal places */
function toFixed(num, s) {
if (num === undefined) { // First argument is undefined
return undefined;
}
let numn = Number(num);
if (isNaN(numn)) { // First argument is not a number
throw "argument for toFixed error";
}
if (numn > Math.pow(10, 21)) { // First argument is too large
return String(numn);
}
let sn = Number(s);
if (s === undefined || sn == 0) { // No second argument or second argument can be converted to 0
return String(Math.round(numn));
}
if (isNaN(sn)) { // Second argument is not a number
throw "The argument of C.toFixed must be a number";
}
if (sn > 20 || sn < 0) { // Second argument out of range
throw "The second argument of C.toFixed must be between 0 and 20";
}
let nums = String(numn);
let numarr = nums.split(".");
if (numarr.length < 2) {
nums += ".";
for (let i = 0; i < sn; i++) {
nums += "0";
}
return nums;
}
let int = numarr[0];
let dec = numarr[1];
if (dec.length == sn) {
return nums;
}
if (dec.length < sn) {
for (let i = 0; i < sn - dec.length; i++) {
nums += "0";
}
return nums;
}
nums = int + "." + dec.slice(0, sn);
let last = dec.slice(sn, sn + 1);
if (parseInt(last, 10) >= 5) {
let x = 10 ** sn;
nums = ((parseFloat(nums) * x) + 1) / x;
nums = nums.toFixed(sn);
}
return nums;
}
/* Simulate form submission, often used for POST downloading files */
function formSubmit(obj) {
const { document } = window;
const form = document.createElement("form");
const { data } = obj;
delete obj.data;
for (let i in obj) {
obj[i] && (form[i] = obj[i]);
}
form.style.display = "none";
for (let i in data) {
const input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", i);
input.value = data[i];
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
}
/* Read text file */
function readText(url) {
return new Promise((res, rej) => {
const xhr = new XMLHttpRequest();
xhr.onload = e => {
res(xhr.response);
};
xhr.onerror = e => {
rej(e);
};
xhr.open('GET', url, true);
xhr.send();
});
}
/* Read JSON file */
function readJSON(url) {
return new Promise((res, rej) => {
const xhr = new XMLHttpRequest();
xhr.onload = e => {
res(JSON.parse(xhr.response));
};
xhr.onerror = e => {
rej(e);
};
xhr.open('GET', url, true);
xhr.send();
});
}
function getStore(str) {
let storage = localStorage.getItem(str);
if (typeof storage === "string") {
try {
storage = JSON.parse(storage);
}
catch (e) { }
}
return storage;
}
function setStore(str, data) {
if (typeof data === 'object' && data !== null) {
try {
data = JSON.stringify(data);
}
catch (err) { }
}
localStorage.setItem(str, data);
}
function unid() {
return Math.floor(Math.random() * 10e13).toString(36) + Date.now().toString(36);
}
function colorRGB(str) {
const reg16 = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
const regRGB = /^(rgb\(|RGB\()[\s\S]+\)/;
let co = str.toLowerCase();
let res = [];
if (reg16.test(co)) {
if (co.length === 4) {
let conew = "#";
for (let i = 1; i < 4; i += 1) {
conew += co.slice(i, i + 1).concat(co.slice(i, i + 1));
}
co = conew;
}
for (let i = 1; i < 7; i += 2) {
res.push(parseInt("0x" + co.slice(i, i + 2)));
}
return res;
}
if (regRGB.test(co)) {
res = co.replace(/( |\(|\)|rgb|RGB)+/g, "").split(",");
return res.map(Number);
}
}
function clipboardWrite(content, type = "text/plain") {
let ci = null;
if (Object.prototype.toString.call(content) === "[object Blob]") {
ci = new ClipboardItem({ [type]: content });
}
else if (Array.isArray(content)) {
ci = new ClipboardItem({ [type]: new Blob(content, { type }) });
}
else {
ci = new ClipboardItem({ [type]: new Blob([content], { type }) });
}
return navigator.clipboard.write([ci]);
}
var webtools = {
Base64,
deepCopy,
filterObject,
getQuery,
queryString,
toFixed,
formSubmit,
readText,
readJSON,
getStore,
setStore,
unid,
colorRGB,
clipboardWrite
};
return webtools;
}));