|
export const regexpEscape = str => { |
|
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") |
|
} |
|
|
|
export const htmlEscape = str => { |
|
return str.replace(/[&<>"]/g, c => { |
|
switch (c) { |
|
case "&": return "&" |
|
case "<": return "<" |
|
case ">": return ">" |
|
case "\x22": return """ |
|
} |
|
}) |
|
} |
|
|
|
export const htmlUnescape = str => { |
|
return str.replace(/&|<|>|"/g, m => { |
|
switch (m) { |
|
case "&": return "&" |
|
case "<": return "<" |
|
case ">": return ">" |
|
case """: return "\x22" |
|
} |
|
}) |
|
} |
|
|
|
export const arrayShuffle = array => { |
|
for (let i = 0, l = array.length; i < l; i++) { |
|
const j = ~~(Math.random() * l) |
|
const t = array[i] |
|
array[i] = array[j] |
|
array[j] = t |
|
} |
|
return array |
|
} |
|
|
|
export const arraySortBy = (array, ...bys) => { |
|
const compare = (a, b) => (a === b ? 0 : a < b ? -1 : 1) |
|
return array.sort((a, b) => { |
|
if (bys.length === 0) { |
|
return compare(a, b) |
|
} |
|
for (const by of bys) { |
|
const result = typeof by === "function" ? compare(by(a), by(b)) : compare(a[by], b[by]) |
|
if (result) return result |
|
} |
|
return 0 |
|
}) |
|
} |
|
|
|
export const stringSplit = (str, by, len) => { |
|
len = ~~len |
|
if (len <= 0) return [] |
|
if (by === "") { |
|
const result = [] |
|
let j = 0 |
|
for (let i = 0; i < len - 1; i++) { |
|
const code = str.codePointAt(i) |
|
if (code === undefined) { |
|
break |
|
} |
|
result.push(String.fromCodePoint(code)) |
|
j += code > 65535 ? 2 : 1 |
|
} |
|
if (str.length > j) { |
|
result.push(str.slice(j)) |
|
} |
|
return result |
|
} else { |
|
const result = [] |
|
let pre_index = 0 |
|
for (let i = 0; i < len - 1; i++) { |
|
const index = str.indexOf(by, pre_index) |
|
if (index === -1) { |
|
break |
|
} |
|
result.push(str.slice(pre_index, index)) |
|
pre_index = index + by.length |
|
} |
|
result.push(str.slice(pre_index)) |
|
return result |
|
} |
|
} |
|
|
|
export const dateFormat = (format, date) => { |
|
date = date == null ? new Date() : new Date(date) |
|
|
|
return String(format).replace(/%./g, m => { |
|
switch (m[1]) { |
|
case "d": return String(date.getDate()).padStart(2, "0") |
|
case "H": return String(date.getHours()).padStart(2, "0") |
|
case "I": return String(date.getHours() % 12).padStart(2, "0") |
|
case "m": return String(date.getMonth() + 1).padStart(2, "0") |
|
case "M": return String(date.getMinutes()).padStart(2, "0") |
|
case "p": return date.getHours() >= 12 ? "PM" : "AM" |
|
case "s": return String(date.getMilliseconds()).padStart(3, "0") |
|
case "S": return String(date.getSeconds()).padStart(2, "0") |
|
case "w": return String(date.getDay()) |
|
case "y": return String(date.getFullYear()).slice(2) |
|
case "Y": return String(date.getFullYear()) |
|
default: |
|
return m[1] |
|
} |
|
}) |
|
} |
|
|
|
export const jsonEquals = (a, b) => { |
|
const format = x => { |
|
if (x && typeof x === "object") { |
|
if (Array.isArray(x)) { |
|
return x.map(format) |
|
} else { |
|
const entries = Object.entries(x) |
|
.sort((a, b) => a[0].localeCompare(b[0])) |
|
.map(e => [e[0], format(e[1])]) |
|
return { entries } |
|
} |
|
} else { |
|
return x |
|
} |
|
} |
|
return JSON.stringify(format(a)) === JSON.stringify(format(b)) |
|
} |