Use less jQuery, more native

This commit is contained in:
djmaze 2020-08-27 15:45:47 +02:00
parent 24cb874c87
commit bdb36ec128
35 changed files with 492 additions and 779 deletions

View file

@ -45,8 +45,8 @@ function writeCSS(css) {
const style = doc.createElement('style');
style.type = 'text/css';
style.textContent = css;
// style.appendChild(doc.createTextNode(styles));
doc.head.appendChild(style);
// style.append(doc.createTextNode(styles));
doc.head.append(style);
}
function loadScript(src) {
@ -59,8 +59,8 @@ function loadScript(src) {
script.onerror = () => reject(new Error(src));
script.src = src;
// script.type = 'text/javascript';
doc.head.appendChild(script);
// doc.body.appendChild(element);
doc.head.append(script);
// doc.body.append(element);
});
}

View file

@ -1,8 +1,8 @@
import ko from 'ko';
import { KeyState } from 'Common/Enums';
export const $html = jQuery('html');
export const $htmlCL = document.documentElement.classList;
export const $html = document.documentElement;
export const $htmlCL = $html.classList;
/**
* @type {?}

View file

@ -106,7 +106,6 @@ class HtmlEditor {
this.onModeChange = onModeChange;
this.element = element;
this.$element = jQuery(element);
this.resize = this.resizeEditor.throttle(100);
@ -414,7 +413,7 @@ class HtmlEditor {
resizeEditor() {
if (this.editor && this.__resizable) {
try {
this.editor.resize(this.$element.width(), this.$element.innerHeight());
this.editor.resize(this.element.clientWidth, this.element.clientHeight);
} catch (e) {} // eslint-disable-line no-empty
}
}

View file

@ -15,7 +15,6 @@ class Selector {
iSelectNextHelper = 0;
iFocusedNextHelper = 0;
oContentVisible;
oContentScrollable;
sItemSelector;
@ -262,12 +261,11 @@ class Selector {
this.focusedItem(null);
}
init(contentVisible, contentScrollable, keyScope = 'all') {
this.oContentVisible = contentVisible;
this.oContentScrollable = contentScrollable ? contentScrollable[0] : null;
init(contentScrollable, keyScope = 'all') {
this.oContentScrollable = contentScrollable;
if (this.oContentVisible && this.oContentScrollable) {
jQuery(this.oContentVisible)
if (contentScrollable) {
jQuery(contentScrollable)
.on('selectstart', (event) => {
if (event && event.preventDefault) {
event.preventDefault();
@ -289,8 +287,9 @@ class Selector {
});
key('enter', keyScope, () => {
if (this.focusedItem() && !this.focusedItem().selected()) {
this.actionClick(this.focusedItem());
const focused = this.focusedItem();
if (focused && !focused.selected()) {
this.actionClick(focused);
return false;
}
@ -500,45 +499,29 @@ class Selector {
* @returns {boolean}
*/
scrollToFocused() {
if (!this.oContentVisible || !this.oContentScrollable) {
return false;
const scrollable = this.oContentScrollable;
if (scrollable) {
let block, focused = scrollable.querySelector(this.sItemFocusedSelector);
if (focused) {
const fRect = focused.getBoundingClientRect(),
sRect = scrollable.getBoundingClientRect();
if (fRect.top < sRect.top) {
block = 'start';
} else if (fRect.bottom > sRect.bottom) {
block = 'end';
}
block && focused.scrollIntoView(block === 'start');
} else {
scrollable.scrollTop = 0;
}
}
const offset = 20,
list = this.list(),
$focused = jQuery(this.sItemFocusedSelector, this.oContentScrollable),
pos = $focused.position(),
visibleHeight = this.oContentVisible.height(),
focusedHeight = $focused.outerHeight();
if (list && list[0] && list[0].focused()) {
this.oContentScrollable.scrollTop = 0;
return true;
} else if (pos && (0 > pos.top || pos.top + focusedHeight > visibleHeight)) {
let top = this.oContentScrollable.scrollTop + pos.top;
this.oContentScrollable.scrollTop =
0 > pos.top
? top - offset
: top - visibleHeight + focusedHeight + offset
;
return true;
}
return false;
}
/**
* @returns {boolean}
*/
scrollToTop() {
if (!this.oContentVisible || !this.oContentScrollable) {
return false;
}
this.oContentScrollable.scrollTop = 0;
return true;
this.oContentScrollable && (this.oContentScrollable.scrollTop = 0);
}
eventClickFunction(item, event) {

View file

@ -1,13 +1,12 @@
import ko from 'ko';
import { Notification, UploadErrorCode } from 'Common/Enums';
import { pInt } from 'Common/Utils';
import { $html, $htmlCL } from 'Common/Globals';
import { langLink } from 'Common/Links';
let I18N_DATA = window.rainloopI18N || {};
const I18N_NOTIFICATION_DATA = {};
const I18N_NOTIFICATION_MAP = [
const doc = document,
I18N_NOTIFICATION_DATA = {},
I18N_NOTIFICATION_MAP = [
[Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'],
[Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'],
[Notification.AuthError, 'NOTIFICATIONS/AUTH_ERROR'],
@ -101,26 +100,24 @@ export function i18n(key, valueList, defaulValue) {
return result;
}
const i18nToNode = (element) => {
const $el = jQuery(element),
key = $el.data('i18n');
const i18nToNode = element => {
const key = element.dataset.i18n;
if (key) {
if ('[' === key.substr(0, 1)) {
switch (key.substr(0, 6)) {
case '[html]':
$el.html(i18n(key.substr(6)));
element.innerHTML = i18n(key.substr(6));
break;
case '[place':
$el.attr('placeholder', i18n(key.substr(13)));
element.placeholder = i18n(key.substr(13));
break;
case '[title':
$el.attr('title', i18n(key.substr(7)));
element.title = i18n(key.substr(7));
break;
// no default
}
} else {
$el.text(i18n(key));
element.textContent = i18n(key);
}
}
};
@ -129,11 +126,9 @@ const i18nToNode = (element) => {
* @param {Object} elements
* @param {boolean=} animate = false
*/
export function i18nToNodes(elements) {
export function i18nToNodes(element) {
setTimeout(() =>
jQuery('[data-i18n]', elements).each((index, item) => {
i18nToNode(item);
})
element.querySelectorAll('[data-i18n]').forEach(item => i18nToNode(item))
, 1);
}
@ -141,7 +136,7 @@ const reloadData = () => {
if (window.rainloopI18N) {
I18N_DATA = window.rainloopI18N || {};
i18nToNodes(document);
i18nToNodes(doc);
dispatchEvent(new CustomEvent('reload-time'));
trigger(!trigger());
@ -209,7 +204,7 @@ export function getNotification(code, message = '', defCode = null) {
*/
export function getNotificationFromResponse(response, defCode = Notification.UnknownNotification) {
return response && response.ErrorCode
? getNotification(pInt(response.ErrorCode), response.ErrorMessage || '')
? getNotification(parseInt(response.ErrorCode, 10) || defCode, response.ErrorMessage || '')
: getNotification(defCode);
}
@ -253,8 +248,6 @@ export function getUploadErrorDescByCode(code) {
export function reload(admin, language) {
const start = Date.now();
$htmlCL.add('rl-changing-language');
return new Promise((resolve, reject) => {
return fetch(langLink(language, admin), {cache: 'reload'})
.then(response => {
@ -269,18 +262,19 @@ export function reload(admin, language) {
reject(new Error(error.message))
})
.then(data => {
var script = document.createElement('script');
var script = doc.createElement('script');
script.text = data;
document.head.appendChild(script).parentNode.removeChild(script);
doc.head.append(script).remove();
setTimeout(
() => {
reloadData();
const isRtl = ['ar', 'ar_sa', 'he', 'he_he', 'ur', 'ur_ir'].includes((language || '').toLowerCase());
const isRtl = ['ar', 'ar_sa', 'he', 'he_he', 'ur', 'ur_ir'].includes((language || '').toLowerCase()),
htmlCL = doc.documentElement.classList;
$htmlCL.remove('rl-changing-language', 'rl-rtl', 'rl-ltr');
// $html.attr('dir', isRtl ? 'rtl' : 'ltr')
$htmlCL.add(isRtl ? 'rl-rtl' : 'rl-ltr');
htmlCL.remove('rl-rtl', 'rl-ltr');
htmlCL.add(isRtl ? 'rl-rtl' : 'rl-ltr');
// doc.documentElement.dir = isRtl ? 'rtl' : 'ltr'
resolve();
},
@ -289,6 +283,3 @@ export function reload(admin, language) {
});
});
}
// init section
$htmlCL.add('rl-' + ($html.attr('dir') || 'ltr'));

View file

@ -3,8 +3,7 @@ import { Mime } from 'Common/Mime';
const
doc = document,
$ = jQuery,
$div = $('<div></div>'),
tpl = doc.createElement('template'),
isArray = Array.isArray,
htmlmap = {
'&': '&amp;',
@ -15,6 +14,13 @@ const
},
htmlspecialchars = str => (''+str).replace(/[&<>"']/g, m => htmlmap[m]);
export function htmlToElement(html) {
var template = document.createElement('template');
template.innerHTML = html.trim();
return template.content.firstChild;
}
/**
* @param {(string|number)} value
* @param {boolean=} includeZero = true
@ -137,7 +143,7 @@ export function inFocus() {
try {
if (doc.activeElement) {
if (undefined === doc.activeElement.__inFocusCache) {
doc.activeElement.__inFocusCache = $(doc.activeElement).is(
doc.activeElement.__inFocusCache = doc.activeElement.matches(
'input,textarea,iframe,.cke_editable'
);
}
@ -156,8 +162,7 @@ export function inFocus() {
export function removeInFocus(force) {
if (doc.activeElement && doc.activeElement.blur) {
try {
const activeEl = $(doc.activeElement);
if (force || (activeEl && activeEl.is('input,textarea'))) {
if (force || doc.activeElement.matches('input,textarea')) {
doc.activeElement.blur();
}
} catch (e) {} // eslint-disable-line no-empty
@ -275,19 +280,6 @@ export function convertLangName(language, isEng = false) {
);
}
/**
* @returns {object}
*/
export function draggablePlace() {
return $(
'<div class="draggablePlace">' +
'<span class="text"></span>&nbsp;' +
'<i class="icon-copy icon-white visible-on-ctrl"></i>' +
'<i class="icon-mail icon-white hidden-on-ctrl"></i>' +
'</div>'
).appendTo('#rl-hidden');
}
/**
* @param {object} domOption
* @param {object} item
@ -299,65 +291,6 @@ export function defautOptionsAfterRender(domItem, item) {
}
}
/**
* @param {string} title
* @param {Object} body
* @param {boolean} isHtml
* @param {boolean} print
*/
export function clearBqSwitcher(body) {
body.find('blockquote.rl-bq-switcher').removeClass('rl-bq-switcher hidden-bq');
body
.find('.rlBlockquoteSwitcher')
.off('.rlBlockquoteSwitcher')
.remove();
body.find('[data-html-editor-font-wrapper]').removeAttr('data-html-editor-font-wrapper');
}
/**
* @param {object} messageData
* @param {Object} body
* @param {boolean} isHtml
* @param {boolean} print
* @returns {void}
*/
export function previewMessage(
{ title, subject, date, fromCreds, toCreds, toLabel, ccClass, ccCreds, ccLabel },
body,
isHtml,
print
) {
const win = open(''),
doc = win.document,
bodyClone = body.clone(),
bodyClass = isHtml ? 'html' : 'plain';
clearBqSwitcher(bodyClone);
const html = bodyClone ? bodyClone.html() : '';
doc.write(
deModule(require('Html/PreviewMessage.html'))
.replace('{{title}}', encodeHtml(title))
.replace('{{subject}}', encodeHtml(subject))
.replace('{{date}}', encodeHtml(date))
.replace('{{fromCreds}}', encodeHtml(fromCreds))
.replace('{{toCreds}}', encodeHtml(toCreds))
.replace('{{toLabel}}', encodeHtml(toLabel))
.replace('{{ccClass}}', encodeHtml(ccClass))
.replace('{{ccCreds}}', encodeHtml(ccCreds))
.replace('{{ccLabel}}', encodeHtml(ccLabel))
.replace('{{bodyClass}}', bodyClass)
.replace('{{html}}', html)
);
doc.close();
if (print) {
setTimeout(() => win.print(), 100);
}
}
/**
* @param {Function} fCallback
* @param {?} koTrigger
@ -483,7 +416,7 @@ export function htmlToPlain(html) {
fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + htmlspecialchars(args[2]) : ''),
convertLinks = (...args) => (args && 1 < args.length ? args[1].trim() : '');
text = html
tpl.innerHTML = html
.replace(/<p[^>]*><\/p>/gi, '')
.replace(/<pre[^>]*>([\s\S\r\n\t]*)<\/pre>/gim, convertPre)
.replace(/[\s]+/gm, ' ')
@ -507,16 +440,13 @@ export function htmlToPlain(html) {
.replace(/&quot;/gi, '"')
.replace(/<[^>]*>/gm, '');
text = $div.html(text).text();
text = text
text = splitPlainText(tpl.textContent
.replace(/\n[ \t]+/gm, '\n')
.replace(/[\n]{3,}/gm, '\n\n')
.replace(/&gt;/gi, '>')
.replace(/&lt;/gi, '<')
.replace(/&amp;/gi, '&');
text = splitPlainText(text);
.replace(/&amp;/gi, '&')
);
pos = 0;
limit = 800;
@ -530,7 +460,6 @@ export function htmlToPlain(html) {
if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3) {
text = text.substring(0, iP1) + convertBlockquote(text.substring(iP1 + 13, iP3)) + text.substring(iP3 + 11);
pos = 0;
} else if (-1 < iP2 && iP2 < iP3) {
pos = iP2 - 1;
@ -552,7 +481,7 @@ export function htmlToPlain(html) {
* @param {boolean} findEmailAndLinksInText = false
* @returns {string}
*/
export function plainToHtml(plain, findEmailAndLinksInText = false) {
export function plainToHtml(plain) {
plain = plain.toString().replace(/\r/g, '');
plain = plain.replace(/^>[> ]>+/gm, ([match]) => (match ? match.replace(/[ ]+/g, '') : match));
@ -595,9 +524,7 @@ export function plainToHtml(plain, findEmailAndLinksInText = false) {
aText = aNextText;
} while (bDo);
plain = aText.join('\n');
plain = plain
return aText.join('\n')
// .replace(/~~~\/blockquote~~~\n~~~blockquote~~~/g, '\n')
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;')
@ -605,8 +532,6 @@ export function plainToHtml(plain, findEmailAndLinksInText = false) {
.replace(/~~~blockquote~~~[\s]*/g, '<blockquote>')
.replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>')
.replace(/\n/g, '<br />');
return findEmailAndLinksInText ? findEmailAndLinks(plain) : plain;
}
window['rainloop_Utils_htmlToPlain'] = htmlToPlain; // eslint-disable-line dot-notation
@ -766,39 +691,6 @@ export function selectElement(element) {
sel.addRange(range);
}
/**
* @param {boolean=} delay = false
*/
export function triggerAutocompleteInputChange(delay = false) {
const fFunc = () => $('.checkAutocomplete').trigger('change');
if (delay) {
setTimeout(fFunc, 100);
} else {
fFunc();
}
}
const configurationScriptTagCache = {};
/**
* @param {string} configuration
* @returns {object}
*/
export function getConfigurationFromScriptTag(configuration) {
if (!configurationScriptTagCache[configuration]) {
configurationScriptTagCache[configuration] = $(
'script[type="application/json"][data-configuration="' + configuration + '"]'
);
}
try {
return JSON.parse(configurationScriptTagCache[configuration].text());
} catch (e) {} // eslint-disable-line no-empty
return {};
}
/**
* @param {Object|Array} objectOrObjects
* @returns {void}