mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Some array.slice to array.startsWith and cleanup some JavaScript code
This commit is contained in:
parent
3903a37b64
commit
ffcc86805a
8 changed files with 83 additions and 146 deletions
|
|
@ -291,7 +291,7 @@ export const
|
||||||
if ('IMG' === name) {
|
if ('IMG' === name) {
|
||||||
oElement.loading = 'lazy';
|
oElement.loading = 'lazy';
|
||||||
let attachment;
|
let attachment;
|
||||||
if ('cid:' === value.slice(0, 4))
|
if (value.startsWith('cid:'))
|
||||||
{
|
{
|
||||||
value = value.slice(4);
|
value = value.slice(4);
|
||||||
setAttribute('data-x-src-cid', value);
|
setAttribute('data-x-src-cid', value);
|
||||||
|
|
@ -331,7 +331,7 @@ export const
|
||||||
result.hasExternals = true;
|
result.hasExternals = true;
|
||||||
oElement.alt || (oElement.alt = value.replace(/^.+\/([^/?]+).*$/, '$1').slice(-20));
|
oElement.alt || (oElement.alt = value.replace(/^.+\/([^/?]+).*$/, '$1').slice(-20));
|
||||||
}
|
}
|
||||||
else if ('data:image/' === value.slice(0, 11))
|
else if (value.startsWith('data:image/'))
|
||||||
{
|
{
|
||||||
oElement.src = value;
|
oElement.src = value;
|
||||||
}
|
}
|
||||||
|
|
@ -382,7 +382,7 @@ export const
|
||||||
oStyle[property] = null;
|
oStyle[property] = null;
|
||||||
found = found[1].replace(/^["'\s]+|["'\s]+$/g, '');
|
found = found[1].replace(/^["'\s]+|["'\s]+$/g, '');
|
||||||
let lowerUrl = found.toLowerCase();
|
let lowerUrl = found.toLowerCase();
|
||||||
if ('cid:' === lowerUrl.slice(0, 4)) {
|
if (lowerUrl.startsWith('cid:')) {
|
||||||
const attachment = findAttachmentByCid(found);
|
const attachment = findAttachmentByCid(found);
|
||||||
if (attachment?.linkPreview && name) {
|
if (attachment?.linkPreview && name) {
|
||||||
oStyle[property] = "url('" + attachment.linkPreview() + "')";
|
oStyle[property] = "url('" + attachment.linkPreview() + "')";
|
||||||
|
|
@ -392,7 +392,7 @@ export const
|
||||||
} else if (httpre.test(lowerUrl)) {
|
} else if (httpre.test(lowerUrl)) {
|
||||||
result.hasExternals = true;
|
result.hasExternals = true;
|
||||||
urls_remote.push([property, found]);
|
urls_remote.push([property, found]);
|
||||||
} else if ('data:image/' === lowerUrl.slice(0, 11)) {
|
} else if (lowerUrl.startsWith('data:image/')) {
|
||||||
oStyle[property] = value;
|
oStyle[property] = value;
|
||||||
} else {
|
} else {
|
||||||
urls_broken.push([property, found]);
|
urls_broken.push([property, found]);
|
||||||
|
|
@ -717,11 +717,9 @@ export class HtmlEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
setHtmlOrPlain(text) {
|
setHtmlOrPlain(text) {
|
||||||
if (':HTML:' === text.slice(0, 6)) {
|
text.startsWith(':HTML:')
|
||||||
this.setHtml(text.slice(6));
|
? this.setHtml(text.slice(6))
|
||||||
} else {
|
: this.setPlain(text);
|
||||||
this.setPlain(text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setData(mode, data) {
|
setData(mode, data) {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export const
|
||||||
*/
|
*/
|
||||||
themePreviewLink = theme => {
|
themePreviewLink = theme => {
|
||||||
let prefix = VERSION_PREFIX;
|
let prefix = VERSION_PREFIX;
|
||||||
if ('@custom' === theme.slice(-7)) {
|
if (theme.endsWith('@custom')) {
|
||||||
theme = theme.slice(0, theme.length - 7).trim();
|
theme = theme.slice(0, theme.length - 7).trim();
|
||||||
prefix = '';
|
prefix = '';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ export class AttachmentModel extends AbstractModel {
|
||||||
const localEvent = event.originalEvent || event;
|
const localEvent = event.originalEvent || event;
|
||||||
if (attachment && localEvent && localEvent.dataTransfer && localEvent.dataTransfer.setData) {
|
if (attachment && localEvent && localEvent.dataTransfer && localEvent.dataTransfer.setData) {
|
||||||
let link = this.linkDownload();
|
let link = this.linkDownload();
|
||||||
if ('http' !== link.slice(0, 4)) {
|
if (!link.startsWith('http')) {
|
||||||
link = location.protocol + '//' + location.host + location.pathname + link;
|
link = location.protocol + '//' + location.host + location.pathname + link;
|
||||||
}
|
}
|
||||||
localEvent.dataTransfer.setData('DownloadURL', this.mimeType + ':' + this.fileName + ':' + link);
|
localEvent.dataTransfer.setData('DownloadURL', this.mimeType + ':' + this.fileName + ':' + link);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ ThemeStore.fontSansSerif.subscribe(value => {
|
||||||
if (null != value) {
|
if (null != value) {
|
||||||
let cl = elementById('rl-app').classList;
|
let cl = elementById('rl-app').classList;
|
||||||
cl.forEach(name => {
|
cl.forEach(name => {
|
||||||
if ('font' === name.slice(0,4) && !/font(Serif|Mono)/.test(name)) {
|
if (name.startsWith('font') && !/font(Serif|Mono)/.test(name)) {
|
||||||
cl.remove(name);
|
cl.remove(name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -46,22 +46,14 @@ ThemeStore.fontSansSerif.subscribe(value => {
|
||||||
ThemeStore.fontSerif.subscribe(value => {
|
ThemeStore.fontSerif.subscribe(value => {
|
||||||
if (null != value) {
|
if (null != value) {
|
||||||
let cl = elementById('rl-app').classList;
|
let cl = elementById('rl-app').classList;
|
||||||
cl.forEach(name => {
|
cl.forEach(name => name.startsWith('fontSerif') && cl.remove(name));
|
||||||
if ('fontSerif' === name.slice(0,9)) {
|
|
||||||
cl.remove(name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
value && cl.add('fontSerif'+value);
|
value && cl.add('fontSerif'+value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ThemeStore.fontMono.subscribe(value => {
|
ThemeStore.fontMono.subscribe(value => {
|
||||||
if (null != value) {
|
if (null != value) {
|
||||||
let cl = elementById('rl-app').classList;
|
let cl = elementById('rl-app').classList;
|
||||||
cl.forEach(name => {
|
cl.forEach(name => name.startsWith('fontMono') && cl.remove(name));
|
||||||
if ('fontMono' === name.slice(0,9)) {
|
|
||||||
cl.remove(name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
value && cl.add('fontMono'+value);
|
value && cl.add('fontMono'+value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -686,7 +686,7 @@ export class ComposePopupView extends AbstractViewPopup {
|
||||||
if (identity && ComposeType.Draft !== msgComposeType && ComposeType.EditAsNew !== msgComposeType) {
|
if (identity && ComposeType.Draft !== msgComposeType && ComposeType.EditAsNew !== msgComposeType) {
|
||||||
this.editor(editor => {
|
this.editor(editor => {
|
||||||
let signature = identity.signature() || '',
|
let signature = identity.signature() || '',
|
||||||
isHtml = ':HTML:' === signature.slice(0, 6),
|
isHtml = signature.startsWith(':HTML:'),
|
||||||
fromLine = oLastMessage ? emailArrayToStringLineHelper(oLastMessage.from, true) : '';
|
fromLine = oLastMessage ? emailArrayToStringLineHelper(oLastMessage.from, true) : '';
|
||||||
if (fromLine) {
|
if (fromLine) {
|
||||||
signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
|
signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export class FolderCreatePopupView extends AbstractViewPopup {
|
||||||
oItem =>
|
oItem =>
|
||||||
oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '',
|
oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '',
|
||||||
FolderUserStore.namespace
|
FolderUserStore.namespace
|
||||||
? item => FolderUserStore.namespace !== item.fullName.slice(0, FolderUserStore.namespace.length)
|
? item => !item.fullName.startsWith(FolderUserStore.namespace)
|
||||||
: null,
|
: null,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import { leftPanelDisabled, moveAction,
|
||||||
|
|
||||||
import { computedPaginatorHelper, showMessageComposer, populateMessageBody } from 'Common/UtilsUser';
|
import { computedPaginatorHelper, showMessageComposer, populateMessageBody } from 'Common/UtilsUser';
|
||||||
import { FileInfo } from 'Common/File';
|
import { FileInfo } from 'Common/File';
|
||||||
import { moveMessagesToFolder } from 'Common/Folders';
|
|
||||||
import { isFullscreen, toggleFullscreen } from 'Common/Fullscreen';
|
import { isFullscreen, toggleFullscreen } from 'Common/Fullscreen';
|
||||||
|
|
||||||
import { mailBox, serverRequest } from 'Common/Links';
|
import { mailBox, serverRequest } from 'Common/Links';
|
||||||
|
|
@ -172,7 +171,49 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
|
|
||||||
this.selector.on('AutoSelect', () => MessagelistUserStore.canAutoSelect());
|
this.selector.on('AutoSelect', () => MessagelistUserStore.canAutoSelect());
|
||||||
|
|
||||||
this.selector.on('UpOrDown', v => this.goToUpOrDown(v));
|
this.selector.on('UpOrDown', up => {
|
||||||
|
if (MessagelistUserStore.hasChecked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(iGoToUpOrDownTimeout);
|
||||||
|
iGoToUpOrDownTimeout = setTimeout(() => {
|
||||||
|
let prev, next, temp, current;
|
||||||
|
|
||||||
|
this.messageListPaginator().find(item => {
|
||||||
|
if (item) {
|
||||||
|
if (current) {
|
||||||
|
next = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.current) {
|
||||||
|
current = item;
|
||||||
|
prev = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (up ? prev : next) {
|
||||||
|
if (SettingsUserStore.usePreviewPane() || MessageUserStore.message()) {
|
||||||
|
this.selector.iSelectNextHelper = up ? -1 : 1;
|
||||||
|
} else {
|
||||||
|
this.selector.iFocusedNextHelper = up ? -1 : 1;
|
||||||
|
}
|
||||||
|
this.selector.unselect();
|
||||||
|
this.gotoPage(up ? prev : next);
|
||||||
|
}
|
||||||
|
}, 350);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
addEventListener('mailbox.message-list.selector.go-down',
|
addEventListener('mailbox.message-list.selector.go-down',
|
||||||
e => this.selector.newSelectPosition('ArrowDown', false, e.detail)
|
e => this.selector.newSelectPosition('ArrowDown', false, e.detail)
|
||||||
|
|
@ -232,15 +273,13 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
if (SettingsCapa('DangerousActions')) {
|
SettingsCapa('DangerousActions')
|
||||||
showScreenPopup(FolderClearPopupView, [FolderUserStore.currentFolder()]);
|
&& showScreenPopup(FolderClearPopupView, [FolderUserStore.currentFolder()]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
if (!MessagelistUserStore.isLoading()) {
|
MessagelistUserStore.isLoading()
|
||||||
MessagelistUserStore.reload(false, true);
|
|| MessagelistUserStore.reload(false, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardCommand() {
|
forwardCommand() {
|
||||||
|
|
@ -251,9 +290,8 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteWithoutMoveCommand() {
|
deleteWithoutMoveCommand() {
|
||||||
if (SettingsCapa('DangerousActions')) {
|
SettingsCapa('DangerousActions')
|
||||||
moveMessagesToFolderType(FolderType.Trash, true);
|
&& moveMessagesToFolderType(FolderType.Trash, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCommand() {
|
deleteCommand() {
|
||||||
|
|
@ -289,50 +327,6 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
showMessageComposer();
|
showMessageComposer();
|
||||||
}
|
}
|
||||||
|
|
||||||
goToUpOrDown(up) {
|
|
||||||
if (MessagelistUserStore.hasChecked()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimeout(iGoToUpOrDownTimeout);
|
|
||||||
iGoToUpOrDownTimeout = setTimeout(() => {
|
|
||||||
let prev, next, temp, current;
|
|
||||||
|
|
||||||
this.messageListPaginator().find(item => {
|
|
||||||
if (item) {
|
|
||||||
if (current) {
|
|
||||||
next = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.current) {
|
|
||||||
current = item;
|
|
||||||
prev = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (up ? prev : next) {
|
|
||||||
if (SettingsUserStore.usePreviewPane() || MessageUserStore.message()) {
|
|
||||||
this.selector.iSelectNextHelper = up ? -1 : 1;
|
|
||||||
} else {
|
|
||||||
this.selector.iFocusedNextHelper = up ? -1 : 1;
|
|
||||||
}
|
|
||||||
this.selector.unselect();
|
|
||||||
this.gotoPage(up ? prev : next);
|
|
||||||
}
|
|
||||||
}, 350);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelSearch() {
|
cancelSearch() {
|
||||||
MessagelistUserStore.mainSearch('');
|
MessagelistUserStore.mainSearch('');
|
||||||
this.focusSearch(false);
|
this.focusSearch(false);
|
||||||
|
|
@ -349,24 +343,6 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sToFolderFullName
|
|
||||||
* @param {boolean} bCopy
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
moveSelectedMessagesToFolder(sToFolderFullName, bCopy) {
|
|
||||||
if (MessagelistUserStore.hasCheckedOrSelected()) {
|
|
||||||
moveMessagesToFolder(
|
|
||||||
FolderUserStore.currentFolderFullName(),
|
|
||||||
MessagelistUserStore.listCheckedOrSelectedUidsWithSubMails(),
|
|
||||||
sToFolderFullName,
|
|
||||||
bCopy
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
listSetSeen() {
|
listSetSeen() {
|
||||||
listAction(
|
listAction(
|
||||||
FolderUserStore.currentFolderFullName(),
|
FolderUserStore.currentFolderFullName(),
|
||||||
|
|
@ -437,49 +413,9 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
flagMessages(currentMessage) {
|
|
||||||
const checked = MessagelistUserStore.listCheckedOrSelected();
|
|
||||||
if (currentMessage) {
|
|
||||||
const checkedUids = checked.map(message => message.uid);
|
|
||||||
if (checkedUids.includes(currentMessage.uid)) {
|
|
||||||
listAction(
|
|
||||||
currentMessage.folder,
|
|
||||||
currentMessage.isFlagged() ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
|
||||||
checked
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
listAction(
|
|
||||||
currentMessage.folder,
|
|
||||||
currentMessage.isFlagged() ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
|
||||||
[currentMessage]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flagMessagesFast(bFlag) {
|
|
||||||
const checked = MessagelistUserStore.listCheckedOrSelected();
|
|
||||||
if (checked.length) {
|
|
||||||
if (undefined === bFlag) {
|
|
||||||
const flagged = checked.filter(message => message.isFlagged());
|
|
||||||
listAction(
|
|
||||||
checked[0].folder,
|
|
||||||
checked.length === flagged.length ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
|
||||||
checked
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
listAction(
|
|
||||||
checked[0].folder,
|
|
||||||
!bFlag ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
|
||||||
checked
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seenMessagesFast(seen) {
|
seenMessagesFast(seen) {
|
||||||
const checked = MessagelistUserStore.listCheckedOrSelected();
|
const checked = MessagelistUserStore.listCheckedOrSelected();
|
||||||
if (checked.length && null != seen) {
|
if (checked.length) {
|
||||||
listAction(
|
listAction(
|
||||||
checked[0].folder,
|
checked[0].folder,
|
||||||
seen ? MessageSetAction.SetSeen : MessageSetAction.UnsetSeen,
|
seen ? MessageSetAction.SetSeen : MessageSetAction.UnsetSeen,
|
||||||
|
|
@ -500,7 +436,7 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
}
|
}
|
||||||
|
|
||||||
gotoThread(message) {
|
gotoThread(message) {
|
||||||
if (0 < message?.threadsLen()) {
|
if (message?.threadsLen()) {
|
||||||
MessagelistUserStore.pageBeforeThread(MessagelistUserStore.page());
|
MessagelistUserStore.pageBeforeThread(MessagelistUserStore.page());
|
||||||
|
|
||||||
hasher.setHash(
|
hasher.setHash(
|
||||||
|
|
@ -549,7 +485,15 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
eqs(event, '.checkboxCheckAll') && this.checkAll(!this.checkAll());
|
eqs(event, '.checkboxCheckAll') && this.checkAll(!this.checkAll());
|
||||||
|
|
||||||
el = eqs(event, '.flagParent');
|
el = eqs(event, '.flagParent');
|
||||||
el && this.flagMessages(ko.dataFor(el));
|
let currentMessage = el && ko.dataFor(el);
|
||||||
|
if (currentMessage) {
|
||||||
|
const checked = MessagelistUserStore.listCheckedOrSelected();
|
||||||
|
listAction(
|
||||||
|
currentMessage.folder,
|
||||||
|
currentMessage.isFlagged() ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
||||||
|
checked.find(message => message.uid == currentMessage.uid) ? checked : [currentMessage]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
el = eqs(event, '.threads-len');
|
el = eqs(event, '.threads-len');
|
||||||
el && this.gotoThread(ko.dataFor(el));
|
el && this.gotoThread(ko.dataFor(el));
|
||||||
|
|
@ -642,7 +586,14 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
|
|
||||||
// important - star/flag messages
|
// important - star/flag messages
|
||||||
registerShortcut('i', '', [Scope.MessageList, Scope.MessageView], () => {
|
registerShortcut('i', '', [Scope.MessageList, Scope.MessageView], () => {
|
||||||
this.flagMessagesFast();
|
const checked = MessagelistUserStore.listCheckedOrSelected();
|
||||||
|
if (checked.length) {
|
||||||
|
listAction(
|
||||||
|
checked[0].folder,
|
||||||
|
checked.every(message => message.isFlagged()) ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
||||||
|
checked
|
||||||
|
);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -715,7 +666,7 @@ export class MailMessageList extends AbstractViewRight {
|
||||||
addShortcut('arrowleft', 'meta', Scope.MessageView, ()=>false);
|
addShortcut('arrowleft', 'meta', Scope.MessageView, ()=>false);
|
||||||
addShortcut('arrowright', 'meta', Scope.MessageView, ()=>false);
|
addShortcut('arrowright', 'meta', Scope.MessageView, ()=>false);
|
||||||
|
|
||||||
addShortcut('f', 'meta', Scope.MessageList, ()=>this.advancedSearchClick());
|
addShortcut('f', 'meta', Scope.MessageList, this.advancedSearchClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
advancedSearchClick() {
|
advancedSearchClick() {
|
||||||
|
|
|
||||||
|
|
@ -441,10 +441,6 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
return MessagelistUserStore.isDraftFolder() || MessagelistUserStore.isSentFolder();
|
return MessagelistUserStore.isDraftFolder() || MessagelistUserStore.isSentFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
composeClick() {
|
|
||||||
showMessageComposer();
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollMessageToTop() {
|
scrollMessageToTop() {
|
||||||
oMessageScrollerDom().scrollTop = (50 < oMessageScrollerDom().scrollTop) ? 50 : 0;
|
oMessageScrollerDom().scrollTop = (50 < oMessageScrollerDom().scrollTop) ? 50 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue