dispatch/client/js/utils/index.js
2019-01-30 04:48:37 +01:00

207 lines
4.1 KiB
JavaScript

import padStart from 'lodash/padStart';
export { findBreakpoints, messageHeight } from './messageHeight';
export { default as linkify } from './linkify';
export function normalizeChannel(channel) {
if (channel.indexOf('#') !== 0) {
return channel;
}
return channel
.split('#')
.join('')
.toLowerCase();
}
export function isChannel(name) {
// TODO: Handle other channel types
if (typeof name === 'object') {
({ name } = name);
}
return typeof name === 'string' && name[0] === '#';
}
export function stringifyTab(server, name) {
if (typeof server === 'object') {
if (server.name) {
return `${server.server};${server.name}`;
}
return server.server;
}
if (name) {
return `${server};${name}`;
}
return server;
}
function isString(s, maxLength) {
if (!s || typeof s !== 'string') {
return false;
}
if (maxLength && s.length > maxLength) {
return false;
}
return true;
}
// RFC 2812
// nickname = ( letter / special ) *( letter / digit / special / "-" )
// letter = A-Z / a-z
// digit = 0-9
// special = "[", "]", "\", "`", "_", "^", "{", "|", "}"
export function isValidNick(nick, maxLength = 30) {
if (!isString(nick, maxLength)) {
return false;
}
for (let i = 0; i < nick.length; i++) {
const char = nick.charCodeAt(i);
if (
(i > 0 && char < 45) ||
(char > 45 && char < 48) ||
(char > 57 && char < 65) ||
char > 125
) {
return false;
}
if ((i === 0 && char < 65) || char > 125) {
return false;
}
}
return true;
}
// chanstring = any octet except NUL, BELL, CR, LF, " ", "," and ":"
export function isValidChannel(channel, requirePrefix = true) {
if (!isString(channel)) {
return false;
}
if (requirePrefix && channel[0] !== '#') {
return false;
}
for (let i = 0; i < channel.length; i++) {
const char = channel.charCodeAt(i);
if (
char === 0 ||
char === 7 ||
char === 10 ||
char === 13 ||
char === 32 ||
char === 44 ||
char === 58
) {
return false;
}
}
return true;
}
// user = any octet except NUL, CR, LF, " " and "@"
export function isValidUsername(username) {
if (!isString(username)) {
return false;
}
for (let i = 0; i < username.length; i++) {
const char = username.charCodeAt(i);
if (
char === 0 ||
char === 10 ||
char === 13 ||
char === 32 ||
char === 64
) {
return false;
}
}
return true;
}
export function isInt(i, min, max) {
if (i < min || i > max || Math.floor(i) !== i) {
return false;
}
return true;
}
export function timestamp(date = new Date()) {
const h = padStart(date.getHours(), 2, '0');
const m = padStart(date.getMinutes(), 2, '0');
return `${h}:${m}`;
}
const dateFmt = new Intl.DateTimeFormat(window.navigator.language);
export const formatDate = dateFmt.format;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
export function stringWidth(str, font) {
ctx.font = font;
return ctx.measureText(str).width;
}
export function measureScrollBarWidth() {
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.width = '100px';
document.body.appendChild(outer);
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
}
export function findIndex(arr, pred) {
if (!Array.isArray(arr) || typeof pred !== 'function') {
return -1;
}
for (let i = 0; i < arr.length; i++) {
if (pred(arr[i])) {
return i;
}
}
return -1;
}
export function find(arr, pred) {
const i = findIndex(arr, pred);
if (i !== -1) {
return arr[i];
}
return null;
}
export function count(arr, pred) {
if (!Array.isArray(arr) || typeof pred !== 'function') {
return 0;
}
let c = 0;
for (let i = 0; i < arr.length; i++) {
if (pred(arr[i])) {
c++;
}
}
return c;
}