snappymail/dev/Common/Utils.js

727 lines
16 KiB
JavaScript
Raw Normal View History

import { ComposeType, SaveSettingsStep, FolderType } from 'Common/Enums';
2016-06-07 05:57:52 +08:00
2020-08-07 22:28:30 +08:00
const
doc = document,
2020-09-22 20:23:31 +08:00
tpl = doc.createElement('template'),
isArray = Array.isArray,
htmlmap = {
'&': '&',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
},
htmlspecialchars = str => (''+str).replace(/[&<>"']/g, m => htmlmap[m]);
2016-06-07 05:57:52 +08:00
/**
* @param {(string|number)} value
* @param {boolean=} includeZero = true
2016-06-30 08:02:45 +08:00
* @returns {boolean}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function isPosNumeric(value, includeZero = true) {
return null != value && (includeZero ? /^[0-9]*$/ : /^[1-9]+[0-9]*$/).test(value.toString());
2016-06-07 05:57:52 +08:00
}
/**
* @param {*} value
* @param {number=} defaultValue = 0
2016-06-30 08:02:45 +08:00
* @returns {number}
2016-06-07 05:57:52 +08:00
*/
export function pInt(value, defaultValue = 0) {
value = parseInt(value, 10);
return isNaN(value) || !isFinite(value) ? defaultValue : value;
2016-06-07 05:57:52 +08:00
}
/**
* @param {*} value
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function pString(value) {
return null != value ? '' + value : '';
2016-06-07 05:57:52 +08:00
}
/**
* @param {string} text
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function encodeHtml(text) {
return null != text ? htmlspecialchars(text.toString()) : '';
2016-06-07 05:57:52 +08:00
}
/**
* @param {string} text
* @param {number=} len = 100
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
function splitPlainText(text, len = 100) {
2019-07-05 03:19:24 +08:00
let prefix = '',
2016-06-07 05:57:52 +08:00
subText = '',
result = text,
spacePos = 0,
2016-06-30 08:02:45 +08:00
newLinePos = 0;
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
while (result.length > len) {
subText = result.substr(0, len);
2016-06-07 05:57:52 +08:00
spacePos = subText.lastIndexOf(' ');
newLinePos = subText.lastIndexOf('\n');
2019-07-05 03:19:24 +08:00
if (-1 !== newLinePos) {
2016-06-07 05:57:52 +08:00
spacePos = newLinePos;
}
2019-07-05 03:19:24 +08:00
if (-1 === spacePos) {
2016-06-07 05:57:52 +08:00
spacePos = len;
}
prefix += subText.substr(0, spacePos) + '\n';
result = result.substr(spacePos + 1);
2016-06-07 05:57:52 +08:00
}
return prefix + result;
}
2019-03-28 06:01:26 +08:00
/**
* @param {any} m
* @returns {any}
*/
export function deModule(m) {
return (m && m.default ? m.default : m) || '';
}
2016-06-07 05:57:52 +08:00
/**
2016-06-30 08:02:45 +08:00
* @returns {boolean}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function inFocus() {
try {
if (doc.activeElement) {
if (undefined === doc.activeElement.__inFocusCache) {
2020-08-27 21:45:47 +08:00
doc.activeElement.__inFocusCache = doc.activeElement.matches(
2019-07-05 03:19:24 +08:00
'input,textarea,iframe,.cke_editable'
);
}
2016-06-07 05:57:52 +08:00
return !!doc.activeElement.__inFocusCache;
}
2019-07-05 03:19:24 +08:00
} catch (e) {} // eslint-disable-line no-empty
2016-06-07 05:57:52 +08:00
return false;
}
/**
* @param {(number|string)} sizeInBytes
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function friendlySize(sizeInBytes) {
2016-06-07 05:57:52 +08:00
sizeInBytes = pInt(sizeInBytes);
const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB'], i = pInt(Math.floor(Math.log(sizeInBytes) / Math.log(1024)));
return (sizeInBytes / Math.pow(1024, i)).toFixed(2>i ? 0 : 1) + sizes[i];
2016-06-07 05:57:52 +08:00
}
/**
* @param {string} theme
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
export const convertThemeName = theme => {
2019-07-05 03:19:24 +08:00
if ('@custom' === theme.substr(-7)) {
theme = theme.substr(0, theme.length - 7).trim();
2016-06-07 05:57:52 +08:00
}
return theme
.replace(/[^a-zA-Z0-9]+/g, ' ')
.replace(/([A-Z])/g, ' $1')
.replace(/\s+/g, ' ')
.trim();
};
2016-06-07 05:57:52 +08:00
/**
*
* @param {string} language
* @param {boolean=} isEng = false
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function convertLangName(language, isEng = false) {
return require('Common/Translator').i18n(
'LANGS_NAMES' + (true === isEng ? '_EN' : '') + '/LANG_' + language.toUpperCase().replace(/[^a-zA-Z0-9]+/g, '_'),
null,
language
);
2016-06-07 05:57:52 +08:00
}
2016-06-30 08:02:45 +08:00
/**
* @param {object} domOption
* @param {object} item
* @returns {void}
*/
2019-07-05 03:19:24 +08:00
export function defautOptionsAfterRender(domItem, item) {
if (item && undefined !== item.disabled && domItem) {
domItem.classList.toggle('disabled', domItem.disabled = item.disabled);
2016-06-07 05:57:52 +08:00
}
}
2016-06-30 08:02:45 +08:00
/**
* @param {object} koTrigger
* @param {mixed} context
* @returns {mixed}
*/
2019-07-05 03:19:24 +08:00
export function settingsSaveHelperSimpleFunction(koTrigger, context) {
return (type, data) => {
koTrigger.call(context, data && data.Result ? SaveSettingsStep.TrueResult : SaveSettingsStep.FalseResult);
setTimeout(() => koTrigger.call(context, SaveSettingsStep.Idle), 1000);
2016-06-07 05:57:52 +08:00
};
}
/**
* @param {string} html
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function htmlToPlain(html) {
let pos = 0,
limit = 0,
2016-06-07 05:57:52 +08:00
iP1 = 0,
iP2 = 0,
iP3 = 0,
2016-06-30 08:02:45 +08:00
text = '';
const convertBlockquote = (blockquoteText) => {
blockquoteText = '> ' + blockquoteText.trim().replace(/\n/gm, '\n> ');
2019-07-05 03:19:24 +08:00
return blockquoteText.replace(/(^|\n)([> ]+)/gm, (...args) =>
args && 2 < args.length ? args[1] + args[2].replace(/[\s]/g, '').trim() + ' ' : ''
2019-07-05 03:19:24 +08:00
);
};
2016-06-07 05:57:52 +08:00
const convertDivs = (...args) => {
2019-07-05 03:19:24 +08:00
if (args && 1 < args.length) {
let divText = args[1].trim();
if (divText.length) {
2019-07-05 03:19:24 +08:00
divText = divText.replace(/<div[^>]*>([\s\S\r\n]*)<\/div>/gim, convertDivs);
divText = '\n' + divText.trim() + '\n';
2016-06-07 05:57:52 +08:00
}
return divText;
}
return '';
};
2019-07-05 03:19:24 +08:00
const convertPre = (...args) =>
args && 1 < args.length
? args[1]
.toString()
.replace(/[\n]/gm, '<br />')
.replace(/[\r]/gm, '')
: '',
fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + htmlspecialchars(args[2]) : ''),
convertLinks = (...args) => (args && 1 < args.length ? args[1].trim() : '');
2016-06-07 05:57:52 +08:00
2020-08-27 21:45:47 +08:00
tpl.innerHTML = html
2016-06-07 05:57:52 +08:00
.replace(/<p[^>]*><\/p>/gi, '')
2019-07-05 03:19:24 +08:00
.replace(/<pre[^>]*>([\s\S\r\n\t]*)<\/pre>/gim, convertPre)
2016-06-07 05:57:52 +08:00
.replace(/[\s]+/gm, ' ')
2019-07-05 03:19:24 +08:00
.replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gim, fixAttibuteValue)
.replace(/<br[^>]*>/gim, '\n')
2016-06-07 05:57:52 +08:00
.replace(/<\/h[\d]>/gi, '\n')
.replace(/<\/p>/gi, '\n\n')
2019-07-05 03:19:24 +08:00
.replace(/<ul[^>]*>/gim, '\n')
2016-06-07 05:57:52 +08:00
.replace(/<\/ul>/gi, '\n')
2019-07-05 03:19:24 +08:00
.replace(/<li[^>]*>/gim, ' * ')
2016-06-07 05:57:52 +08:00
.replace(/<\/li>/gi, '\n')
.replace(/<\/td>/gi, '\n')
.replace(/<\/tr>/gi, '\n')
2019-07-05 03:19:24 +08:00
.replace(/<hr[^>]*>/gim, '\n_______________________________\n\n')
.replace(/<div[^>]*>([\s\S\r\n]*)<\/div>/gim, convertDivs)
.replace(/<blockquote[^>]*>/gim, '\n__bq__start__\n')
.replace(/<\/blockquote>/gim, '\n__bq__end__\n')
.replace(/<a [^>]*>([\s\S\r\n]*?)<\/a>/gim, convertLinks)
2016-06-07 05:57:52 +08:00
.replace(/<\/div>/gi, '\n')
.replace(/&nbsp;/gi, ' ')
2016-06-07 05:57:52 +08:00
.replace(/&quot;/gi, '"')
2016-06-30 08:02:45 +08:00
.replace(/<[^>]*>/gm, '');
2016-06-07 05:57:52 +08:00
2020-09-22 20:23:31 +08:00
text = splitPlainText(tpl.innerText
2016-06-07 05:57:52 +08:00
.replace(/\n[ \t]+/gm, '\n')
.replace(/[\n]{3,}/gm, '\n\n')
.replace(/&gt;/gi, '>')
.replace(/&lt;/gi, '<')
2020-08-27 21:45:47 +08:00
.replace(/&amp;/gi, '&')
);
2016-06-07 05:57:52 +08:00
pos = 0;
limit = 800;
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
while (0 < limit) {
--limit;
iP1 = text.indexOf('__bq__start__', pos);
2019-07-05 03:19:24 +08:00
if (-1 < iP1) {
2016-06-07 05:57:52 +08:00
iP2 = text.indexOf('__bq__start__', iP1 + 5);
iP3 = text.indexOf('__bq__end__', iP1 + 5);
2019-07-05 03:19:24 +08:00
if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3) {
text = text.substr(0, iP1) + convertBlockquote(text.substring(iP1 + 13, iP3)) + text.substr(iP3 + 11);
pos = 0;
2019-07-05 03:19:24 +08:00
} else if (-1 < iP2 && iP2 < iP3) {
pos = iP2 - 1;
2019-07-05 03:19:24 +08:00
} else {
pos = 0;
2016-06-07 05:57:52 +08:00
}
2019-07-05 03:19:24 +08:00
} else {
2016-06-07 05:57:52 +08:00
break;
}
}
return text.replace(/__bq__start__|__bq__end__/gm, '').trim();
2016-06-07 05:57:52 +08:00
}
/**
* @param {string} plain
* @param {boolean} findEmailAndLinksInText = false
2016-06-30 08:02:45 +08:00
* @returns {string}
2016-06-07 05:57:52 +08:00
*/
2020-08-27 21:45:47 +08:00
export function plainToHtml(plain) {
2016-06-07 05:57:52 +08:00
plain = plain.toString().replace(/\r/g, '');
2016-07-02 06:49:59 +08:00
plain = plain.replace(/^>[> ]>+/gm, ([match]) => (match ? match.replace(/[ ]+/g, '') : match));
2019-07-05 03:19:24 +08:00
let bIn = false,
2016-06-07 05:57:52 +08:00
bDo = true,
bStart = true,
aNextText = [],
2016-06-30 08:02:45 +08:00
aText = plain.split('\n');
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
do {
2016-06-07 05:57:52 +08:00
bDo = false;
aNextText = [];
aText.forEach(sLine => {
2016-06-07 05:57:52 +08:00
bStart = '>' === sLine.substr(0, 1);
2019-07-05 03:19:24 +08:00
if (bStart && !bIn) {
2016-06-07 05:57:52 +08:00
bDo = true;
bIn = true;
aNextText.push('~~~blockquote~~~');
aNextText.push(sLine.substr(1));
2019-07-05 03:19:24 +08:00
} else if (!bStart && bIn) {
if (sLine) {
2016-06-07 05:57:52 +08:00
bIn = false;
aNextText.push('~~~/blockquote~~~');
aNextText.push(sLine);
2019-07-05 03:19:24 +08:00
} else {
2016-06-07 05:57:52 +08:00
aNextText.push(sLine);
}
2019-07-05 03:19:24 +08:00
} else if (bStart && bIn) {
2016-06-07 05:57:52 +08:00
aNextText.push(sLine.substr(1));
2019-07-05 03:19:24 +08:00
} else {
2016-06-07 05:57:52 +08:00
aNextText.push(sLine);
}
});
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
if (bIn) {
2016-06-07 05:57:52 +08:00
bIn = false;
aNextText.push('~~~/blockquote~~~');
}
aText = aNextText;
2019-07-05 03:19:24 +08:00
} while (bDo);
2016-06-07 05:57:52 +08:00
2020-08-27 21:45:47 +08:00
return aText.join('\n')
// .replace(/~~~\/blockquote~~~\n~~~blockquote~~~/g, '\n')
2016-06-07 05:57:52 +08:00
.replace(/&/g, '&amp;')
2019-07-05 03:19:24 +08:00
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
2016-06-07 05:57:52 +08:00
.replace(/~~~blockquote~~~[\s]*/g, '<blockquote>')
.replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>')
2016-06-30 08:02:45 +08:00
.replace(/\n/g, '<br />');
2016-06-07 05:57:52 +08:00
}
rl.Utils = {
htmlToPlain: htmlToPlain,
plainToHtml: plainToHtml
};
2016-06-07 05:57:52 +08:00
/**
* @param {Array} aSystem
* @param {Array} aList
* @param {Array=} aDisabled
* @param {Array=} aHeaderLines
* @param {?number=} iUnDeep
* @param {Function=} fDisableCallback
* @param {Function=} fVisibleCallback
* @param {Function=} fRenameCallback
* @param {boolean=} bSystem
* @param {boolean=} bBuildUnvisible
2016-06-30 08:02:45 +08:00
* @returns {Array}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function folderListOptionsBuilder(
aSystem,
aList,
aDisabled,
aHeaderLines,
iUnDeep,
fDisableCallback,
fVisibleCallback,
fRenameCallback,
bSystem,
bBuildUnvisible
) {
let /**
2016-06-07 05:57:52 +08:00
* @type {?FolderModel}
*/
bSep = false,
2016-06-30 08:02:45 +08:00
aResult = [];
const sDeepPrefix = '\u00A0\u00A0\u00A0';
2016-06-07 05:57:52 +08:00
bBuildUnvisible = undefined === bBuildUnvisible ? false : !!bBuildUnvisible;
bSystem = null == bSystem ? 0 < aSystem.length : bSystem;
iUnDeep = null == iUnDeep ? 0 : iUnDeep;
fDisableCallback = null != fDisableCallback ? fDisableCallback : null;
fVisibleCallback = null != fVisibleCallback ? fVisibleCallback : null;
fRenameCallback = null != fRenameCallback ? fRenameCallback : null;
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
if (!isArray(aDisabled)) {
2016-06-07 05:57:52 +08:00
aDisabled = [];
}
2019-07-05 03:19:24 +08:00
if (!isArray(aHeaderLines)) {
2016-06-07 05:57:52 +08:00
aHeaderLines = [];
}
aHeaderLines.forEach(line => {
2016-06-07 05:57:52 +08:00
aResult.push({
id: line[0],
name: line[1],
2016-06-07 05:57:52 +08:00
system: false,
seporator: false,
disabled: false
});
});
2016-06-07 05:57:52 +08:00
bSep = true;
aSystem.forEach(oItem => {
2019-07-05 03:19:24 +08:00
if (fVisibleCallback ? fVisibleCallback(oItem) : true) {
if (bSep && aResult.length) {
2016-06-07 05:57:52 +08:00
aResult.push({
id: '---',
name: '---',
system: false,
seporator: true,
disabled: true
});
}
bSep = false;
aResult.push({
id: oItem.fullNameRaw,
2016-07-02 06:49:59 +08:00
name: fRenameCallback ? fRenameCallback(oItem) : oItem.name(),
2016-06-07 05:57:52 +08:00
system: true,
seporator: false,
2019-07-05 03:19:24 +08:00
disabled:
!oItem.selectable ||
aDisabled.includes(oItem.fullNameRaw) ||
2016-07-02 06:49:59 +08:00
(fDisableCallback ? fDisableCallback(oItem) : false)
2016-06-07 05:57:52 +08:00
});
}
});
2016-06-07 05:57:52 +08:00
bSep = true;
aList.forEach(oItem => {
// if (oItem.subScribed() || !oItem.existen || bBuildUnvisible)
2019-07-05 03:19:24 +08:00
if (
(oItem.subScribed() || !oItem.existen || bBuildUnvisible) &&
(oItem.selectable || oItem.hasSubScribedSubfolders())
) {
if (fVisibleCallback ? fVisibleCallback(oItem) : true) {
if (FolderType.User === oItem.type() || !bSystem || oItem.hasSubScribedSubfolders()) {
if (bSep && aResult.length) {
2016-06-07 05:57:52 +08:00
aResult.push({
id: '---',
name: '---',
system: false,
seporator: true,
disabled: true
});
}
bSep = false;
aResult.push({
id: oItem.fullNameRaw,
2019-07-05 03:19:24 +08:00
name:
new Array(oItem.deep + 1 - iUnDeep).join(sDeepPrefix) +
2016-07-02 06:49:59 +08:00
(fRenameCallback ? fRenameCallback(oItem) : oItem.name()),
2016-06-07 05:57:52 +08:00
system: false,
seporator: false,
2019-07-05 03:19:24 +08:00
disabled:
!oItem.selectable ||
aDisabled.includes(oItem.fullNameRaw) ||
2016-07-02 06:49:59 +08:00
(fDisableCallback ? fDisableCallback(oItem) : false)
2016-06-07 05:57:52 +08:00
});
}
}
}
if (oItem.subScribed() && oItem.subFolders().length) {
2019-07-05 03:19:24 +08:00
aResult = aResult.concat(
folderListOptionsBuilder(
[],
oItem.subFolders(),
aDisabled,
[],
iUnDeep,
fDisableCallback,
fVisibleCallback,
fRenameCallback,
bSystem,
bBuildUnvisible
)
);
2016-06-07 05:57:52 +08:00
}
});
2016-06-07 05:57:52 +08:00
return aResult;
}
/**
* @param {Object|Array} objectOrObjects
2016-06-30 08:02:45 +08:00
* @returns {void}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function delegateRunOnDestroy(objectOrObjects) {
if (objectOrObjects) {
if (isArray(objectOrObjects)) {
objectOrObjects.forEach(item => delegateRunOnDestroy(item));
} else {
objectOrObjects.onDestroy && objectOrObjects.onDestroy();
2016-06-07 05:57:52 +08:00
}
}
}
2019-07-05 03:19:24 +08:00
let __themeTimer = 0,
2016-06-30 08:02:45 +08:00
__themeAjax = null;
2016-06-07 05:57:52 +08:00
2016-06-30 08:02:45 +08:00
/**
* @param {string} value
2016-08-22 05:30:34 +08:00
* @param {function=} themeTrigger = noop
2016-06-30 08:02:45 +08:00
* @returns {void}
*/
export function changeTheme(value, themeTrigger = ()=>{}) {
const themeLink = doc.getElementById('app-theme-link'),
clearTimer = () => {
__themeTimer = setTimeout(() => themeTrigger(SaveSettingsStep.Idle), 1000);
__themeAjax = null;
2016-06-30 08:02:45 +08:00
};
let themeStyle = doc.getElementById('app-theme-style'),
url = (themeLink && themeLink.href) || (themeStyle && themeStyle.dataset.href);
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
if (url) {
url = url.toString()
.replace(/\/-\/[^/]+\/-\//, '/-/' + value + '/-/')
.replace(/\/Css\/[^/]+\/User\//, '/Css/0/User/')
.replace(/\/Hash\/[^/]+\//, '/Hash/-/');
2016-06-07 05:57:52 +08:00
if ('Json/' !== url.substr(-5)) {
2016-06-07 05:57:52 +08:00
url += 'Json/';
}
clearTimeout(__themeTimer);
2016-08-22 05:30:34 +08:00
2016-06-07 05:57:52 +08:00
themeTrigger(SaveSettingsStep.Animate);
if (__themeAjax) {
2016-06-07 05:57:52 +08:00
__themeAjax.abort();
}
let init = {};
if (window.AbortController) {
__themeAjax = new AbortController();
init.signal = __themeAjax.signal;
}
rl.fetchJSON(url, init)
.then(data => {
2019-07-05 03:19:24 +08:00
if (data && isArray(data) && 2 === data.length) {
if (themeLink && !themeStyle) {
themeStyle = doc.createElement('style');
themeStyle.id = 'app-theme-style';
2019-07-05 03:19:24 +08:00
themeLink.after(themeStyle);
themeLink.remove();
2016-06-07 05:57:52 +08:00
}
if (themeStyle) {
themeStyle.textContent = data[1];
themeStyle.dataset.href = url;
themeStyle.dataset.theme = data[0];
2019-07-05 03:19:24 +08:00
}
2016-06-07 05:57:52 +08:00
2019-07-05 03:19:24 +08:00
themeTrigger(SaveSettingsStep.TrueResult);
}
})
.then(clearTimer, clearTimer);
2016-06-07 05:57:52 +08:00
}
}
2016-06-30 08:02:45 +08:00
/**
* @returns {function}
*/
2019-07-05 03:19:24 +08:00
export function computedPagenatorHelper(koCurrentPage, koPageCount) {
2016-06-28 02:14:33 +08:00
return () => {
2019-07-05 03:19:24 +08:00
const currentPage = koCurrentPage(),
2016-06-28 02:14:33 +08:00
pageCount = koPageCount(),
result = [],
fAdd = (index, push = true, customName = '') => {
const data = {
current: index === currentPage,
name: customName ? customName.toString() : index.toString(),
custom: !!customName,
title: customName ? index.toString() : '',
2016-06-28 02:14:33 +08:00
value: index.toString()
};
2019-07-05 03:19:24 +08:00
if (push) {
2016-06-28 02:14:33 +08:00
result.push(data);
2019-07-05 03:19:24 +08:00
} else {
2016-06-28 02:14:33 +08:00
result.unshift(data);
}
2016-06-30 08:02:45 +08:00
};
2016-06-28 02:14:33 +08:00
2019-07-05 03:19:24 +08:00
let prev = 0,
2016-06-28 02:14:33 +08:00
next = 0,
2016-06-30 08:02:45 +08:00
limit = 2;
2016-06-28 02:14:33 +08:00
2019-07-05 03:19:24 +08:00
if (1 < pageCount || (0 < pageCount && pageCount < currentPage)) {
if (pageCount < currentPage) {
2016-06-28 02:14:33 +08:00
fAdd(pageCount);
prev = pageCount;
next = pageCount;
2019-07-05 03:19:24 +08:00
} else {
if (3 >= currentPage || pageCount - 2 <= currentPage) {
2016-06-28 02:14:33 +08:00
limit += 2;
}
fAdd(currentPage);
prev = currentPage;
next = currentPage;
}
while (0 < limit) {
--prev;
++next;
2016-06-28 02:14:33 +08:00
2019-07-05 03:19:24 +08:00
if (0 < prev) {
2016-06-28 02:14:33 +08:00
fAdd(prev, false);
--limit;
2016-06-28 02:14:33 +08:00
}
2019-07-05 03:19:24 +08:00
if (pageCount >= next) {
2016-06-28 02:14:33 +08:00
fAdd(next, true);
--limit;
2019-07-05 03:19:24 +08:00
} else if (0 >= prev) {
2016-06-28 02:14:33 +08:00
break;
}
}
2019-07-05 03:19:24 +08:00
if (3 === prev) {
2016-06-28 02:14:33 +08:00
fAdd(2, false);
2019-07-05 03:19:24 +08:00
} else if (3 < prev) {
2016-06-28 02:14:33 +08:00
fAdd(Math.round((prev - 1) / 2), false, '...');
}
2019-07-05 03:19:24 +08:00
if (pageCount - 2 === next) {
2016-06-28 02:14:33 +08:00
fAdd(pageCount - 1, true);
2019-07-05 03:19:24 +08:00
} else if (pageCount - 2 > next) {
2016-06-28 02:14:33 +08:00
fAdd(Math.round((pageCount + next) / 2), true, '...');
}
// first and last
2019-07-05 03:19:24 +08:00
if (1 < prev) {
2016-06-28 02:14:33 +08:00
fAdd(1, false);
}
2019-07-05 03:19:24 +08:00
if (pageCount > next) {
2016-06-28 02:14:33 +08:00
fAdd(pageCount, true);
}
}
return result;
};
}
2017-08-07 23:09:14 +08:00
/**
* @param {string} color
* @returns {boolean}
*/
2019-07-05 03:19:24 +08:00
export function isTransparent(color) {
2017-08-07 23:09:14 +08:00
return 'rgba(0, 0, 0, 0)' === color || 'transparent' === color;
}
2016-06-07 05:57:52 +08:00
/**
* @param {string} mailToUrl
2017-09-28 01:58:15 +08:00
* @param {Function} PopupComposeViewModel
2016-06-30 08:02:45 +08:00
* @returns {boolean}
2016-06-07 05:57:52 +08:00
*/
2019-07-05 03:19:24 +08:00
export function mailToHelper(mailToUrl, PopupComposeViewModel) {
if (
mailToUrl &&
'mailto:' ===
mailToUrl
.toString()
.substr(0, 7)
.toLowerCase()
) {
if (!PopupComposeViewModel) {
2016-06-07 05:57:52 +08:00
return true;
}
mailToUrl = mailToUrl.toString().substr(7);
2019-07-05 03:19:24 +08:00
let to = [],
2016-06-07 05:57:52 +08:00
cc = null,
bcc = null,
2016-06-30 08:02:45 +08:00
params = {};
2019-07-05 03:19:24 +08:00
const email = mailToUrl.replace(/\?.+$/, ''),
query = mailToUrl.replace(/^[^?]*\?/, ''),
2017-09-28 01:58:15 +08:00
EmailModel = require('Model/Email').default;
query.split('&').forEach(temp => {
temp = temp.split('=');
params[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
});
2016-06-07 05:57:52 +08:00
if (undefined !== params.to) {
2017-10-07 02:52:00 +08:00
to = EmailModel.parseEmailLine(decodeURIComponent(email + ',' + params.to));
to = Object.values(
2019-07-05 03:19:24 +08:00
to.reduce((result, value) => {
if (value) {
if (result[value.email]) {
if (!result[value.email].name) {
result[value.email] = value;
}
} else {
2017-10-07 02:52:00 +08:00
result[value.email] = value;
}
}
2019-07-05 03:19:24 +08:00
return result;
}, {})
);
} else {
2017-10-07 02:52:00 +08:00
to = EmailModel.parseEmailLine(email);
}
if (undefined !== params.cc) {
2017-09-28 01:58:15 +08:00
cc = EmailModel.parseEmailLine(decodeURIComponent(params.cc));
2016-06-07 05:57:52 +08:00
}
if (undefined !== params.bcc) {
2017-09-28 01:58:15 +08:00
bcc = EmailModel.parseEmailLine(decodeURIComponent(params.bcc));
2016-06-07 05:57:52 +08:00
}
2017-09-28 01:58:15 +08:00
require('Knoin/Knoin').showScreenPopup(PopupComposeViewModel, [
2019-07-05 03:19:24 +08:00
ComposeType.Empty,
null,
to,
cc,
bcc,
null == params.subject ? null : pString(decodeURIComponent(params.subject)),
null == params.body ? null : plainToHtml(pString(decodeURIComponent(params.body)))
2016-06-07 05:57:52 +08:00
]);
return true;
}
return false;
}