fox-send/app/utils.js

201 lines
4.5 KiB
JavaScript
Raw Normal View History

const b64 = require('base64-js');
function arrayToB64(array) {
return b64
.fromByteArray(array)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
2017-06-02 03:59:27 +00:00
}
function b64ToArray(str) {
str = (str + '==='.slice((str.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/');
return b64.toByteArray(str);
2017-06-02 03:59:27 +00:00
}
function loadShim(polyfill) {
return new Promise((resolve, reject) => {
const shim = document.createElement('script');
shim.src = polyfill;
shim.addEventListener('load', () => resolve(true));
shim.addEventListener('error', () => resolve(false));
document.head.appendChild(shim);
});
}
async function canHasSend(polyfill) {
try {
const key = await window.crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 128
},
true,
['encrypt', 'decrypt']
);
await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: window.crypto.getRandomValues(new Uint8Array(12)),
tagLength: 128
},
key,
new ArrayBuffer(8)
);
return true;
2017-07-12 17:53:29 +00:00
} catch (err) {
return loadShim(polyfill);
}
}
function isFile(id) {
return /^[0-9a-fA-F]{10}$/.test(id);
}
2017-08-04 03:13:17 +00:00
function copyToClipboard(str) {
const aux = document.createElement('input');
aux.setAttribute('value', str);
aux.contentEditable = true;
aux.readOnly = true;
document.body.appendChild(aux);
if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {
const range = document.createRange();
range.selectNodeContents(aux);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
aux.setSelectionRange(0, str.length);
} else {
2017-08-04 03:13:17 +00:00
aux.select();
}
const result = document.execCommand('copy');
2017-08-04 03:13:17 +00:00
document.body.removeChild(aux);
return result;
2017-08-04 03:13:17 +00:00
}
2017-08-06 01:06:43 +00:00
const LOCALIZE_NUMBERS = !!(
typeof Intl === 'object' &&
Intl &&
typeof Intl.NumberFormat === 'function' &&
typeof navigator === 'object'
2017-08-06 01:06:43 +00:00
);
const UNITS = ['B', 'kB', 'MB', 'GB'];
function bytes(num) {
if (num < 1) {
return '0B';
}
2017-08-06 01:06:43 +00:00
const exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1);
const n = Number(num / Math.pow(1000, exponent));
2017-11-09 21:58:20 +00:00
let nStr = n.toFixed(1);
if (LOCALIZE_NUMBERS) {
try {
const locale = document.querySelector('html').lang;
nStr = n.toLocaleString(locale, {
2017-08-06 01:06:43 +00:00
minimumFractionDigits: 1,
maximumFractionDigits: 1
2017-11-09 21:58:20 +00:00
});
} catch (e) {
// fall through
}
}
2017-08-06 01:06:43 +00:00
return `${nStr}${UNITS[exponent]}`;
}
function percent(ratio) {
2017-11-09 21:58:20 +00:00
if (LOCALIZE_NUMBERS) {
try {
const locale = document.querySelector('html').lang;
return ratio.toLocaleString(locale, { style: 'percent' });
2017-11-09 21:58:20 +00:00
} catch (e) {
// fall through
}
}
return `${Math.floor(ratio * 100)}%`;
}
2018-02-08 03:46:18 +00:00
function number(n) {
if (LOCALIZE_NUMBERS) {
const locale = document.querySelector('html').lang;
return n.toLocaleString(locale);
}
return n.toString();
}
2017-08-11 02:01:39 +00:00
function allowedCopy() {
const support = !!document.queryCommandSupported;
return support ? document.queryCommandSupported('copy') : false;
}
function delay(delay = 100) {
return new Promise(resolve => setTimeout(resolve, delay));
}
function fadeOut(id) {
const classes = document.getElementById(id).classList;
classes.remove('fadeIn');
classes.add('fadeOut');
return delay(300);
}
2018-01-24 18:23:13 +00:00
function saveFile(file) {
const reader = new FileReader();
2018-01-24 18:23:13 +00:00
const dataView = new DataView(file.plaintext);
const blob = new Blob([dataView], { type: file.type });
if (window.navigator.msSaveBlob) {
return window.navigator.msSaveBlob(blob, file.name);
}
reader.addEventListener('loadend', function() {
if (reader.result) {
const a = document.createElement('a');
a.href = reader.result;
a.download = file.name;
document.body.appendChild(a);
a.click();
return;
}
if (reader.error) {
console.error(reader.error);
window.location.href = '/error';
//TODO
}
});
reader.readAsDataURL(blob);
2018-01-24 18:23:13 +00:00
}
function openLinksInNewTab(links, should = true) {
links = links || Array.from(document.querySelectorAll('a:not([target])'));
if (should) {
links.forEach(l => {
l.setAttribute('target', '_blank');
l.setAttribute('rel', 'noopener noreferrer');
});
} else {
links.forEach(l => {
l.removeAttribute('target');
l.removeAttribute('rel');
});
}
return links;
}
module.exports = {
fadeOut,
delay,
2017-08-11 02:01:39 +00:00
allowedCopy,
2017-08-06 01:06:43 +00:00
bytes,
percent,
2018-02-08 03:46:18 +00:00
number,
2017-08-04 03:13:17 +00:00
copyToClipboard,
arrayToB64,
b64ToArray,
canHasSend,
isFile,
2018-01-24 18:23:13 +00:00
saveFile,
openLinksInNewTab
2017-06-02 03:59:27 +00:00
};