trilium/src/public/javascripts/services/utils.js

273 lines
6.3 KiB
JavaScript
Raw Normal View History

function reloadApp() {
window.location.reload(true);
}
function parseDate(str) {
try {
return new Date(Date.parse(str));
2018-03-25 11:37:55 +08:00
}
catch (e) {
throw new Error("Can't parse date from " + str + ": " + e.stack);
2018-03-25 11:37:55 +08:00
}
}
2018-03-25 11:37:55 +08:00
function padNum(num) {
return (num <= 9 ? "0" : "") + num;
}
2018-03-25 11:37:55 +08:00
function formatTime(date) {
return padNum(date.getHours()) + ":" + padNum(date.getMinutes());
}
2018-03-25 11:37:55 +08:00
function formatTimeWithSeconds(date) {
return padNum(date.getHours()) + ":" + padNum(date.getMinutes()) + ":" + padNum(date.getSeconds());
}
// this is producing local time!
function formatDate(date) {
// return padNum(date.getDate()) + ". " + padNum(date.getMonth() + 1) + ". " + date.getFullYear();
// instead of european format we'll just use ISO as that's pretty unambiguous
return formatDateISO(date);
}
// this is producing local time!
function formatDateISO(date) {
return date.getFullYear() + "-" + padNum(date.getMonth() + 1) + "-" + padNum(date.getDate());
}
function formatDateTime(date) {
return formatDate(date) + " " + formatTime(date);
}
function now() {
return formatTimeWithSeconds(new Date());
}
function isElectron() {
2019-02-10 02:25:55 +08:00
return !!(window && window.process && window.process.type);
}
function isMac() {
return navigator.platform.indexOf('Mac') > -1;
}
function assertArguments() {
for (const i in arguments) {
if (!arguments[i]) {
console.trace(`Argument idx#${i} should not be falsy: ${arguments[i]}`);
2018-03-25 11:37:55 +08:00
}
}
}
function escapeHtml(str) {
return $('<div/>').text(str).html();
}
2018-03-25 11:37:55 +08:00
async function stopWatch(what, func) {
const start = new Date();
2018-03-25 11:37:55 +08:00
const ret = await func();
2018-02-05 09:23:30 +08:00
2019-02-10 23:36:25 +08:00
const tookMs = Date.now() - start.getTime();
2018-02-05 09:23:30 +08:00
console.log(`${what} took ${tookMs}ms`);
2018-02-05 09:23:30 +08:00
return ret;
}
function formatValueWithWhitespace(val) {
return /[^\w_-]/.test(val) ? '"' + val + '"' : val;
}
function formatLabel(label) {
let str = "@" + formatValueWithWhitespace(label.name);
2018-03-25 11:37:55 +08:00
if (label.value !== "") {
str += "=" + formatValueWithWhitespace(label.value);
}
return str;
}
function getHost() {
const url = new URL(window.location.href);
return url.protocol + "//" + url.hostname + ":" + url.port;
}
2018-02-25 23:55:21 +08:00
function download(url) {
2019-11-09 20:01:05 +08:00
url += '?' + Date.now(); // don't use cache
if (isElectron()) {
const remote = require('electron').remote;
2018-02-25 23:55:21 +08:00
remote.getCurrentWebContents().downloadURL(url);
2018-02-25 23:55:21 +08:00
}
else {
window.location.href = url;
}
}
function toObject(array, fn) {
const obj = {};
for (const item of array) {
2018-03-26 11:25:17 +08:00
const [key, value] = fn(item);
2018-03-25 11:37:55 +08:00
2018-03-26 11:25:17 +08:00
obj[key] = value;
}
return obj;
}
function randomString(len) {
let text = "";
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < len; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
function bindGlobalShortcut(keyboardShortcut, handler) {
bindElShortcut($(document), keyboardShortcut, handler);
}
function bindElShortcut($el, keyboardShortcut, handler) {
2018-12-25 01:39:31 +08:00
if (isDesktop()) {
keyboardShortcut = normalizeShortcut(keyboardShortcut);
$el.bind('keydown', keyboardShortcut, e => {
2019-08-26 03:55:36 +08:00
handler(e);
2018-12-25 01:39:31 +08:00
e.preventDefault();
2019-08-26 03:55:36 +08:00
e.stopPropagation();
2018-12-25 01:39:31 +08:00
});
}
}
/**
* Normalize to the form expected by the jquery.hotkeys.js
*/
function normalizeShortcut(shortcut) {
return shortcut
.toLowerCase()
.replace("enter", "return")
.replace("delete", "del")
.replace("ctrl+alt", "alt+ctrl")
.replace("meta+alt", "alt+meta"); // alt needs to be first;
}
function isMobile() {
2019-01-15 06:50:45 +08:00
return window.device === "mobile"
// window.device is not available in setup
|| (!window.device && /Mobi/.test(navigator.userAgent));
}
function isDesktop() {
2019-01-15 06:50:45 +08:00
return window.device === "desktop"
// window.device is not available in setup
|| (!window.device && !/Mobi/.test(navigator.userAgent));
}
// cookie code below works for simple use cases only - ASCII only
// not setting path so that cookies do not leak into other websites if multiplexed with reverse proxy
2018-12-29 07:09:16 +08:00
function setCookie(name, value) {
const date = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
const expires = "; expires=" + date.toUTCString();
document.cookie = name + "=" + (value || "") + expires + ";";
}
function setSessionCookie(name, value) {
document.cookie = name + "=" + (value || "") + ";";
}
function getCookie(name) {
const valueMatch = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return valueMatch ? valueMatch[2] : null;
2018-12-29 07:09:16 +08:00
}
function getNoteTypeClass(type) {
return "type-" + type;
}
function getMimeTypeClass(mime) {
const semicolonIdx = mime.indexOf(';');
if (semicolonIdx !== -1) {
// stripping everything following the semicolon
mime = mime.substr(0, semicolonIdx);
}
return 'mime-' + mime.toLowerCase().replace(/[\W_]+/g,"-");
}
function closeActiveDialog() {
if (glob.activeDialog) {
glob.activeDialog.modal('hide');
}
}
function isHtmlEmpty(html) {
2019-10-06 17:21:12 +08:00
return $("<div>").html(html).text().trim().length === 0 && !html.toLowerCase().includes('<img');
}
2019-11-09 06:09:57 +08:00
async function clearBrowserCache() {
if (isElectron()) {
const win = require('electron').remote.getCurrentWindow();
await win.webContents.session.clearCache();
}
}
/**
* @param url - should be without initial slash!!!
*/
function getUrlForDownload(url) {
if (isElectron()) {
// electron needs absolute URL so we extract current host, port, protocol
return getHost() + '/' + url;
}
else {
// web server can be deployed on subdomain so we need to use relative path
return url;
}
}
export default {
reloadApp,
parseDate,
padNum,
formatTime,
formatTimeWithSeconds,
formatDate,
formatDateISO,
formatDateTime,
now,
isElectron,
isMac,
assertArguments,
escapeHtml,
stopWatch,
formatLabel,
download,
toObject,
randomString,
bindGlobalShortcut,
bindElShortcut,
isMobile,
2018-12-29 07:09:16 +08:00
isDesktop,
setCookie,
setSessionCookie,
getCookie,
getNoteTypeClass,
getMimeTypeClass,
closeActiveDialog,
2019-11-09 06:09:57 +08:00
isHtmlEmpty,
clearBrowserCache,
getUrlForDownload,
normalizeShortcut
};