diff --git a/.gitignore b/.gitignore
index c88cfb29614..dbdbc28ef74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ program/js/jquery.min.js
program/js/jstz.min.js
program/js/publickey.js
program/js/tinymce/
+**/*.min.js
# eslint dependencies
/node_modules
diff --git a/index.php b/index.php
index 83d9be2f9e9..5cb04c169fe 100644
--- a/index.php
+++ b/index.php
@@ -226,7 +226,7 @@
}
if ($RCMAIL->output->ajax_call || $RCMAIL->output->get_env('framed')) {
- $RCMAIL->output->command('session_error', $RCMAIL->url(['_err' => 'session']));
+ $RCMAIL->output->add_js_call('session_error', $RCMAIL->url(['_err' => 'session']));
$RCMAIL->output->send('iframe');
}
diff --git a/installer/client.js b/installer/client.js
index 7bfb7c1e1a4..1d8e7b30d1c 100644
--- a/installer/client.js
+++ b/installer/client.js
@@ -45,3 +45,35 @@ function removehostfield(row) {
var container = document.getElementById('defaulthostlist');
container.removeChild(row);
}
+
+function addOnclickCallback(id, callback) {
+ var elem = document.getElementById(id);
+ if (!elem) {
+ console.error('No element found with ID "' + id + '", cannot add callback!');
+ return false;
+ }
+ elem.addEventListener('click', callback);
+}
+
+document.addEventListener('DOMContentLoaded', function () {
+ addOnclickCallback('button-save-config', function () {
+ document.getElementById('getconfig_form').submit();
+ });
+
+ addOnclickCallback('button-download-config', function () {
+ location.href = 'index.php?_getconfig=1';
+ });
+
+ addOnclickCallback('button-continue-step-3', function () {
+ location.href = './index.php?_step=3';
+ });
+
+ addOnclickCallback('remove-host-field', function (event) {
+ removehostfield(event.target.parentNode);
+ return false;
+ });
+
+ addOnclickCallback('add-host-field', function () {
+ addhostfield();
+ });
+});
diff --git a/installer/config.php b/installer/config.php
index 02e6498686f..8f2c3d5dfe9 100644
--- a/installer/config.php
+++ b/installer/config.php
@@ -42,13 +42,13 @@
echo ' ';
$button_txt = html::quote('Save in ' . $dir);
- $save_button = ' ';
+ $save_button = ' ';
}
echo '
Copy or download the following configuration and save it';
echo ' as config.inc.php within the ' . RCUBE_CONFIG_DIR . ' directory of your Roundcube installation. ';
echo ' Make sure that there are no characters before the <?php bracket when saving the file.';
- echo ' ';
+ echo ' ';
echo $save_button;
if ($RCI->legacy_config) {
@@ -65,7 +65,7 @@
echo '
Of course there are more options to configure.
Have a look at the defaults.inc.php file or visit Howto_Config to find out.
';
- echo '
';
+ echo '
';
// echo '';
echo "\n \n";
@@ -327,14 +327,14 @@
foreach ($default_hosts as $host) {
echo '' . $text_imaphost->show($host);
if ($i++ > 0) {
- echo '
remove ';
+ echo '
remove ';
}
echo '
';
}
?>
-
+
The IMAP host(s) chosen to perform the log-in
Leave blank to show a textbox at login. To use SSL/STARTTLS connection add ssl:// or tls:// prefix. It can also contain the port number, e.g. tls://imap.domain.tld:143.
diff --git a/plugins/acl/acl.php b/plugins/acl/acl.php
index 20aff988d1f..d86f750b222 100644
--- a/plugins/acl/acl.php
+++ b/plugins/acl/acl.php
@@ -135,7 +135,7 @@ public function acl_autocomplete()
$users = array_values($keys);
}
- $this->rc->output->command('ksearch_query_results', $users, $search, $reqid);
+ $this->rc->output->add_js_call('ksearch_query_results', $users, $search, $reqid);
$this->rc->output->send();
}
@@ -533,7 +533,7 @@ private function action_save()
if ($user != $self && $username != $self) {
if ($this->rc->storage->set_acl($mbox, $user, $acl)) {
$display = $this->resolve_acl_identifier($username, $title);
- $this->rc->output->command('acl_update', [
+ $this->rc->output->add_js_call('acl_update', [
'id' => rcube_utils::html_identifier($user),
'username' => $username,
'title' => $title,
@@ -566,7 +566,7 @@ private function action_delete()
foreach ($user as $u) {
$u = trim($u);
if ($this->rc->storage->delete_acl($mbox, $u)) {
- $this->rc->output->command('acl_remove_row', rcube_utils::html_identifier($u));
+ $this->rc->output->add_js_call('acl_remove_row', rcube_utils::html_identifier($u));
} else {
$error = true;
}
@@ -599,7 +599,7 @@ private function action_list()
$out = preg_replace(['/^
]+>/', '/<\/table>$/'], '', $out);
- $this->rc->output->command('acl_list_update', $out);
+ $this->rc->output->add_js_call('acl_list_update', $out);
}
/**
diff --git a/plugins/acl/skins/elastic/templates/table.html b/plugins/acl/skins/elastic/templates/table.html
index 0a4b581337e..84032704036 100644
--- a/plugins/acl/skins/elastic/templates/table.html
+++ b/plugins/acl/skins/elastic/templates/table.html
@@ -18,7 +18,7 @@
-
+
diff --git a/plugins/archive/archive.php b/plugins/archive/archive.php
index e9178b97ada..1034a2c4c99 100644
--- a/plugins/archive/archive.php
+++ b/plugins/archive/archive.php
@@ -227,7 +227,7 @@ public function move_messages()
// @phpstan-ignore-next-line
if ($this->result['error']) {
if (!$from_show_action) {
- $rcmail->output->command('list_mailbox');
+ $rcmail->output->add_js_call('list_mailbox');
}
$rcmail->output->show_message($this->gettext('archiveerror'), 'warning');
@@ -236,7 +236,7 @@ public function move_messages()
if (!empty($_POST['_refresh'])) {
// FIXME: send updated message rows instead of reloading the entire list
- $rcmail->output->command('refresh_list');
+ $rcmail->output->add_js_call('refresh_list');
$addrows = false;
} else {
$addrows = true;
@@ -249,9 +249,9 @@ public function move_messages()
if ($from_show_action) {
if ($next = rcube_utils::get_input_string('_next_uid', rcube_utils::INPUT_GPC)) {
- $rcmail->output->command('show_message', $next);
+ $rcmail->output->add_js_call('show_message', $next);
} else {
- $rcmail->output->command('command', 'list');
+ $rcmail->output->add_js_call('command', 'list');
}
$rcmail->output->send();
@@ -287,8 +287,8 @@ public function move_messages()
$rcmail->output->set_env('current_page', $page);
$rcmail->output->set_env('pagecount', $pages);
$rcmail->output->set_env('exists', $exists);
- $rcmail->output->command('set_quota', rcmail_action::quota_content(null, $quota_root));
- $rcmail->output->command('set_rowcount', rcmail_action_mail_index::get_messagecount_text($msg_count), $mbox);
+ $rcmail->output->add_js_call('set_quota', rcmail_action::quota_content(null, $quota_root));
+ $rcmail->output->add_js_call('set_rowcount', rcmail_action_mail_index::get_messagecount_text($msg_count), $mbox);
if ($threading) {
$count = rcube_utils::get_input_string('_count', rcube_utils::INPUT_POST);
@@ -403,7 +403,7 @@ public function prefs_table($args)
'maxlength' => 30,
'folder_filter' => 'mail',
'folder_rights' => 'w',
- 'onchange' => "if ($(this).val() == 'INBOX') $(this).val('')",
+ 'data-onchange' => ['reset_value_if_inbox', '__THIS__'],
'class' => 'custom-select',
]);
} else {
diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js
index 865380d8cd7..fc745fe709c 100644
--- a/plugins/enigma/enigma.js
+++ b/plugins/enigma/enigma.js
@@ -567,14 +567,15 @@ rcube_webmail.prototype.enigma_compose_handler = function (props) {
};
// Import attached keys/certs file
-rcube_webmail.prototype.enigma_import_attachment = function (mime_id) {
+$('[data-event-handle="enigma_import_attachment"]').on('click', function (event) {
+ var mime_id = event.target.dataset.part;
var lock = this.set_busy(true, 'loading'),
post = { _uid: this.env.uid, _mbox: this.env.mailbox, _part: mime_id };
this.http_post('plugin.enigmaimport', post, lock);
return false;
-};
+});
// password request popup
rcube_webmail.prototype.enigma_password_request = function (data) {
@@ -745,3 +746,16 @@ rcube_webmail.prototype.enigma_find_publickey = function (email) {
}
);
};
+
+// Some event handlers.
+$('[data-event-handle="enigma_import_upload"]').on('click', function (event) {
+ return window.rcmail.command('plugin.enigma-import', '', event.target, event);
+});
+
+$('[data-event-handle="enigma_import_search"]').on('click', function (event) {
+ return window.rcmail.command('plugin.enigma-import-search', '', event.target, event);
+});
+
+$('[data-event-handle="enigma_import_search"]').on('click', function (event) {
+ window.rcmail.command('menu-open', 'enigmamenu', event.target, event);
+});
diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php
index 1eea580cace..723f6b0f014 100644
--- a/plugins/enigma/lib/enigma_ui.php
+++ b/plugins/enigma/lib/enigma_ui.php
@@ -174,7 +174,7 @@ public function password_prompt($status, $params = [])
}
if (preg_match('/^(send|plugin.enigmaimport|plugin.enigmakeys)$/', $this->rc->action)) {
- $this->rc->output->command('enigma_password_request', $data);
+ $this->rc->output->add_js_call('enigma_password_request', $data);
} else {
$this->rc->output->set_env('enigma_password_request', $data);
}
@@ -254,7 +254,7 @@ private function key_list()
// Add rows
foreach ($list as $key) {
- $this->rc->output->command('enigma_add_list_row', [
+ $this->rc->output->add_js_call('enigma_add_list_row', [
'name' => rcube::Q($key->name),
'id' => $key->id,
'flags' => $key->is_private() ? 'p' : '',
@@ -266,7 +266,7 @@ private function key_list()
$this->rc->output->set_env('search_request', $search);
$this->rc->output->set_env('pagecount', ceil($listsize / $pagesize));
$this->rc->output->set_env('current_page', $page);
- $this->rc->output->command('set_rowcount', $this->get_rowcount_text($listsize, $size, $page));
+ $this->rc->output->add_js_call('set_rowcount', $this->get_rowcount_text($listsize, $size, $page));
$this->rc->output->send();
}
@@ -323,7 +323,7 @@ private function key_info()
$this->data = $res;
} else { // error
$this->rc->output->show_message('enigma.keyopenerror', 'error');
- $this->rc->output->command('parent.enigma_loadframe');
+ $this->rc->output->add_js_call('parent.enigma_loadframe');
$this->rc->output->send('iframe');
}
@@ -528,14 +528,14 @@ private function key_import()
if (is_array($result)) {
if (rcube_utils::get_input_value('_generated', rcube_utils::INPUT_POST)) {
- $this->rc->output->command('enigma_key_create_success');
+ $this->rc->output->add_js_call('enigma_key_create_success');
$this->rc->output->show_message('enigma.keygeneratesuccess', 'confirmation');
} else {
$this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
['new' => $result['imported'], 'old' => $result['unchanged']]);
if ($result['imported'] && !empty($_POST['_refresh'])) {
- $this->rc->output->command('enigma_list', 1, false);
+ $this->rc->output->add_js_call('enigma_list', 1, false);
}
}
} else {
@@ -550,13 +550,13 @@ private function key_import()
if (is_array($result)) {
// reload list if any keys has been added
if ($result['imported']) {
- $this->rc->output->command('parent.enigma_list', 1);
+ $this->rc->output->add_js_call('parent.enigma_list', 1);
}
$this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
['new' => $result['imported'], 'old' => $result['unchanged']]);
- $this->rc->output->command('parent.enigma_import_success');
+ $this->rc->output->add_js_call('parent.enigma_import_success');
} elseif ($result instanceof enigma_error && $result->getCode() == enigma_error::BADPASS) {
$this->password_prompt($result);
} else {
@@ -611,7 +611,7 @@ public function tpl_key_import_form($attrib)
$max_filesize = rcmail_action::upload_init();
$upload_button = new html_button([
'class' => 'button import',
- 'onclick' => "return rcmail.command('plugin.enigma-import','',this,event)",
+ 'data-event-handle' => 'enigma_import_upload',
]);
$form = html::div(null, html::p(null, rcube::Q($this->enigma->gettext('keyimporttext'), 'show'))
@@ -639,7 +639,7 @@ public function tpl_key_import_form($attrib)
$search_button = new html_button([
'class' => 'button search',
- 'onclick' => "return rcmail.command('plugin.enigma-import-search','',this,event)",
+ 'data-event-handle' => 'enigma_import_search',
]);
$form = html::div(null,
@@ -710,7 +710,7 @@ private function key_generate()
]);
if ($result instanceof enigma_key) {
- $this->rc->output->command('enigma_key_create_success');
+ $this->rc->output->add_js_call('enigma_key_create_success');
$this->rc->output->show_message('enigma.keygeneratesuccess', 'confirmation');
} else {
$this->rc->output->show_message('enigma.keygenerateerror', 'error');
@@ -820,12 +820,12 @@ private function key_delete()
if ($res !== true) {
$this->rc->output->show_message('enigma.keyremoveerror', 'error');
- $this->rc->output->command('enigma_list');
+ $this->rc->output->add_js_call('enigma_list');
$this->rc->output->send();
}
}
- $this->rc->output->command('enigma_list');
+ $this->rc->output->add_js_call('enigma_list');
$this->rc->output->show_message('enigma.keyremovesuccess', 'confirmation');
$this->rc->output->send();
}
@@ -848,7 +848,7 @@ private function compose_ui()
$this->enigma->add_button([
'type' => 'link',
'command' => 'plugin.enigma',
- 'onclick' => "rcmail.command('menu-open', 'enigmamenu', event.target, event)",
+ 'data-event-handle' => 'enigma_menu_open',
'class' => 'button enigma',
'title' => 'encryptionoptions',
'label' => 'encryption',
@@ -1107,7 +1107,8 @@ public function message_output($p)
$p['content'] = html::p(['class' => 'enigmaattachment boxinformation aligned-buttons'],
html::span(null, rcube::Q($this->enigma->gettext('keyattfound'))) .
html::tag('button', [
- 'onclick' => 'return ' . rcmail_output::JS_OBJECT_NAME . ".enigma_import_attachment('" . rcube::JQ($part) . "')",
+ 'data-event-handle' => 'enigma_import_attachment',
+ 'data-part' => $part,
'title' => $this->enigma->gettext('keyattimport'),
'class' => 'import btn-sm',
], rcube::Q($this->rc->gettext('import'))
@@ -1190,7 +1191,7 @@ public function message_ready($p)
if (!empty($msg)) {
if (!empty($vars['email'])) {
- $this->rc->output->command('enigma_key_not_found', [
+ $this->rc->output->add_js_call('enigma_key_not_found', [
'email' => $vars['email'],
'text' => $this->rc->gettext(['name' => $msg, 'vars' => $vars]),
'title' => $this->enigma->gettext('keynotfound'),
diff --git a/plugins/help/help.php b/plugins/help/help.php
index d3d1e5a0a61..3a6d3bc74ab 100644
--- a/plugins/help/help.php
+++ b/plugins/help/help.php
@@ -108,7 +108,8 @@ public function tablink($attrib)
// so button() will translate it correctly
$attrib['title'] = $attrib['label'];
- $attrib['onclick'] = sprintf("return show_help_content('%s', event)", $attrib['action']);
+ $attrib['data-action'] = $attrib['action'];
+ $attrib['data-event-handle'] = 'call_show_help_content';
return $rcmail->output->button($attrib);
}
diff --git a/plugins/jqueryui/jqueryui.php b/plugins/jqueryui/jqueryui.php
index c971bd133f2..0a3982f2e54 100644
--- a/plugins/jqueryui/jqueryui.php
+++ b/plugins/jqueryui/jqueryui.php
@@ -120,7 +120,8 @@ public static function miniColors()
$rcube->output->include_css('plugins/jqueryui/' . $css);
$rcube->output->include_script($script, 'head', false);
- $rcube->output->add_script('$.fn.miniColors = $.fn.minicolors; $("input.colors").minicolors(' . $config_str . ')', 'docready');
+ $rcube->output->include_script('plugins/jqueryui/js/jqueryui-minicolors-init.js');
+ $rcube->output->add_js_call('jqueryui_minicolors_init', $config_str);
$rcube->output->set_env('minicolors_config', $config);
}
diff --git a/plugins/jqueryui/js/jqueryui-minicolors-init.js b/plugins/jqueryui/js/jqueryui-minicolors-init.js
new file mode 100644
index 00000000000..e5ba4c2feb5
--- /dev/null
+++ b/plugins/jqueryui/js/jqueryui-minicolors-init.js
@@ -0,0 +1,4 @@
+rcube_webmail.prototype.jqueryui_minicolors_init = function (config) {
+ $.fn.miniColors = $.fn.minicolors;
+ $("input.colors").minicolors(config);
+}
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
index 15b468bac34..8fb92b21547 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -133,7 +133,7 @@ public function start($mode = null)
// reload interface in case of possible error when specified script wasn't found (#1489412)
if ($script_name !== null && !empty($list) && !in_array($script_name, $list)) {
- $this->rc->output->command('reload', 500);
+ $this->rc->output->add_js_call('reload', 500);
}
// to disable 'Add filter' button set env variable
@@ -306,7 +306,7 @@ public function actions()
if ($result === true) {
$this->rc->output->show_message('managesieve.filterdeleted', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'del', ['id' => $fid]);
+ $this->rc->output->add_js_call('managesieve_updatelist', 'del', ['id' => $fid]);
} else {
$this->rc->output->show_message('managesieve.filterdeleteerror', 'error');
}
@@ -344,7 +344,7 @@ public function actions()
$result = $this->list_rules();
$this->rc->output->show_message('managesieve.moved', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'list',
+ $this->rc->output->add_js_call('managesieve_updatelist', 'list',
['list' => $result, 'clear' => true, 'set' => $to]);
} else {
$this->rc->output->show_message('managesieve.moveerror', 'error');
@@ -367,7 +367,7 @@ public function actions()
} else {
$this->rc->output->show_message('managesieve.activated', 'confirmation');
}
- $this->rc->output->command('managesieve_updatelist', 'update',
+ $this->rc->output->add_js_call('managesieve_updatelist', 'update',
['id' => $fid, 'disabled' => $rule['disabled']]);
} else {
if ($rule['disabled']) {
@@ -386,7 +386,7 @@ public function actions()
if ($result === true) {
$this->rc->output->set_env('active_sets', $this->active);
$this->rc->output->show_message('managesieve.setactivated', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setact',
+ $this->rc->output->add_js_call('managesieve_updatelist', 'setact',
['name' => $script_name, 'active' => true, 'all' => !$kep14]);
} else {
$this->rc->output->show_message('managesieve.setactivateerror', 'error');
@@ -402,7 +402,7 @@ public function actions()
if ($result === true) {
$this->rc->output->set_env('active_sets', $this->active);
$this->rc->output->show_message('managesieve.setdeactivated', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setact',
+ $this->rc->output->add_js_call('managesieve_updatelist', 'setact',
['name' => $script_name, 'active' => false]);
} else {
$this->rc->output->show_message('managesieve.setdeactivateerror', 'error');
@@ -417,7 +417,7 @@ public function actions()
if ($result === true) {
$this->rc->output->show_message('managesieve.setdeleted', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setdel', ['name' => $script_name]);
+ $this->rc->output->add_js_call('managesieve_updatelist', 'setdel', ['name' => $script_name]);
$this->rc->session->remove('managesieve_current');
} else {
$this->rc->output->show_message('managesieve.setdeleteerror', 'error');
@@ -447,23 +447,23 @@ public function actions()
} elseif ($action == 'list') {
$result = $this->list_rules();
- $this->rc->output->command('managesieve_updatelist', 'list', ['list' => $result]);
+ $this->rc->output->add_js_call('managesieve_updatelist', 'list', ['list' => $result]);
} elseif ($action == 'ruleadd') {
$rid = rcube_utils::get_input_string('_rid', rcube_utils::INPUT_POST);
$id = $this->genid();
$content = $this->rule_div($fid, $id, false, !empty($_SESSION['managesieve-compact-form']));
- $this->rc->output->command('managesieve_rulefill', $content, $id, $rid);
+ $this->rc->output->add_js_call('managesieve_rulefill', $content, $id, $rid);
} elseif ($action == 'actionadd') {
$aid = rcube_utils::get_input_string('_aid', rcube_utils::INPUT_POST);
$id = $this->genid();
$content = $this->action_div($fid, $id, false);
- $this->rc->output->command('managesieve_actionfill', $content, $id, $aid);
+ $this->rc->output->add_js_call('managesieve_actionfill', $content, $id, $aid);
} elseif ($action == 'addresses') {
$aid = rcube_utils::get_input_string('_aid', rcube_utils::INPUT_POST);
- $this->rc->output->command('managesieve_vacation_addresses_update', $aid, $this->user_emails());
+ $this->rc->output->add_js_call('managesieve_vacation_addresses_update', $aid, $this->user_emails());
}
$this->rc->output->send();
@@ -515,7 +515,7 @@ public function saveraw()
}
} else {
$this->rc->output->show_message('managesieve.setupdated', 'confirmation');
- $this->rc->output->command('parent.managesieve_updatelist', 'refresh');
+ $this->rc->output->add_js_call('parent.managesieve_updatelist', 'refresh');
}
$this->send();
@@ -602,7 +602,7 @@ public function save()
$index = array_search($name, $list);
$this->rc->output->show_message('managesieve.setcreated', 'confirmation');
- $this->rc->output->command('parent.managesieve_updatelist', 'setadd',
+ $this->rc->output->add_js_call('parent.managesieve_updatelist', 'setadd',
['name' => $name, 'index' => $index]);
} elseif ($error) {
$this->rc->output->show_message($error, 'error');
@@ -1217,9 +1217,9 @@ public function save()
'id' => $fid,
'disabled' => $this->form['disabled'],
];
- $this->rc->output->command('parent.managesieve_updatelist', isset($new) ? 'add' : 'update', $args);
+ $this->rc->output->add_js_call('parent.managesieve_updatelist', isset($new) ? 'add' : 'update', $args);
} else {
- $this->rc->output->command('managesieve_dialog_close');
+ $this->rc->output->add_js_call('managesieve_dialog_close');
$this->rc->output->send('iframe');
}
} else {
@@ -1321,7 +1321,7 @@ public function filtersets_list($attrib, $no_env = false)
'name' => '_set',
'id' => $attrib['id'],
'class' => 'custom-select',
- 'onchange' => $this->rc->task != 'mail' ? 'rcmail.managesieve_set()' : '',
+ 'data-onchange' => $this->rc->task != 'mail' ? ['managesieve_set'] : '',
]);
if ($list) {
@@ -1567,7 +1567,7 @@ public function filter_form($attrib)
if ($compact) {
$select = new html_select(['name' => '_join', 'id' => '_join', 'class' => 'custom-select',
- 'onchange' => 'rule_join_radio(this.value)']);
+ 'data-onchange' => ['managesieve_rule_join_radio_with_this_value']]);
foreach (['allof', 'anyof', 'any'] as $val) {
$select->add($this->plugin->gettext('filter' . $val), $val);
@@ -1592,7 +1592,7 @@ public function filter_form($attrib)
// any, allof, anyof radio buttons
$field_id = '_allof';
$input_join = new html_radiobutton(['name' => '_join', 'id' => $field_id, 'value' => 'allof',
- 'onclick' => 'rule_join_radio(\'allof\')', 'class' => 'radio']);
+ 'data-event-handle' => 'managesieve_rule_join_radio', 'data-value' => 'allof', 'class' => 'radio']);
if (isset($scr) && !$any) {
$input_join = $input_join->show($scr['join'] ? 'allof' : '');
@@ -1604,7 +1604,7 @@ public function filter_form($attrib)
$field_id = '_anyof';
$input_join = new html_radiobutton(['name' => '_join', 'id' => $field_id, 'value' => 'anyof',
- 'onclick' => 'rule_join_radio(\'anyof\')', 'class' => 'radio']);
+ 'data-event-handle' => 'managesieve_rule_join_radio', 'data-value' => 'anyof', 'class' => 'radio']);
if (isset($scr) && !$any) {
$input_join = $input_join->show($scr['join'] ? '' : 'anyof');
@@ -1616,7 +1616,7 @@ public function filter_form($attrib)
$field_id = '_any';
$input_join = new html_radiobutton(['name' => '_join', 'id' => $field_id, 'value' => 'any',
- 'onclick' => 'rule_join_radio(\'any\')', 'class' => 'radio']);
+ 'data-event-handle' => 'managesieve_rule_join_radio', 'data-value' => 'any', 'class' => 'radio']);
$input_join = $input_join->show($any ? 'any' : '');
@@ -1687,7 +1687,7 @@ public function rule_div($fid, $id, $div = true, $compact = false)
// headers select
$select_header = new html_select(['name' => "_header[{$id}]", 'id' => 'header' . $id,
- 'onchange' => 'rule_header_select(' . $id . ')', 'class' => 'custom-select']);
+ 'data-onchange' => ['rule_header_select', $id]), 'class' => 'custom-select'];
foreach ($this->headers as $index => $header) {
$header = $this->rc->text_exists($index) ? $this->plugin->gettext($index) : $header;
@@ -1872,7 +1872,7 @@ public function rule_div($fid, $id, $div = true, $compact = false)
'name' => "_rule_spamtest_op[{$id}]",
'id' => 'rule_spamtest_op' . $id,
'class' => 'input-group-prepend custom-select',
- 'onchange' => 'rule_spamtest_select(' . $id . ')',
+ 'data-onchange' => ['rule_spamtest_select', $id],
]);
$select_spamtest_op->add(rcube::Q($this->plugin->gettext('spamtestisunknown')), '');
$select_spamtest_op->add(rcube::Q($this->plugin->gettext('spamtestisgreaterthan')), 'value-gt');
@@ -1909,7 +1909,7 @@ public function rule_div($fid, $id, $div = true, $compact = false)
'name' => "_rule_mod[{$id}]",
'id' => 'rule_mod_op' . $id,
'class' => 'custom-select',
- 'onchange' => 'rule_mod_select(' . $id . ')',
+ 'data-onchange' => ['rule_mod_select', $id],
]);
$select_mod->add(rcube::Q($this->plugin->gettext('none')), '');
$select_mod->add(rcube::Q($this->plugin->gettext('address')), 'address');
@@ -1955,7 +1955,7 @@ public function rule_div($fid, $id, $div = true, $compact = false)
$select_mime = new html_select([
'name' => "_rule_mime_type[{$id}]",
'id' => 'rule_mime_type' . $id,
- 'style' => 'min-width:8em', 'onchange' => 'rule_mime_select(' . $id . ')',
+ 'style' => 'min-width:8em', 'data-onchange' => ['rule_mime_select', $id],
'class' => 'custom-select',
]);
$select_mime->add('-', '');
@@ -1994,7 +1994,7 @@ public function rule_div($fid, $id, $div = true, $compact = false)
'name' => "_rule_trans[{$id}]",
'id' => 'rule_trans_op' . $id,
'class' => 'custom-select',
- 'onchange' => 'rule_trans_select(' . $id . ')',
+ 'data-onchange' => ['rule_trans_select', $id],
]);
$select_mod->add(rcube::Q($this->plugin->gettext('text')), 'text');
$select_mod->add(rcube::Q($this->plugin->gettext('undecoded')), 'raw');
@@ -2108,25 +2108,66 @@ public function rule_div($fid, $id, $div = true, $compact = false)
$out .= '';
if (!$compact) {
- $out .= '';
- $out .= sprintf(''
- . '%s ', $id, $adv_title, $id, $adv_title);
- $out .= ' ';
+ $out .= html::tag('td', ['class' => 'advbutton'],
+ html::a([
+ 'href' => '#',
+ 'id' => "ruleadv{$id}",
+ 'title' => $adv_title,
+ 'data-id' => $id,
+ 'data-event-handle' => 'managesieve_rule_adv_switch',
+ 'class' => 'show',
+ ],
+ html::span(['class' => 'inner'], $adv_title)
+ )
+ );
}
- $out .= '' . $aout . '
';
- $out .= '' . $tout . "\n";
- $out .= '' . $mout . '
';
- $out .= ' ';
+ $out .= html::tag('td', ['class' => 'rowactions'],
+ html::div(['class' => 'flexbox'], $aout)
+ );
+ $out .= html::tag('td', ['class' => 'rowtargets'], [
+ $tout,
+ html::div([
+ 'id' => "rule_advanced{$id}",
+ 'style' => 'display:none',
+ 'class' => 'advanced',
+ ],
+ $mout),
+ ]);
+
$out .= '';
if ($compact) {
- $out .= sprintf(''
- . '%s ', $id, $adv_title, $id, $adv_title);
+ $out .= html::a([
+ 'href' => '#',
+ 'id' => "ruleadv{$id}",
+ 'title' => $adv_title,
+ 'data-id' => $id,
+ 'data-event-handle' => 'managesieve_rule_adv_switch',
+ 'class' => 'advanced show',
+ ],
+ html::span(['class' => 'inner'], $adv_title)
+ );
}
- $out .= sprintf(''
- . '%s ', $id, $add_title, $id, $add_title);
- $out .= sprintf(''
- . '%s ', $id, $del_title, $id, $rows_num < 2 ? ' disabled' : '', $del_title);
+ $out .= html::a([
+ 'href' => '#',
+ 'id' => "ruleadd{$id}",
+ 'title' => $add_title,
+ 'data-id' => $id,
+ 'data-event-handle' => 'managesieve_ruleadd',
+ 'class' => 'button create add',
+ ],
+ html::span(['class' => 'inner'], $add_title)
+ );
+ $out .= html::a([
+ 'href' => '#',
+ 'id' => "ruledel{$id}",
+ 'title' => $del_title,
+ 'data-id' => $id,
+ 'data-event-handle' => 'managesieve_ruledel',
+ 'class' => 'button delete del ' . $rows_num < 2 ? 'disabled' : '',
+ ],
+ html::span(['class' => 'inner'], $del_title)
+ );
$out .= ' ';
$out .= '
';
@@ -2211,7 +2252,7 @@ public function action_div($fid, $id, $div = true)
'name' => "_action_type[{$id}]",
'id' => 'action_type' . $id,
'class' => 'custom-select',
- 'onchange' => "action_type_select({$id})",
+ 'data-onchange' => ['managesieve_action_type_select', $id],
]);
if (in_array('fileinto', $this->exts)) {
$select_action->add($this->plugin->gettext('messagemoveto'), 'fileinto');
@@ -2373,7 +2414,7 @@ public function action_div($fid, $id, $div = true)
$out .= $this->list_input($id, 'action_addresses', $action['addresses'] ?? null,
30, false, ['class' => $this->error_class($id, 'action', 'addresses', 'action_addresses')]
)
- . html::a(['href' => '#', 'onclick' => rcmail_output::JS_OBJECT_NAME . ".managesieve_vacation_addresses({$id})"],
+ . html::a(['href' => '#', 'data-event-handle' => 'managesieve_vacation_addresses', 'data-id' => $id],
rcube::Q($this->plugin->gettext('filladdresses')));
$out .= '' . rcube::Q($this->plugin->gettext('vacationinterval')) . ' ';
$out .= '' . html::tag('input', [
@@ -2671,12 +2712,30 @@ public function action_div($fid, $id, $div = true)
// add/del buttons
$add_label = rcube::Q($this->plugin->gettext('add'));
$del_label = rcube::Q($this->plugin->gettext('del'));
- $out .= '
';
- $out .= sprintf(''
- . '%s ', $id, $add_label, $id, $add_label);
- $out .= sprintf(''
- . '%s ', $id, $del_label, $id, $rows_num < 2 ? ' disabled' : '', $del_label);
- $out .= ' ';
+ $out .= html::tag('td', ['class' => 'rowbuttons'],
+ html::a(
+ [
+ 'href' => '#',
+ 'id' => "actionadd{$id}",
+ 'title' => $add_label,
+ 'data-id' => $id,
+ 'data-event-handle' => 'managesieve_actionadd',
+ 'class' => 'button create add',
+ ],
+ html::span(['class' => 'inner'], $add_label),
+ ),
+ html::a(
+ [
+ 'href' => '#',
+ 'id' => "actiondel{$id}",
+ 'title' => $del_label,
+ 'data-id' => $id,
+ 'data-event-handle' => ['managesieve_actiondel',
+ 'class' => 'button delete del ' . ($rows_num < 2 ? 'disabled' : ''),
+ ],
+ html::span(['class' => 'inner'], $del_label),
+ )
+ );
$out .= '
';
@@ -2757,8 +2816,7 @@ protected function print_tips()
return;
}
- $script = rcmail_output::JS_OBJECT_NAME . '.managesieve_tip_register(' . json_encode($this->tips) . ');';
- $this->rc->output->add_script($script, 'docready');
+ $this->rc->output->add_js_call('managesieve_tip_register', $this->tips);
}
protected function list_input($id, $name, $value, $size = null, $hidden = false, $attrib = [])
@@ -3255,7 +3313,7 @@ protected function match_type_selector($name, $id, $test, $rule = null, $mode =
'id' => "{$name}{$id}",
'style' => 'display:' . (!in_array($rule, ['size', 'duplicate', 'spamtest']) ? 'inline' : 'none'),
'class' => 'operator_selector col-6 custom-select',
- 'onchange' => "{$name}_select(this, '{$id}')",
+ 'data-onchange' => ["managesieve_{$name}_select", '__THIS__', $id],
]);
$select_op->add(rcube::Q($this->plugin->gettext('filtercontains')), 'contains');
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
index ac7abe7e6a8..6afb627f2ff 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
@@ -393,12 +393,12 @@ public function vacation_form($attrib)
. (!empty($this->vacation['addresses']) ? rcube::Q(implode("\n", (array) $this->vacation['addresses']), 'strict', false) : '')
. '';
$status = new html_select(['name' => 'vacation_status', 'id' => 'vacation_status', 'class' => 'custom-select']);
- $action = new html_select(['name' => 'vacation_action', 'id' => 'vacation_action', 'class' => 'custom-select', 'onchange' => 'vacation_action_select()']);
+ $action = new html_select(['name' => 'vacation_action', 'id' => 'vacation_action', 'class' => 'custom-select', 'data-onchange' => ['vacation_action_select']]);
$addresses_link = new html_inputfield([
'type' => 'button',
'href' => '#',
'class' => 'button',
- 'onclick' => rcmail_output::JS_OBJECT_NAME . '.managesieve_vacation_addresses()',
+ 'data-event-handle' => 'managesieve_vacation_addresses',
]);
$redirect = !empty($this->vacation['action'])
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
index c9b43fa6227..f9769fc1ee0 100644
--- a/plugins/managesieve/managesieve.js
+++ b/plugins/managesieve/managesieve.js
@@ -537,10 +537,6 @@ rcube_webmail.prototype.managesieve_save = function () {
};
// Operations on filters form
-rcube_webmail.prototype.managesieve_ruleadd = function (id) {
- this.http_post('plugin.managesieve-action', '_act=ruleadd&_rid=' + id);
-};
-
rcube_webmail.prototype.managesieve_rulefill = function (content, id, after) {
if (content != '') {
// create new element
@@ -559,22 +555,6 @@ rcube_webmail.prototype.managesieve_rulefill = function (content, id, after) {
}
};
-rcube_webmail.prototype.managesieve_ruledel = function (id) {
- if ($('#ruledel' + id).hasClass('disabled')) {
- return;
- }
-
- this.confirm_dialog(this.get_label('managesieve.ruledeleteconfirm'), 'delete', function (e, ref) {
- var row = document.getElementById('rulerow' + id);
- row.parentNode.removeChild(row);
- ref.managesieve_formbuttons(document.getElementById('rules'));
- });
-};
-
-rcube_webmail.prototype.managesieve_actionadd = function (id) {
- this.http_post('plugin.managesieve-action', '_act=actionadd&_aid=' + id);
-};
-
rcube_webmail.prototype.managesieve_actionfill = function (content, id, after) {
if (content != '') {
var div = $('#actions')[0],
@@ -592,18 +572,6 @@ rcube_webmail.prototype.managesieve_actionfill = function (content, id, after) {
}
};
-rcube_webmail.prototype.managesieve_actiondel = function (id) {
- if ($('#actiondel' + id).hasClass('disabled')) {
- return;
- }
-
- this.confirm_dialog(this.get_label('managesieve.actiondeleteconfirm'), 'delete', function (e, ref) {
- var row = document.getElementById('actionrow' + id);
- row.parentNode.removeChild(row);
- ref.managesieve_formbuttons(document.getElementById('actions'));
- });
-};
-
// insert rule/action row in specified place on the list
rcube_webmail.prototype.managesieve_insertrow = function (div, row, after) {
var node = $('#' + ($(div).attr('id') == 'rules' ? 'rulerow' : 'actionrow') + after)[0];
@@ -627,12 +595,6 @@ rcube_webmail.prototype.managesieve_formbuttons = function (div) {
}
};
-// update vacation addresses field with user identities
-rcube_webmail.prototype.managesieve_vacation_addresses = function (id) {
- var lock = this.set_busy(true, 'loading');
- this.http_post('plugin.managesieve-action', { _act: 'addresses', _aid: id }, lock);
-};
-
// update vacation addresses field with user identities
rcube_webmail.prototype.managesieve_vacation_addresses_update = function (id, addresses) {
var field = $('#vacation_addresses,#action_addresses' + (id || ''));
@@ -747,6 +709,8 @@ function rule_op_select(obj, id, header) {
target.style.display = obj.value.match(/^(exists|notexists)$/) || header.match(/^(size|spamtest|message)$/) ? 'none' : '';
}
+rcube_webmail.prototype.managesieve_rule_op_select = rule_op_select;
+
function rule_trans_select(id) {
var obj = document.getElementById('rule_trans_op' + id),
target = document.getElementById('rule_trans_type' + id);
@@ -787,22 +751,6 @@ function rule_spamtest_select(id) {
$(obj)[obj.value ? 'removeClass' : 'addClass']('rounded-right');
}
-function rule_join_radio(value) {
- $('#rules').css('display', value == 'any' ? 'none' : 'block');
-}
-
-function rule_adv_switch(id, elem) {
- var elem = $(elem), enabled = elem.hasClass('hide'), adv = $('#rule_advanced' + id);
-
- if (enabled) {
- adv.get(0).style.display = 'none';
- elem.removeClass('hide').addClass('show');
- } else {
- adv.get(0).style.display = '';
- elem.removeClass('show').addClass('hide');
- }
-}
-
function rule_mime_select(id) {
var elem = $('#rule_mime_type' + id),
param_elem = $('#rule_mime_param' + id + '_list');
@@ -847,6 +795,8 @@ function action_type_select(id) {
}
}
+rcube_webmail.prototype.managesieve_action_type_select = action_type_select;
+
function vacation_action_select() {
var selected = $('#vacation_action').val();
@@ -1140,7 +1090,7 @@ var cmeditor;
function cmCreateErrorElem(msg) {
var marker = document.createElement('div');
marker.style.color = '#822';
- marker.innerHTML = '●';
+ marker.innerText = '●';
marker.title = msg;
return marker;
@@ -1283,3 +1233,77 @@ rcube_webmail.prototype.managesieve_dialog_resize = function (o) {
dialog.dialog('option', { height: Math.min(h - 20, height + 120), width: Math.min(w - 20, width + 65) });
};
+
+// Some event handlers.
+window.rcmail.addEventListener('init', function () {
+
+ $('[data-event-handle="managesieve_switch_nav_list"]').on('click', function (event) {
+ UI.switch_nav_list(event.target);
+ });
+
+ $('[data-event-handle="managesieve_ruleadd"]').on('click', function (event) {
+ const id = event.target.dataset.id;
+ this.http_post('plugin.managesieve-action', '_act=ruleadd&_rid=' + id);
+ return false;
+ });
+
+ $('[data-event-handle="managesieve_ruledel"]').on('click', function (event) {
+ const id = event.target.dataset.id;
+ if ($('#ruledel' + id).hasClass('disabled')) {
+ return;
+ }
+
+ this.confirm_dialog(this.get_label('managesieve.ruledeleteconfirm'), 'delete', function (e, ref) {
+ var row = document.getElementById('rulerow' + id);
+ row.parentNode.removeChild(row);
+ ref.managesieve_formbuttons(document.getElementById('rules'));
+ });
+ });
+
+ $('[data-event-handle="managesieve_actionadd"]').on('click', function (event) {
+ const id = event.target.dataset.id;
+ this.http_post('plugin.managesieve-action', '_act=actionadd&_aid=' + id);
+ });
+
+ $('[data-event-handle="managesieve_actiondel"]').on('click', function (event) {
+ const id = event.target.dataset.id;
+ if ($('#actiondel' + id).hasClass('disabled')) {
+ return;
+ }
+
+ this.confirm_dialog(this.get_label('managesieve.actiondeleteconfirm'), 'delete', function (e, ref) {
+ var row = document.getElementById('actionrow' + id);
+ row.parentNode.removeChild(row);
+ ref.managesieve_formbuttons(document.getElementById('actions'));
+ });
+ });
+
+ // update vacation addresses field with user identities
+ $('[data-event-handle="managesieve_vacation_addresses"]').on('click', function (event) {
+ const id = event.target.dataset.id;
+ var lock = window.rcmail.set_busy(true, 'loading');
+ window.rcmail.http_post('plugin.managesieve-action', { _act: 'addresses', _aid: id }, lock);
+ });
+
+ $('data-event-handle="managesieve_rule_join_radio"]').on('click', function (event) {
+ const value = event.target.dataset.value;
+ $('#rules').css('display', value == 'any' ? 'none' : 'block');
+ });
+
+ $('data-event-handle="managesieve_rule_adv_switch"]').on('click', function (event) {
+ var elem = event.target;
+ var id = elem.dataset.id;
+ var elem = $(elem), enabled = elem.hasClass('hide'), adv = $('#rule_advanced' + id);
+
+ if (enabled) {
+ adv.get(0).style.display = 'none';
+ elem.removeClass('hide').addClass('show');
+ } else {
+ adv.get(0).style.display = '';
+ elem.removeClass('show').addClass('hide');
+ }
+
+ return false;
+ });
+
+});
diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php
index 1e160b60f83..da38fff2d72 100644
--- a/plugins/managesieve/managesieve.php
+++ b/plugins/managesieve/managesieve.php
@@ -206,7 +206,7 @@ public function mail_headers($args)
$headers = $this->parse_headers($args['headers']);
if ($this->rc->action == 'preview') {
- $this->rc->output->command('parent.set_env', ['sieve_headers' => $headers]);
+ $this->rc->output->add_js_call('parent.set_env', ['sieve_headers' => $headers]);
} else {
$this->rc->output->set_env('sieve_headers', $headers);
}
@@ -228,7 +228,7 @@ public function managesieve_actions()
$headers = $this->parse_headers($message->headers);
$this->rc->output->set_env('sieve_headers', $headers);
- $this->rc->output->command('managesieve_create', true);
+ $this->rc->output->add_js_call('managesieve_create', true);
$this->rc->output->send();
}
diff --git a/plugins/managesieve/skins/elastic/templates/managesieve.html b/plugins/managesieve/skins/elastic/templates/managesieve.html
index e3201f89326..7ecfeb874e3 100644
--- a/plugins/managesieve/skins/elastic/templates/managesieve.html
+++ b/plugins/managesieve/skins/elastic/templates/managesieve.html
@@ -18,7 +18,7 @@ :
-
diff --git a/skins/elastic/templates/compose.html b/skins/elastic/templates/compose.html
index 0f7cad8caf0..218cfb04704 100644
--- a/skins/elastic/templates/compose.html
+++ b/skins/elastic/templates/compose.html
@@ -21,7 +21,7 @@
-
+
@@ -78,7 +78,7 @@