Embed cleaner node modules

This commit is contained in:
djmaze 2020-08-12 01:47:24 +02:00
parent e7180a86ce
commit aaf4933b0a
6 changed files with 383 additions and 20 deletions

View file

@ -75,23 +75,23 @@ Things might work in Edge 15-18, Firefox 47-62 and Chrome 54-68 due to one polyf
|js/* |1.14.0 |native |gzip 1.14 |gzip |
|----------- |--------: |--------: |--------: |--------: |
|admin.js |2.130.942 |1.172.413 | 485.481 | 291.715 |
|app.js |4.184.455 |2.888.668 | 932.725 | 682.438 |
|boot.js | 671.522 | 44.394 | 169.502 | 15.460 |
|admin.js |2.130.942 |1.133.275 | 485.481 | 274.632 |
|app.js |4.184.455 |2.844.189 | 932.725 | 664.075 |
|boot.js | 671.522 | 44.029 | 169.502 | 15.460 |
|libs.js | 647.614 | 431.049 | 194.728 | 132.315 |
|polyfills.js | 325.834 | 0 | 71.825 | 0 |
|TOTAL js |7.960.367 |4.537.200 |1.854.261 |1.121.928 |
|TOTAL js |7.960.367 |4.452.542 |1.854.261 |1.086.482 |
|js/min/* |1.14.0 |native |gzip 1.14 |gzip |
|--------------- |--------: |--------: |--------: |--------: |
|admin.min.js | 252.147 | 153.689 | 73.657 | 44.000 |
|app.min.js | 511.202 | 380.294 |140.462 |100.236 |
|admin.min.js | 252.147 | 153.095 | 73.657 | 43.734 |
|app.min.js | 511.202 | 378.695 |140.462 | 99.511 |
|boot.min.js | 66.007 | 5.589 | 22.567 | 2.333 |
|libs.min.js | 572.545 | 387.636 |176.720 |122.519 |
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 |
|TOTAL js/min |1.434.353 | 927.208 |424.718 |269.088 |
|TOTAL js/min |1.434.353 | 925.015 |424.718 |268.097 |
507.145 bytes (155.630 gzip) is not much, but it feels faster.
509.338 bytes (156.621 gzip) is not much, but it feels faster.
|css/* |1.14.0 |native |

View file

@ -1,6 +1,114 @@
import Cookies from 'js-cookie';
import { CLIENT_SIDE_STORAGE_INDEX_NAME } from 'Common/Consts';
var Cookies = (() => {
function extend (...args) {
var result = {};
args.forEach(attributes => {
for (var key in attributes) {
result[key] = attributes[key];
}
});
return result;
}
function decode (s) {
return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
}
function set (key, value, attributes) {
if (typeof document === 'undefined') {
return;
}
attributes = extend({
path: '/'
}, attributes);
if (typeof attributes.expires === 'number') {
attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
var result = JSON.stringify(value);
if (/^[{[]/.test(result)) {
value = result;
}
} catch (e) {} // eslint-disable-line no-empty
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
key = encodeURIComponent(String(key))
.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)
.replace(/[()]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
// Considers RFC 6265 section 5.2:
// ...
// 3. If the remaining unparsed-attributes contains a %x3B (";")
// character:
// Consume the characters of the unparsed-attributes up to,
// not including, the first %x3B (";") character.
// ...
stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
function get (key) {
if (typeof document === 'undefined') {
return;
}
var jar = {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all.
var cookies = document.cookie ? document.cookie.split('; ') : [];
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
try {
var name = decode(parts[0]);
cookie = decode(cookie);
try {
cookie = JSON.parse(cookie);
} catch (e) {} // eslint-disable-line no-empty
jar[name] = cookie;
if (key === name) {
break;
}
} catch (e) {} // eslint-disable-line no-empty
}
return key ? jar[key] : jar;
}
return {
set: set,
getJSON: key => get(key)
};
})();
class CookieDriver {
/**
* @param {string} key

View file

@ -1,6 +1,267 @@
import addressparser from 'emailjs-addressparser';
import { encodeHtml, isNonEmptyArray } from 'Common/Utils';
'use strict';
/**
* Parses structured e-mail addresses from an address field
*
* Example:
*
* "Name <address@domain>"
*
* will be converted to
*
* [{name: "Name", address: "address@domain"}]
*
* @param {String} str Address field
* @return {Array} An array of address objects
*/
function addressparser(str) {
var tokenizer = new Tokenizer(str);
var tokens = tokenizer.tokenize();
var addresses = [];
var address = [];
var parsedAddresses = [];
tokens.forEach(token => {
if (token.type === 'operator' && (token.value === ',' || token.value === ';')) {
if (address.length) {
addresses.push(address);
}
address = [];
} else {
address.push(token);
}
});
if (address.length) {
addresses.push(address);
}
addresses.forEach(address => {
address = _handleAddress(address);
if (address.length) {
parsedAddresses = parsedAddresses.concat(address);
}
});
return parsedAddresses;
}
/**
* Converts tokens for a single address into an address object
*
* @param {Array} tokens Tokens object
* @return {Object} Address object
*/
function _handleAddress(tokens) {
var isGroup = false;
var state = 'text';
var address = void 0;
var addresses = [];
var data = {
address: [],
comment: [],
group: [],
text: []
// Filter out <addresses>, (comments) and regular text
};
for (var i = 0, len = tokens.length; i < len; i++) {
var token = tokens[i];
if (token.type === 'operator') {
switch (token.value) {
case '<':
state = 'address';
break;
case '(':
state = 'comment';
break;
case ':':
state = 'group';
isGroup = true;
break;
default:
state = 'text';
}
} else {
if (token.value) {
data[state].push(token.value);
}
}
}
// If there is no text but a comment, replace the two
if (!data.text.length && data.comment.length) {
data.text = data.comment;
data.comment = [];
}
if (isGroup) {
// http://tools.ietf.org/html/rfc2822#appendix-A.1.3
data.text = data.text.join(' ');
addresses.push({
name: data.text || address && address.name,
group: data.group.length ? addressparser(data.group.join(',')) : []
});
} else {
// If no address was found, try to detect one from regular text
if (!data.address.length && data.text.length) {
for (var _i = data.text.length - 1; _i >= 0; _i--) {
if (data.text[_i].match(/^[^@\s]+@[^@\s]+$/)) {
data.address = data.text.splice(_i, 1);
break;
}
}
var _regexHandler = function _regexHandler(address) {
if (!data.address.length) {
data.address = [address.trim()];
return ' ';
}
return address;
};
// still no address
if (!data.address.length) {
for (var _i2 = data.text.length - 1; _i2 >= 0; _i2--) {
data.text[_i2] = data.text[_i2].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, _regexHandler).trim();
if (data.address.length) {
break;
}
}
}
}
// If there's still is no text but a comment exixts, replace the two
if (!data.text.length && data.comment.length) {
data.text = data.comment;
data.comment = [];
}
// Keep only the first address occurence, push others to regular text
if (data.address.length > 1) {
data.text = data.text.concat(data.address.splice(1));
}
// Join values with spaces
data.text = data.text.join(' ');
data.address = data.address.join(' ');
if (!data.address && isGroup) {
return [];
}
address = {
address: data.address || data.text || '',
name: data.text || data.address || ''
};
if (address.address === address.name) {
if ((address.address || '').match(/@/)) {
address.name = '';
} else {
address.address = '';
}
}
addresses.push(address);
}
return addresses;
}
/*
* Operator tokens and which tokens are expected to end the sequence
*/
var OPERATORS = {
'"': '"',
'(': ')',
'<': '>',
',': '',
// Groups are ended by semicolons
':': ';',
// Semicolons are not a legal delimiter per the RFC2822 grammar other
// than for terminating a group, but they are also not valid for any
// other use in this context. Given that some mail clients have
// historically allowed the semicolon as a delimiter equivalent to the
// comma in their UI, it makes sense to treat them the same as a comma
// when used outside of a group.
';': ''
};
class Tokenizer
{
constructor(str) {
this.str = (str || '').toString();
this.operatorCurrent = '';
this.operatorExpecting = '';
this.node = null;
this.escaped = false;
this.list = [];
}
tokenize() {
var list = [], i = this.str.length;
while (i--) this.checkChar(this.str[i]);
this.list.forEach(node => {
node.value = (node.value || '').toString().trim();
if (node.value) {
list.push(node);
}
});
return list;
}
checkChar(chr) {
if ((chr in OPERATORS || chr === '\\') && this.escaped) {
this.escaped = false;
} else if (this.operatorExpecting && chr === this.operatorExpecting) {
this.node = {
type: 'operator',
value: chr
};
this.list.push(this.node);
this.node = null;
this.operatorExpecting = '';
this.escaped = false;
return;
} else if (!this.operatorExpecting && chr in OPERATORS) {
this.node = {
type: 'operator',
value: chr
};
this.list.push(this.node);
this.node = null;
this.operatorExpecting = OPERATORS[chr];
this.escaped = false;
return;
}
if (!this.escaped && chr === '\\') {
this.escaped = true;
return;
}
if (!this.node) {
this.node = {
type: 'text',
value: ''
};
this.list.push(this.node);
}
if (this.escaped && chr !== '\\') {
this.node.value += '\\';
}
this.node.value += chr;
this.escaped = false;
}
}
class EmailModel {
email = '';
name = '';

View file

@ -1,5 +1,4 @@
import ko from 'ko';
import classnames from 'classnames';
import { MessagePriority, SignedVerifyStatus } from 'Common/Enums';
import { i18n } from 'Common/Translator';
@ -456,7 +455,8 @@ class MessageModel extends AbstractModel {
* @return string
*/
lineAsCss() {
return classnames({
let classes = [];
Object.entries({
'deleted': this.deleted(),
'deleted-mark': this.deletedMark(),
'selected': this.selected(),
@ -473,7 +473,8 @@ class MessageModel extends AbstractModel {
// 'hasChildrenMessage': 1 < this.threadsLen(),
'hasUnseenSubMessage': this.hasUnseenSubMessage(),
'hasFlaggedSubMessage': this.hasFlaggedSubMessage()
});
}).forEach(([key, value]) => value && classes.push(key));
return classes.join(' ');
}
/**

View file

@ -55,10 +55,8 @@
"autolinker": "3.13.0",
"babel-eslint": "10.1.0",
"babel-loader": "8.0.6",
"classnames": "2.2.6",
"copy-webpack-plugin": "5.1.1",
"css-loader": "3.4.2",
"emailjs-addressparser": "2.0.2",
"eslint": "6.8.0",
"eslint-config-prettier": "6.10.0",
"eslint-plugin-prettier": "3.1.2",
@ -89,7 +87,6 @@
"gulp-zip": "5.0.1",
"ifvisible.js": "1.0.6",
"jquery": "^3.5.1",
"js-cookie": "2.2.1",
"knockout": "3.4.2",
"knockout-sortable": "1.2.0",
"moment": "2.24.0",

View file

@ -1856,10 +1856,6 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
classnames@2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
clean-css@4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"