mirror of
https://github.com/webmin/webmin.git
synced 2026-03-26 19:20:23 +00:00
Compare commits
1 Commits
dev/server
...
dev/time-o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd3e985cf8 |
File diff suppressed because one or more lines are too long
@@ -207,7 +207,7 @@ if ($access{'lang'}) {
|
||||
if ($access{'locale'}) {
|
||||
# Current locale
|
||||
eval "use DateTime; use DateTime::Locale; use DateTime::TimeZone;";
|
||||
if (!$@ && $] > 5.011) {
|
||||
if (!$@) {
|
||||
my $locales = &list_locales();
|
||||
my %localesrev = reverse %{$locales};
|
||||
my $locale_auto = &parse_accepted_language();
|
||||
|
||||
@@ -38,9 +38,7 @@ if ($module_name ne 'htaccess') {
|
||||
# Need to build list of supported modules
|
||||
local ($ver, $mods, $fullver) = &httpd_info($httpd);
|
||||
if ($ver) {
|
||||
my @allmods = &available_modules();
|
||||
local @mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
local @mods = map { "$_/$ver" } &configurable_modules();
|
||||
foreach my $m (@mods) {
|
||||
if ($m =~ /(\S+)\/(\S+)/) {
|
||||
$httpd_modules{$1} = $2;
|
||||
@@ -49,14 +47,10 @@ if ($module_name ne 'htaccess') {
|
||||
# Call again now that known modules have been set, as
|
||||
# sometimes there are dependencies due to LoadModule
|
||||
# statements in an IfModule block
|
||||
undef(@get_config_cache);
|
||||
@allmods = &available_modules();
|
||||
@mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
@mods = map { "$_/$ver" } &configurable_modules();
|
||||
local %site = ( 'size' => $st[7],
|
||||
'path' => $httpd,
|
||||
'modules' => join(' ', @mods),
|
||||
'allmodules' => join(' ', @allmods),
|
||||
'version' => $ver,
|
||||
'fullversion' => $fullver,
|
||||
'webmin' => &get_webmin_version() );
|
||||
@@ -78,9 +72,6 @@ if (&read_file($site_file, \%site)) {
|
||||
$httpd_modules{$1} = $2;
|
||||
}
|
||||
}
|
||||
foreach $m (split(/\s+/, $site{'allmodules'})) {
|
||||
$all_httpd_modules{$m} = $site{'version'};
|
||||
}
|
||||
foreach $m (keys %httpd_modules) {
|
||||
if (!-r "$module_root_directory/$m.pl") {
|
||||
delete($httpd_modules{$m});
|
||||
@@ -1834,46 +1825,46 @@ for(my $i=0; $i<$secs; $i++) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
# configurable_modules([&all-mods])
|
||||
# configurable_modules()
|
||||
# Returns a list of Apaches that are compiled in or dynamically loaded, and
|
||||
# supported by Webmin.
|
||||
sub configurable_modules
|
||||
{
|
||||
my ($allmods) = @_;
|
||||
$allmods ||= [ &available_modules() ];
|
||||
return grep { -r "$module_root_directory/$_.pl" } @$allmods;
|
||||
}
|
||||
|
||||
# available_modules()
|
||||
# Returns a list of Apaches that are compiled in or dynamically loaded
|
||||
sub available_modules
|
||||
{
|
||||
my ($ver, $mods) = &httpd_info(&find_httpd());
|
||||
my @rv;
|
||||
local ($ver, $mods) = &httpd_info(&find_httpd());
|
||||
local @rv;
|
||||
local $m;
|
||||
|
||||
# Add compiled-in modules
|
||||
push(@rv, @$mods);
|
||||
foreach $m (@$mods) {
|
||||
if (-r "$module_root_directory/$m.pl") {
|
||||
push(@rv, $m);
|
||||
}
|
||||
}
|
||||
|
||||
# Add dynamically loaded modules
|
||||
my $conf = &get_config();
|
||||
foreach my $l (&find_directive_struct("LoadModule", $conf)) {
|
||||
if ($l->{'words'}->[1] =~ /(mod_\S+)\.(so|dll)/) {
|
||||
local $conf = &get_config();
|
||||
foreach $l (&find_directive_struct("LoadModule", $conf)) {
|
||||
if ($l->{'words'}->[1] =~ /(mod_\S+)\.(so|dll)/ &&
|
||||
-r "$module_root_directory/$1.pl") {
|
||||
push(@rv, $1);
|
||||
}
|
||||
elsif ($l->{'words'}->[1] =~ /libssl\.so/) {
|
||||
elsif ($l->{'words'}->[1] =~ /libssl\.so/ &&
|
||||
-r "$module_root_directory/mod_apachessl.pl") {
|
||||
push(@rv, "mod_apachessl");
|
||||
}
|
||||
elsif ($l->{'words'}->[1] =~ /lib([^\/\s]+)\.(so|dll)/) {
|
||||
elsif ($l->{'words'}->[1] =~ /lib([^\/\s]+)\.(so|dll)/ &&
|
||||
-r "$module_root_directory/mod_$1.pl") {
|
||||
push(@rv, "mod_$1");
|
||||
}
|
||||
}
|
||||
undef(@get_config_cache); # Cache is no longer valid
|
||||
|
||||
# Add dynamically loaded modules
|
||||
if ($config{'apachectl_path'}) {
|
||||
&open_execute_command(APACHE,
|
||||
"$config{'apachectl_path'} -M 2>/dev/null", 1);
|
||||
while(<APACHE>) {
|
||||
if (/(\S+)_module/) {
|
||||
if (/(\S+)_module/ && -r "$module_root_directory/mod_${1}.pl") {
|
||||
push(@rv, "mod_${1}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
show_list=0
|
||||
httpd_dir=/usr/local
|
||||
httpd_path=/usr/local/sbin/httpd
|
||||
apachectl_path=/usr/local/sbin/apachectl
|
||||
httpd_conf=/usr/local/etc/apache24/httpd.conf
|
||||
mime_types=/usr/local/etc/apache24/mime.types
|
||||
srm_conf=/usr/local/etc/apache24/srm.conf
|
||||
access_conf=/usr/local/etc/apache24/access.conf
|
||||
show_order=0
|
||||
max_servers=100
|
||||
test_config=1
|
||||
test_manual=0
|
||||
test_always=0
|
||||
test_apachectl=1
|
||||
auto_mods=1
|
||||
pid_file=/var/run/httpd.pid
|
||||
show_names=0
|
||||
allow_virtualmin=0
|
||||
format_config=1
|
||||
@@ -1,11 +1,11 @@
|
||||
show_list=0
|
||||
httpd_dir=/usr/apache2/2.4
|
||||
httpd_conf=/etc/apache2/2.4/httpd.conf
|
||||
httpd_path=/usr/apache2/2.4/bin/httpd
|
||||
apachectl_path=/usr/apache2/2.4/bin/apachectl
|
||||
pid_file=/var/run/apache2/2.4/httpd.pid
|
||||
start_cmd=svcadm enable svc:/network/http:apache24
|
||||
stop_cmd=svcadm disable svc:/network/http:apache24
|
||||
httpd_dir=/usr/apache2/2.2
|
||||
httpd_conf=/etc/apache2/2.2/httpd.conf
|
||||
httpd_path=/usr/apache2/2.2/bin/httpd
|
||||
apachectl_path=/usr/apache2/2.2/bin/apachectl
|
||||
pid_file=/var/run/apache2/2.2/httpd.pid
|
||||
start_cmd=svcadm enable svc:/network/http:apache22
|
||||
stop_cmd=svcadm disable svc:/network/http:apache22
|
||||
mime_types=
|
||||
srm_conf=
|
||||
access_conf=
|
||||
|
||||
@@ -1041,7 +1041,7 @@ sub edit_LimitRequestBody
|
||||
{
|
||||
return (1, $text{'core_maxbody'},
|
||||
&opt_input($_[0]->{'value'}, "LimitRequestBody", $text{'core_default'}, 8)
|
||||
.&ui_space(2).$text{'bytes'});
|
||||
.$text{'bytes'});
|
||||
}
|
||||
sub save_LimitRequestBody
|
||||
{
|
||||
@@ -1052,7 +1052,7 @@ sub edit_LimitXMLRequestBody
|
||||
{
|
||||
return (1, $text{'core_maxxml'},
|
||||
&opt_input($_[0]->{'value'}, "LimitXMLRequestBody",
|
||||
$text{'core_default'}, 8).&ui_space(2).$text{'bytes'});
|
||||
$text{'core_default'}, 8).$text{'bytes'});
|
||||
}
|
||||
sub save_LimitXMLRequestBody
|
||||
{
|
||||
|
||||
@@ -637,7 +637,6 @@ mod_proxy_preserve=Preserve original Host: header
|
||||
mod_proxy_timeout=Proxy request timeout in seconds
|
||||
mod_proxy_etimeout=Proxy request timeout must be a number of seconds
|
||||
mod_proxy_via=Set Via: headers
|
||||
mod_proxy_preserve=Preserve original HTTP host
|
||||
mod_proxy_not=None
|
||||
|
||||
mod_log_agent_default=Default
|
||||
|
||||
@@ -25,7 +25,6 @@ $rv = [ [ 'ProxyRequests', 0, 13, 'virtual', undef, 11 ],
|
||||
[ 'ProxyMaxForwards', 0, 13, 'virtual', 2.0 ],
|
||||
[ 'ProxyPreserveHost', 0, 13, 'virtual', 2.031 ],
|
||||
[ 'ProxyTimeout', 0, 13, 'virtual', 2.031 ],
|
||||
[ 'ProxyPreserveHost', 0, 13, 'virtual', 2.3 ],
|
||||
[ 'ProxyVia', 0, 13, 'virtual', 2.0 ] ];
|
||||
return &make_directives($rv, $_[0], "mod_proxy");
|
||||
}
|
||||
@@ -292,16 +291,7 @@ sub save_ProxyVia
|
||||
return &parse_choice("ProxyVia", "");
|
||||
}
|
||||
|
||||
sub edit_ProxyPreserveHost
|
||||
{
|
||||
return (1, $text{'mod_proxy_preserve'},
|
||||
&choice_input($_[0]->{'value'}, "ProxyPreserveHost", "",
|
||||
"$text{'yes'},on", "$text{'no'},off", "$text{'default'},"));
|
||||
}
|
||||
sub save_ProxyPreserveHost
|
||||
{
|
||||
return &parse_choice("ProxyPreserveHost", "");
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ sub edit_SuexecUserGroup
|
||||
local $rv;
|
||||
$rv .= sprintf "<input type=radio name=SuexecUserGroup_def value=1 %s> %s\n",
|
||||
$_[0] ? "" : "checked", $text{'suexec_none'};
|
||||
$rv .= &ui_newline();
|
||||
$rv .= sprintf "<input type=radio name=SuexecUserGroup_def value=0 %s>\n",
|
||||
$_[0] ? "checked" : "";
|
||||
$rv .= sprintf "%s <input name=SuexecUserGroup_u size=8 value='%s'> %s\n",
|
||||
|
||||
@@ -11,7 +11,7 @@ use File::Basename;
|
||||
use File::Find;
|
||||
use JSON::PP;
|
||||
use HTTP::Tiny;
|
||||
eval "use HTML::Entities";
|
||||
use HTML::Entities;
|
||||
use List::MoreUtils qw(any uniq);
|
||||
use Cwd qw(cwd);
|
||||
use Encode qw/encode decode/;
|
||||
@@ -245,16 +245,7 @@ sub main
|
||||
talk('affected', \%opt, \%data);
|
||||
|
||||
# Run in overwrite mode
|
||||
if ($opt{'mode'} eq 'clean') {
|
||||
# # Execute clean
|
||||
talk('clean-pre', \%opt, \%data);
|
||||
if (prompt('next')) {
|
||||
go(\%opt, \%data);
|
||||
}
|
||||
}
|
||||
|
||||
# Run in overwrite mode
|
||||
elsif ($opt{'mode'} eq 'full') {
|
||||
if ($opt{'mode'} eq 'full') {
|
||||
|
||||
# Execute force transcode/translate
|
||||
talk('overwrite-pre', \%opt, \%data);
|
||||
@@ -958,7 +949,6 @@ sub go
|
||||
my $verbose = $opt->{'verbose'} || @{$keys_test};
|
||||
my $mode_sync = $opt->{'mode'} ne 'full';
|
||||
my $mode_transcode = $opt->{'mode'} eq 'transcode';
|
||||
my $mode_clean = $opt->{'mode'} eq 'clean';
|
||||
my $allow_symlinks = $opt->{'allow-symlinks'};
|
||||
my $verbose_silent_mode = $mode_sync && $verbose != 2;
|
||||
|
||||
@@ -975,12 +965,6 @@ sub go
|
||||
|
||||
# Check if there has been something to process, if not print a message
|
||||
my $output;
|
||||
|
||||
# If cleaning called in this mode, throw an error
|
||||
if ($mode_clean) {
|
||||
say RED, "Error: Cleaning can only be performed when the target type is unset!", RESET;
|
||||
exit;
|
||||
}
|
||||
|
||||
# Build targets first
|
||||
talk_log(("Transcoding/translating " . CYAN BOLD, $module, RESET . " module's help .."), $data, 1);
|
||||
@@ -1216,7 +1200,6 @@ sub go
|
||||
# Set message type
|
||||
my $message_type_s1 = 'Transcoding/translating';
|
||||
$message_type_s1 = 'Searching/replacing in' if (@{$values_fix});
|
||||
$message_type_s1 = 'Cleaning in' if ($mode_clean);
|
||||
|
||||
talk_log(("$message_type_s1 " . BLUE BOLD, $module, RESET . " module .."), $data, 1);
|
||||
foreach $language (@{ $data->{'languages_source_list'} }) {
|
||||
@@ -1240,51 +1223,6 @@ sub go
|
||||
my %language;
|
||||
my %language_auto;
|
||||
|
||||
# If in clean mode delete the file and go next
|
||||
if ($mode_clean) {
|
||||
|
||||
# Language files
|
||||
my $cfile = "$mpath/$code";
|
||||
my $cfileauto = "$cfile.auto";
|
||||
unlink($cfile);
|
||||
unlink($cfileauto);
|
||||
|
||||
# Module files
|
||||
foreach ('module', 'config', 'uconfig') {
|
||||
my %mdata = %{$data};
|
||||
$mdata{'type'} = $_;
|
||||
my (undef, undef, $ffile) = source_data($module, \%mdata, $opt);
|
||||
$ffile =~ s/\/$_\//\//;
|
||||
my $cxfile = "$ffile.$code";
|
||||
my $cxfileauto = "$cxfile.auto";
|
||||
unlink($cxfile);
|
||||
unlink($cxfileauto);
|
||||
}
|
||||
|
||||
# Help files
|
||||
my %hdata = %{$data};
|
||||
$hdata{'type'} = 'help';
|
||||
my (undef, $hpath) = source_data($module, \%hdata, $opt);
|
||||
my @hdelete_targets;
|
||||
if (-d $hpath) {
|
||||
find(
|
||||
{
|
||||
wanted => sub {
|
||||
my $found = $File::Find::name;
|
||||
if ($found =~ /\.$code\./) {
|
||||
push(@hdelete_targets, $found);
|
||||
}
|
||||
},
|
||||
},
|
||||
$hpath);
|
||||
unlink(@hdelete_targets);
|
||||
}
|
||||
|
||||
# Go next, don't translate
|
||||
$output++;
|
||||
next;
|
||||
}
|
||||
|
||||
my $message_type_s2 = "Processing";
|
||||
$message_type_s2 = "Testing translations for selected keys with" if (@{$keys_test});
|
||||
|
||||
@@ -1794,10 +1732,6 @@ sub talk
|
||||
say GREEN, "Affected languages" . RESET, DARK . " [$languages_count]" . RESET . ": ", YELLOW BOLD,
|
||||
"" . $languages . "", RESET;
|
||||
}
|
||||
if ($what eq 'clean-pre') {
|
||||
say RED, "Danger! ", RESET, WHITE,
|
||||
"The following operation will delete all files related to the affected lang-\nuage, including machine-translated files in all the mentioned modules listed above.",
|
||||
}
|
||||
if ($what eq 'overwrite-pre') {
|
||||
say RED, "Warning! ", RESET, WHITE,
|
||||
"The following operation will force-translate and overwrite mentioned\nlanguages in all mentioned modules listed above, using ",
|
||||
@@ -1895,13 +1829,9 @@ Test translations for "index_stopmsg,trusted_warning" keys, in Russian and Germa
|
||||
|
||||
- webmin language-manager -m=bind8 -t=ru,de -kt=index_stopmsg,trusted_warning
|
||||
|
||||
Clean build directory by removing all kind of language files except English.
|
||||
|
||||
- webmin language-manager --mode=clean
|
||||
|
||||
=item --mode, -x <sync|full|transcode>
|
||||
|
||||
Mode can be either <sync> or <full> or <transcode> or <clean>. Default is set to "sync" and will only keep the keys found on template language file, while missing keys in target languages (translations), will be deleted, and newly added keys to template language file, will be translated. Mode "full" is meant to perform full translation, keeping human translated strings and overwriting all machine translations done in the past (not recommended to run). Mode "transcode" is useful to fix human translated language files, which stored in "utf-8" encoding already, while still having "í" or "é" HTML entities. Mode "clean" is useful to clean build package by removing all kind of language files except source language.
|
||||
Mode can be either <sync> or <full> or <transcode>. Default is set to "sync" and will only keep the keys found on template language file, while missing keys in target languages (translations), will be deleted, and newly added keys to template language file, will be translated. Mode "full" is meant to perform full translation, keeping human translated strings and overwriting all machine translations done in the past (not recommended to run). Mode "transcode" is useful to fix human translated language files, which stored in "utf-8" encoding already, while still having "í" or "é" HTML entities.
|
||||
|
||||
=item --type, -w <lang|ulang|help|config|uconfig|module>
|
||||
|
||||
@@ -1987,4 +1917,4 @@ Verbosely print processed files and provide detailed output. By detault, verbose
|
||||
|
||||
=head1 LICENSE AND COPYRIGHT
|
||||
|
||||
Copyright 2020 Ilia Rostovtsev <ilia@virtualmin.com>
|
||||
Copyright 2022 Ilia Rostovtsev <ilia@virtualmin.com>
|
||||
|
||||
@@ -65,10 +65,10 @@ our @dnssec_dlv_key = ( 257, 3, 5, '"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWE
|
||||
|
||||
my $rand_flag;
|
||||
if ($gconfig{'os_type'} =~ /-linux$/ &&
|
||||
$config{'force_random'} eq '0' &&
|
||||
-r "/dev/urandom" &&
|
||||
$bind_version =~ /^9\./ &&
|
||||
&compare_version_numbers($bind_version, '<', '9.14.2')) {
|
||||
!$config{'force_random'} &&
|
||||
$bind_version &&
|
||||
&compare_version_numbers($bind_version, '9.14') < 0) {
|
||||
# Version: 9.14.2 deprecated the use of -r option
|
||||
# in favor of using /dev/random [bugs:#5370]
|
||||
$rand_flag = "-r /dev/urandom";
|
||||
@@ -376,22 +376,9 @@ return @rv ? wantarray ? @rv : $rv[0]
|
||||
sub find_value
|
||||
{
|
||||
my @v = &find($_[0], $_[1]);
|
||||
if (!@v) {
|
||||
return undef;
|
||||
}
|
||||
elsif (wantarray) {
|
||||
return map { &extract_value($_) } @v;
|
||||
}
|
||||
else {
|
||||
return &extract_value($v[0]);
|
||||
}
|
||||
}
|
||||
|
||||
sub extract_value
|
||||
{
|
||||
my ($dir) = @_;
|
||||
return defined($dir->{'value'}) ? $dir->{'value'} :
|
||||
defined($dir->{'values'}) && @{$dir->{'values'}} ? $dir->{'values'}->[0] : undef;
|
||||
if (!@v) { return undef; }
|
||||
elsif (wantarray) { return map { $_->{'value'} } @v; }
|
||||
else { return $v[0]->{'value'}; }
|
||||
}
|
||||
|
||||
# base_directory([&config], [no-cache])
|
||||
@@ -513,8 +500,9 @@ for(my $i=0; $i<@oldv || $i<@newv; $i++) {
|
||||
sub recursive_set_value
|
||||
{
|
||||
my ($dir) = @_;
|
||||
if (!defined($dir->{'value'})) {
|
||||
$dir->{'value'} = &extract_value($dir);
|
||||
if ($dir->{'values'}) {
|
||||
my @v = @{$dir->{'values'}};
|
||||
$dir->{'value'} = @v ? $v[0] : undef;
|
||||
}
|
||||
if ($dir->{'type'} && $dir->{'type'} == 1 && $dir->{'members'}) {
|
||||
foreach my $m (@{$dir->{'members'}}) {
|
||||
@@ -3022,7 +3010,7 @@ my %on = map { $_, 1 } @{$_[0]};
|
||||
&remote_error_setup(\&slave_error_handler);
|
||||
my @slaveerrs;
|
||||
foreach my $slave (&list_slave_servers()) {
|
||||
next if (%on && !$on{$slave->{'nsname'}} && !$on{$slave->{'host'}});
|
||||
next if (%on && !$on{$slave->{'host'}});
|
||||
|
||||
# Find the PID file
|
||||
$slave_error = undef;
|
||||
|
||||
@@ -17,14 +17,6 @@ my $dom = $zone->{'name'};
|
||||
&ui_print_header(&zone_subhead($zone), $text{'master_title'}, "",
|
||||
undef, undef, undef, undef, &restart_links($zone));
|
||||
|
||||
my $d = &get_virtualmin_domains($dom);
|
||||
if ($d && $d->{'alias'}) {
|
||||
print &ui_alert_box($text{'master_vminalias'}, 'danger');
|
||||
}
|
||||
elsif ($d) {
|
||||
print &ui_alert_box($text{'master_vmin'}, 'warn');
|
||||
}
|
||||
|
||||
# Find the record types
|
||||
my (@rcodes, @recs);
|
||||
if (!$config{'largezones'}) {
|
||||
|
||||
@@ -147,8 +147,6 @@ master_defttl=Default time-to-live for records
|
||||
master_edefttl='$1' is not a valid default time-to-live for records
|
||||
master_esoagone=No SOA record found!
|
||||
master_einclude=Additional template file does not exist
|
||||
master_vmin=This zone is managed by Virtualmin. Records should be edited using the Virtualmin UI, to ensure they are consistent with other virtual server settings.
|
||||
master_vminalias=This zone is an alias of a Virtualmin domain, which is kept in sync with it's target. Records should never be edited here, as any changes will be overwritten!
|
||||
|
||||
delete_title=Delete Zone
|
||||
delete_mesg=Are you sure you want to delete the zone $1 ? All records and the zone file will be deleted.
|
||||
|
||||
@@ -59,9 +59,9 @@ if ($access{'lang'}) {
|
||||
|
||||
# Old datetime format or a new locale
|
||||
if ($access{'locale'}) {
|
||||
&foreign_require('webmin');
|
||||
eval "use DateTime; use DateTime::Locale; use DateTime::TimeZone;";
|
||||
if (!$@ && $] > 5.011) {
|
||||
&foreign_require('webmin');
|
||||
if (!$@) {
|
||||
my $locales = &list_locales();
|
||||
my %localesrev = reverse %{$locales};
|
||||
my $locale = $locale_auto || $gconfig{'locale'} || &get_default_system_locale();
|
||||
|
||||
@@ -925,7 +925,7 @@ $table .= &ui_columns_row(\@cols, [ "valign=top", "valign=top", "valign=top",
|
||||
"valign=top", "valign=top" ]);
|
||||
$table .= &ui_columns_end();
|
||||
$table .= $text{'edit_ctrl'};
|
||||
$rv .= &ui_table_row(undef, $table, $width, undef, ['data-schedule-tr']);
|
||||
$rv .= &ui_table_row(undef, $table, $width);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,12 +74,12 @@ open(FILE, "<".$_[0]);
|
||||
while($line = <FILE>) {
|
||||
# strip comments
|
||||
$line =~ s/\r|\n//g;
|
||||
$line =~ s/([^\\])\\"/$1\\042/g; # convert escaped quotes to \042
|
||||
$line =~ s/^([^"#]*)#.*$/$1/g;
|
||||
$line =~ s/^([^"]*)\/\/.*$/$1/g;
|
||||
$line =~ s/^([^"]*)\s+#.*$/$1/g; # remove stuff after #, unless
|
||||
$line =~ s/^(.*".*".*)\s+#.*$/$1/g; # it is inside quotes
|
||||
$line =~ s/\\\\/\\134/g; # convert \\ into \134
|
||||
$line =~ s/([^\\])\\"/$1\\042/g; # convert escaped quotes to \042
|
||||
while(1) {
|
||||
if (!$cmode && $line =~ /\/\*/ && $line !~ /\".*\/\*.*\"/) {
|
||||
# start of a C-style comment
|
||||
|
||||
@@ -566,15 +566,4 @@ if ($?) {
|
||||
}
|
||||
}
|
||||
|
||||
# Unblock all IPs in given jail
|
||||
sub unblock_jail
|
||||
{
|
||||
my ($jail) = @_;
|
||||
my $cmd = "$config{'client_cmd'} reload --unban ".quotemeta($jail)." 2>&1 </dev/null";
|
||||
my $out = &backquote_logged($cmd);
|
||||
if ($?) {
|
||||
&error(&text('status_err_unbanjail', &html_escape($jail)) . " : $out");
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Show a status of all active jails
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './fail2ban-lib.pl';
|
||||
our (%in, %text, %config);
|
||||
|
||||
&ReadParse();
|
||||
|
||||
my $jail = $in{'jail'};
|
||||
my $out = &backquote_logged("$config{'client_cmd'} status 2>&1 </dev/null");
|
||||
my ($jail_list) = $out =~ /jail\s+list:\s*(.*)/im;
|
||||
my @jails = split(/,\s*/, $jail_list);
|
||||
&indexof($jail, @jails) > -1 || error($text{'status_err_unknownjail'});
|
||||
|
||||
&ui_print_header("$jail", $text{'status_title3'}, "");
|
||||
my $fh = 'jailinfo';
|
||||
my @jail_blocks;
|
||||
&open_execute_command($fh, "$config{'client_cmd'} get @{[quotemeta($jail)]} banip --with-time 2>&1 </dev/null", 1);
|
||||
while(<$fh>) {
|
||||
if (/^(?<ip>.*?)\s+(?<start>.*?\s+.*?)\s+.*?\s+.*?\s+=\s+(?<end>.*)$/) {
|
||||
my $ip = $+{ip};
|
||||
my $start = $+{start};
|
||||
my $end = $+{end};
|
||||
if ($ip && $start && $end) {
|
||||
push(@jail_blocks, [$ip, $start, $end]);
|
||||
}
|
||||
}
|
||||
}
|
||||
close($fh);
|
||||
|
||||
if (@jail_blocks) {
|
||||
my $popts = \%in;
|
||||
$popts->{'paginations'}->{'form'} = { 'jail' => $jail };
|
||||
my $pagination = &ui_paginations(\@jail_blocks, $popts);
|
||||
my @links = ( &select_all_link("ip"),
|
||||
&select_invert_link("ip"));
|
||||
print $pagination->{'search'}->{'form-data'};
|
||||
print &ui_form_start("unblock_jailed_ip.cgi", "post");
|
||||
print &ui_links_row(\@links);
|
||||
print &ui_columns_start([ "",
|
||||
$text{'status_head_blocks_ip'},
|
||||
$text{'status_head_blocks_stime'},
|
||||
$text{'status_head_blocks_etime'} ]);
|
||||
if (@jail_blocks) {
|
||||
foreach my $r (@jail_blocks) {
|
||||
print &ui_checked_columns_row($r, [ 'width=5' ], "ip", $r->[0]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
print $pagination->{'search'}->{'no-results'};
|
||||
}
|
||||
print &ui_columns_end();
|
||||
print $pagination->{'paginator'}->{'form-data'};
|
||||
print $pagination->{'paginator'}->{'form-scripts'};
|
||||
print &ui_hidden("jail", $jail);
|
||||
print &ui_hidden("return", 1);
|
||||
print $pagination->{'form'};
|
||||
print &ui_links_row(\@links);
|
||||
print &ui_form_end([ [ undef, $text{'status_jail_unblock_ips'} ] ]);
|
||||
print $pagination->{'search'}->{'form'};
|
||||
print $pagination->{'paginator'}->{'form'};
|
||||
}
|
||||
else {
|
||||
print &text('status_jail_noactiveips', $jail);
|
||||
}
|
||||
|
||||
&ui_print_footer("list_status.cgi", $text{'status_return'},
|
||||
"", $text{'index_return'});
|
||||
@@ -170,32 +170,23 @@ manual_efile=Selected file is not part of the Fail2Ban configuration!
|
||||
manual_err=Failed to edit config file
|
||||
manual_edata=No config file contents entered
|
||||
|
||||
status_title=Jails Status
|
||||
status_title3=Jail Blocks
|
||||
status_return=jails status
|
||||
status_head_jail_blocks=Jail blocks
|
||||
status_title=Jails Status And Actions
|
||||
status_title2=Jails Status
|
||||
status_head_jail_name=Jail name
|
||||
status_head_currently_failed=Currently failed
|
||||
status_head_total_failed=Total failed
|
||||
status_head_file_list=File list
|
||||
status_head_currently_banned=Currently banned
|
||||
status_head_total_banned=Total banned
|
||||
status_head_banned_ip_list=Banned IP list
|
||||
status_head_blocks_ip=IP
|
||||
status_head_blocks_stime=Start time
|
||||
status_head_blocks_etime=End time
|
||||
status_rules_plus_more=+ $1 more
|
||||
status_jail_unblock_ip=Remove $1 from banned list
|
||||
status_jail_unblock=Unblock Selected Jails
|
||||
status_jail_unblock_ips=Unblock Selected IP
|
||||
status_jail_unblock=Unblock All IPs for Selected Jails
|
||||
status_jail_noactive=There are no active jails enabled yet.
|
||||
status_jail_noactiveips=There are no blocked entries in jail <tt>$1</tt> found.
|
||||
status_err_set=Failed set action
|
||||
status_err_unblock=Failed to unblock action
|
||||
status_err_nojail=No jails have been selected
|
||||
status_err_noips=No IP has been selected
|
||||
status_err_unban=Cannot un-ban $1 IP address
|
||||
status_err_unbanjail=Cannot un-ban $1 jail
|
||||
status_err_unknownjail=Unknown jail
|
||||
|
||||
syslog_logtarget=Fail2Ban action log
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ no warnings 'uninitialized';
|
||||
require './fail2ban-lib.pl';
|
||||
our (%in, %text, %config);
|
||||
|
||||
&ui_print_header(undef, $text{'status_title'}, "");
|
||||
&ui_print_header(undef, $text{'status_title2'}, "");
|
||||
|
||||
my $out = &backquote_logged("$config{'client_cmd'} status 2>&1 </dev/null");
|
||||
my ($jail_list) = $out =~ /jail\s+list:\s*(.*)/im;
|
||||
@@ -25,13 +25,13 @@ if (@jails) {
|
||||
my $fh = 'cmdjail';
|
||||
my $cmd = "$config{'client_cmd'} status ".quotemeta($jail);
|
||||
my $jcmd = "$cmd 2>&1 </dev/null";
|
||||
my @head = (undef, $text{"status_head_jail_blocks"});
|
||||
my @body = &ui_link("jail_blocks.cgi?jail=".urlize($jail), " ".&html_escape($jail), undef);
|
||||
my @head = (undef, $text{"status_head_jail_name"});
|
||||
my @body = (&ui_link("edit_jail.cgi?name=".urlize($jail), " ".&html_escape($jail)));
|
||||
my $br = '<br>';
|
||||
my $nbsp = ' ';
|
||||
my $ipslimit = sub {
|
||||
my ($ips, $limit) = @_;
|
||||
$limit ||= 10;
|
||||
$limit ||= 15;
|
||||
# Limit sanity check
|
||||
$limit = 1 if ($limit < 1);
|
||||
my $ipscount = () = $ips =~ /$br/g;
|
||||
@@ -39,9 +39,7 @@ if (@jails) {
|
||||
my @ips = split($br, $ips);
|
||||
@ips = @ips[0 .. $limit];
|
||||
$ips = join($br, @ips);
|
||||
$ips .= "<small style='cursor: default;'>$br".
|
||||
(&ui_link("jail_blocks.cgi?jail=".urlize($jail),
|
||||
" ".&text('status_rules_plus_more', $ipscount-$limit), undef))."</small>";
|
||||
$ips .= "<small style='cursor: default;'>$br".&text('status_rules_plus_more', $ipscount-$limit)."</small>";
|
||||
}
|
||||
return $ips;
|
||||
};
|
||||
@@ -59,7 +57,7 @@ if (@jails) {
|
||||
if ($col =~ /banned_ip_list/) {
|
||||
$jips = $val;
|
||||
my @ips = split(/\s+/, $val);
|
||||
@ips = map { "<small $tal><tt><label $lwf>" . &ui_link("unblock_jailed_ip.cgi?ip=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", $_, undef,
|
||||
@ips = map { "<small $tal><tt><label $lwf>" . &ui_link("unblock_jail.cgi?unblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", $_, undef,
|
||||
"title=\"@{[&text('status_jail_unblock_ip', "e_escape($_))]}\" onmouseover=\"this.style.textDecoration='line-through'\" onmouseout=\"this.style.textDecoration='none'\""
|
||||
) . "</label></tt></small>" } @ips;
|
||||
$val = "<br>" if ($val);
|
||||
@@ -84,6 +82,9 @@ if (@jails) {
|
||||
if ($head) {
|
||||
print &ui_columns_end();
|
||||
print &ui_links_row(\@links);
|
||||
foreach my $j (@jipsall) {
|
||||
print &ui_hidden("jips-$j->[0]", "$j->[1]");
|
||||
}
|
||||
print &ui_form_end([ [ 'unblock', $text{'status_jail_unblock'} ] ]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Unblock specific jail
|
||||
# Create, update or delete a action
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
@@ -18,8 +18,13 @@ my @jails = split(/\0/, $in{'jail'});
|
||||
# Processes jails actions
|
||||
my @jailsmod;
|
||||
foreach my $jail (@jails) {
|
||||
&unblock_jail($jail);
|
||||
push(@jailsmod, $jail);
|
||||
my @jailips = split(/\s+/, $in{"jips-$jail"});
|
||||
if (@jailips) {
|
||||
foreach my $ip (@jailips) {
|
||||
&unblock_jailed_ip($jail, $ip);
|
||||
push(@jailsmod, $jail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Log and redirect
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Unblock specific IP in jail
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './fail2ban-lib.pl';
|
||||
our (%in, %text, %config);
|
||||
&ReadParse();
|
||||
&error_setup($text{'status_err_set'});
|
||||
|
||||
my $jail = $in{'jail'};
|
||||
my @ips = split(/\0/, $in{'ip'});
|
||||
|
||||
# Error checks
|
||||
$jail || &error($text{'status_err_nojail'});
|
||||
@ips || &error($text{'status_err_noips'});
|
||||
|
||||
# Processes jails actions
|
||||
my @jailips;
|
||||
foreach my $ip (@ips) {
|
||||
&unblock_jailed_ip($jail, $ip);
|
||||
push(@jailips, $ip);
|
||||
}
|
||||
|
||||
# Log and redirect
|
||||
&webmin_log('update', 'jail', $jail) if (@jailips);
|
||||
&redirect($in{'return'} ? &get_referer_relative() : "list_status.cgi");
|
||||
1
file/xinha
Symbolic link
1
file/xinha
Symbolic link
@@ -0,0 +1 @@
|
||||
../mailboxes/xinha
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 907 B |
@@ -261,8 +261,7 @@ else {
|
||||
# Generate the header
|
||||
local (@hcols, @tds);
|
||||
push(@hcols, "", $text{'index_action'});
|
||||
push(@tds, "width=5", "width=10% nowrap",
|
||||
"width=70%", "nowrap", "nowrap");
|
||||
push(@tds, "width=5", "width=30% nowrap");
|
||||
if ($config{'view_condition'}) {
|
||||
push(@hcols, $text{'index_desc'});
|
||||
push(@tds, "nowrap");
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
firewall_cmd=firewall-cmd
|
||||
init_name=firewalld
|
||||
config_dir=/etc/firewalld
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
firewall_cmd=Full path to firewall-cmd program,0
|
||||
init_name=FirewallD init script name,0
|
||||
config_dir=FirewallD configuration directory,0
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Show a page for manually editing FirewallD config files
|
||||
|
||||
require './firewalld-lib.pl';
|
||||
&ui_print_header(undef, $text{'manual_title'}, "");
|
||||
&ReadParse();
|
||||
my @files = &unique(&get_config_files());
|
||||
my $file = $in{'file'} || $files[0];
|
||||
&indexof($file, @files) >= 0 || &error($text{'manual_efile'});
|
||||
|
||||
# Show the file selector
|
||||
print &ui_form_start("edit_manual.cgi");
|
||||
print "<b>$text{'manual_editsel'}</b>\n";
|
||||
print &ui_select("file", $file, \@files),"\n";
|
||||
print &ui_submit($text{'manual_ok'});
|
||||
print &ui_form_end();
|
||||
|
||||
# Show the file contents
|
||||
print &ui_form_start("save_manual.cgi", "form-data");
|
||||
print &ui_hidden("file", $file);
|
||||
print &ui_table_start(undef, undef, 2);
|
||||
$data = &read_file_contents($file);
|
||||
print &ui_table_row(undef, ui_textarea("data", $data, 20, 80), 2);
|
||||
print &ui_table_end();
|
||||
print &ui_form_end([ [ "save", $text{'save'} ] ]);
|
||||
|
||||
&ui_print_footer("", $text{'index_return'});
|
||||
|
||||
@@ -89,21 +89,18 @@ $service =~ s/[^A-Za-z0-9\-]//g;
|
||||
# my $out = &backquote_command("$config{'firewall_cmd'} --service=".quotemeta($service)." --get-ports --permanent </dev/null 2>&1");
|
||||
|
||||
# Check for file in directory containing all services as xml files
|
||||
my $services_dir = "/usr/lib/firewalld/services/";
|
||||
my $service_file = "$services_dir/$service.xml";
|
||||
my @ports;
|
||||
my @protos;
|
||||
foreach my $services_dir ("/usr/lib/firewalld/services",
|
||||
"/etc/firewalld/services") {
|
||||
my $service_file = "$services_dir/$service.xml";
|
||||
if (-r $service_file) {
|
||||
my $lref = &read_file_lines($service_file, 1);
|
||||
foreach my $l (@{$lref}) {
|
||||
if ($l =~ /<port\s+protocol=["'](?<proto>\S+)["']\s+port=["'](?<port>[\d-]+)["']\/>/) {
|
||||
my $port = "$+{port}";
|
||||
my $proto = "$+{proto}";
|
||||
push(@ports, $port) if ($port);
|
||||
push(@protos, $proto) if ($port && $proto);
|
||||
}
|
||||
}
|
||||
if (-r $service_file) {
|
||||
my $lref = &read_file_lines($service_file, 1);
|
||||
foreach my $l (@{$lref}) {
|
||||
$l =~ /<port\s+protocol=["'](?<proto>\S+)["']\s+port=["'](?<port>[\d-]+)["']\/>/;
|
||||
my $port = "$+{port}";
|
||||
my $proto = "$+{proto}";
|
||||
push(@ports, $port) if ($port);
|
||||
push(@protos, $proto) if ($port && $proto);
|
||||
}
|
||||
}
|
||||
@ports = &unique(@ports);
|
||||
@@ -498,21 +495,4 @@ $out = &backquote_logged(&$get_cmd('permanent')." 2>&1 </dev/null");
|
||||
return $? ? $out : undef;
|
||||
}
|
||||
|
||||
sub get_config_files
|
||||
{
|
||||
my $conf_dir = $config{'config_dir'} || '/etc/firewalld';
|
||||
my @conf_files;
|
||||
my @dirpath = ($conf_dir);
|
||||
eval "use File::Find;";
|
||||
if (!$@) {
|
||||
find(sub {
|
||||
my $file = $File::Find::name;
|
||||
push(@conf_files, $file)
|
||||
if (-f $file && $file =~ /\.(conf|xml)$/);
|
||||
}, @dirpath);
|
||||
}
|
||||
push(@conf_files, "$conf_dir/direct.xml");
|
||||
return @conf_files;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -76,7 +76,6 @@ if ($ok) {
|
||||
$text{'index_sadd'}),
|
||||
&ui_link("edit_forward.cgi?new=1&zone=".&urlize($zone->{'name'}),
|
||||
$text{'index_fadd'}),
|
||||
&ui_link("edit_manual.cgi", $text{'index_manual'}),
|
||||
);
|
||||
if (@{$zone->{'services'}} || @{$zone->{'ports'}}) {
|
||||
my @tds = ( "width=5" );
|
||||
|
||||
@@ -38,14 +38,6 @@ index_restart_firewalld=Reload FirewallD
|
||||
index_restart_firewallddesc=Reload the FirewallD server and apply the rules that were permanently created.
|
||||
index_listrules_restartdesc=List details about existing rich and direct FirewallD rules in $1 zone.
|
||||
index_dependent=Failed to restart $1 dependent service
|
||||
index_manual=Edit Config Files.
|
||||
|
||||
manual_title=Edit Config Files
|
||||
manual_editsel=Edit FirewallD configuration file
|
||||
manual_err=Failed to save config file
|
||||
manual_efile=Selected configuration file is not valid
|
||||
manual_ok=Edit
|
||||
|
||||
|
||||
port_edit=Edit Port
|
||||
port_create=Add Port
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Update the manually edited FirewallD config file
|
||||
|
||||
require './firewalld-lib.pl';
|
||||
&ReadParseMime();
|
||||
&error_setup($text{'manual_err'});
|
||||
my @files = &unique(&get_config_files());
|
||||
my $file = $in{'file'};
|
||||
&indexof($file, @files) >= 0 || &error($text{'manual_efile'});
|
||||
|
||||
$in{'data'} =~ s/\r//g;
|
||||
|
||||
&open_lock_tempfile(my $data, ">$file");
|
||||
&print_tempfile($data, $in{'data'});
|
||||
&close_tempfile($data);
|
||||
|
||||
&webmin_log("manual", undef, $file);
|
||||
&redirect("");
|
||||
|
||||
@@ -70,7 +70,7 @@ dump_before=Command to run before backup
|
||||
dump_after=Command to run after backup
|
||||
dump_fok=Halt if command fails
|
||||
dump_fok2=Report failure if command fails
|
||||
dump_aok=Skip command if backup fails
|
||||
dump_aok=Skip command even if backup fails
|
||||
dump_extra=Extra command-line parameters
|
||||
dump_rsh=Remote backup command
|
||||
dump_rsh0=Default (RSH)
|
||||
@@ -95,7 +95,6 @@ dump_bcomp=Buffer compressed data into blocks?
|
||||
dump_xdev=Limit backup to one filesystem?
|
||||
dump_update2=Just add new files to archive?
|
||||
dump_ignoreread=Ignore read errors on files?
|
||||
dump_ignorechanged=Ignore errors if files change?
|
||||
dump_notape=Prompt for new tape if needed?
|
||||
dump_rmt=Path to <tt>rmt</tt> on remote system
|
||||
dump_links=Follow symbolic links?
|
||||
@@ -122,7 +121,7 @@ edit_header2=Backup schedule
|
||||
edit_header3=Backup options
|
||||
edit_enabled=Scheduled backup enabled?
|
||||
edit_enabled_no=Disabled
|
||||
edit_enabled_yes=Enabled
|
||||
edit_enabled_yes=Enabled, at times chosen below..
|
||||
edit_enabled_af=Enabled, after:
|
||||
edit_savenow=Save and Backup Now
|
||||
edit_createnow=Create and Backup Now
|
||||
|
||||
@@ -107,11 +107,6 @@ if ($_[0]->{'fs'} eq 'tar') {
|
||||
&ui_yesno_radio("ignoreread",
|
||||
int($_[0]->{'ignoreread'})),
|
||||
1, $tds);
|
||||
|
||||
print &ui_table_row(&hlink($text{'dump_ignorechanged'},"ignorechanged"),
|
||||
&ui_yesno_radio("ignorechanged",
|
||||
int($_[0]->{'ignorechanged'})),
|
||||
1, $tds);
|
||||
}
|
||||
elsif ($_[0]->{'fs'} eq 'xfs') {
|
||||
# Display xfs dump options
|
||||
@@ -255,7 +250,6 @@ if ($_[0]->{'fs'} eq 'tar') {
|
||||
}
|
||||
$_[0]->{'update'} = $in{'update'};
|
||||
$_[0]->{'ignoreread'} = $in{'ignoreread'};
|
||||
$_[0]->{'ignorechanged'} = $in{'ignorechanged'};
|
||||
if ($in{'gzip'} && $in{'update'}) {
|
||||
&error($text{'dump_egzip3'});
|
||||
}
|
||||
@@ -375,7 +369,6 @@ if ($_[0]->{'fs'} eq 'tar') {
|
||||
$cmd .= " --rmt-command=".quotemeta($_[0]->{'rmt'})
|
||||
if ($_[0]->{'rmt'});
|
||||
$cmd .= " --ignore-failed-read" if ($_[0]->{'ignoreread'});
|
||||
$cmd .= " --warning=no-file-changed" if ($_[0]->{'ignorechanged'});
|
||||
if ($_[0]->{'exclude'}) {
|
||||
foreach my $e (&split_quoted_string($_[0]->{'exclude'})) {
|
||||
$cmd .= " --exclude ".quotemeta($e);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -274,6 +274,12 @@ print "<script>\n";
|
||||
print "var rowsel = new Array();\n";
|
||||
print "</script>\n";
|
||||
print "<script type='text/javascript' src='@{[&get_webprefix()]}/unauthenticated/sorttable.js'></script>\n";
|
||||
if ($ENV{'HTTP_USER_AGENT'} =~ /Chrome/) {
|
||||
print "<style type=\"text/css\">\n";
|
||||
print "textarea,pre { font-size:120%; }\n";
|
||||
print "textarea { font-family:monospace; }\n";
|
||||
print "</style>\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub theme_popup_prehead
|
||||
@@ -717,14 +723,15 @@ sub theme_ui_checked_columns_row
|
||||
$theme_ui_columns_row_toggle = $theme_ui_columns_row_toggle ? '0' : '1';
|
||||
local ($cols, $tdtags, $checkname, $checkvalue, $checked, $disabled, $tags) = @_;
|
||||
my $rv;
|
||||
my $cbid = "e_escape("${checkname}_${checkvalue}");
|
||||
my $rid = "e_escape("row_${checkname}_${checkvalue}");
|
||||
my $cbid = "e_escape(quotemeta("${checkname}_${checkvalue}"));
|
||||
my $rid = "e_escape(quotemeta("row_${checkname}_${checkvalue}"));
|
||||
my $ridtr = "e_escape("row_${checkname}_${checkvalue}");
|
||||
my $mycb = $cb;
|
||||
if ($checked) {
|
||||
$mycb =~ s/mainbody/mainsel/g;
|
||||
}
|
||||
$mycb =~ s/class='/class='row$theme_ui_columns_row_toggle ui_checked_columns /;
|
||||
$rv .= "<tr id=\"$rid\" $mycb onMouseOver=\"this.className = document.getElementById('$cbid').checked ? 'mainhighsel' : 'mainhigh'\" onMouseOut=\"this.className = document.getElementById('$cbid').checked ? 'mainsel' : 'mainbody row$theme_ui_columns_row_toggle'\">\n";
|
||||
$rv .= "<tr id=\"$ridtr\" $mycb onMouseOver=\"this.className = document.getElementById('$cbid').checked ? 'mainhighsel' : 'mainhigh'\" onMouseOut=\"this.className = document.getElementById('$cbid').checked ? 'mainsel' : 'mainbody row$theme_ui_columns_row_toggle'\">\n";
|
||||
$rv .= "<td class='ui_checked_checkbox' ".$tdtags->[0].">".
|
||||
&ui_checkbox($checkname, $checkvalue, undef, $checked, $tags." "."onClick=\"document.getElementById('$rid').className = this.checked ? 'mainhighsel' : 'mainhigh';\"", $disabled).
|
||||
"</td>\n";
|
||||
@@ -749,15 +756,16 @@ sub theme_ui_radio_columns_row
|
||||
{
|
||||
local ($cols, $tdtags, $checkname, $checkvalue, $checked) = @_;
|
||||
my $rv;
|
||||
my $cbid = "e_escape("${checkname}_${checkvalue}");
|
||||
my $rid = "e_escape("row_${checkname}_${checkvalue}");
|
||||
my $cbid = "e_escape(quotemeta("${checkname}_${checkvalue}"));
|
||||
my $rid = "e_escape(quotemeta("row_${checkname}_${checkvalue}"));
|
||||
my $ridtr = "e_escape("row_${checkname}_${checkvalue}");
|
||||
my $mycb = $cb;
|
||||
if ($checked) {
|
||||
$mycb =~ s/mainbody/mainsel/g;
|
||||
}
|
||||
|
||||
$mycb =~ s/class='/class='ui_radio_columns /;
|
||||
$rv .= "<tr $mycb id=\"$rid\" onMouseOver=\"this.className = document.getElementById('$cbid').checked ? 'mainhighsel' : 'mainhigh'\" onMouseOut=\"this.className = document.getElementById('$cbid').checked ? 'mainsel' : 'mainbody'\">\n";
|
||||
$rv .= "<tr $mycb id=\"$ridtr\" onMouseOver=\"this.className = document.getElementById('$cbid').checked ? 'mainhighsel' : 'mainhigh'\" onMouseOut=\"this.className = document.getElementById('$cbid').checked ? 'mainsel' : 'mainbody'\">\n";
|
||||
$rv .= "<td ".$tdtags->[0]." class='ui_radio_radio'>".
|
||||
&ui_oneradio($checkname, $checkvalue, undef, $checked, "onClick=\"for(i=0; i<form.$checkname.length; i++) { ff = form.${checkname}[i]; r = document.getElementById('row_'+ff.id); if (r) { r.className = 'mainbody' } } document.getElementById('$rid').className = this.checked ? 'mainhighsel' : 'mainhigh';\"").
|
||||
"</td>\n";
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
body blockquote:not([style*="border-left"]) {
|
||||
border-left: 1px solid #ccc;
|
||||
margin-left: 6px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -6,4 +6,4 @@ version: 2.6.0
|
||||
*/
|
||||
h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:bold;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;} em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}
|
||||
|
||||
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}del,ins{text-decoration:none;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
|
||||
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}del,ins{text-decoration:none;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -80,8 +80,8 @@ if ($in{'multi'}) {
|
||||
if ($in{'group'} eq $u->[0]) { print "<tr class='filter_match' $cb>\n"; }
|
||||
else { print "<tr class='filter_match'>\n"; }
|
||||
$u->[0] =~ s/\\/\\\\/g;
|
||||
print "<td width=20%><a href=\"\" onClick='return addgroup(\"@{["e_escape($u->[0], \"'\")]}\", \"@{["e_escape($u->[3], \"'\")]}\")'>@{[&html_escape($u->[0])]}</a></td>\n";
|
||||
print "<td>@{[&html_escape($u->[3])]}</td> </tr>\n";
|
||||
print "<td width=20%><a href=\"\" onClick='return addgroup(\"$u->[0]\", \"$u->[3]\")'>$u->[0]</a></td>\n";
|
||||
print "<td>$u->[3]</td> </tr>\n";
|
||||
$cnt++;
|
||||
}
|
||||
print "</table>\n";
|
||||
@@ -172,8 +172,8 @@ else {
|
||||
foreach $u (&get_groups_list()) {
|
||||
if ($in{'group'} eq $u->[0]) { print "<tr class='filter_match' $cb>\n"; }
|
||||
else { print "<tr class='filter_match'>\n"; }
|
||||
print "<td width=20%><a href=\"\" onClick='return select(\"@{["e_escape($u->[0], \"'\")]}\")'>@{[&html_escape($u->[0])]}</a></td>\n";
|
||||
print "<td>@{[&html_escape($u->[3])]}</td> </tr>\n";
|
||||
print "<td width=20%><a href=\"\" onClick='return select(\"$u->[0]\")'>$u->[0]</a></td>\n";
|
||||
print "<td>$u->[3]</td> </tr>\n";
|
||||
$cnt++;
|
||||
}
|
||||
print "</table>\n";
|
||||
|
||||
36
help.cgi
36
help.cgi
@@ -59,6 +59,42 @@ $help =~ s/<if\s+([^>]*)>([\000-\177]*?)<\/if>/ifhelp($1, $2)/ige;
|
||||
print $help;
|
||||
&popup_footer();
|
||||
|
||||
# read_help_file(module, file)
|
||||
# Reads the contents of a help file, either unpacked or from a ZIP
|
||||
sub read_help_file
|
||||
{
|
||||
my ($module, $file) = @_;
|
||||
my $path = &help_file($module, $file);
|
||||
if (-r $path) {
|
||||
return &read_file_contents($path);
|
||||
}
|
||||
my $gzpath = $path.".gz";
|
||||
if (-r $gzpath) {
|
||||
my $out = &backquote_command(
|
||||
"gunzip -c ".quotemeta($gzpath)." 2>/dev/null");
|
||||
return $? ? undef : $out;
|
||||
}
|
||||
my $zip = $path;
|
||||
$zip =~ s/\/[^\/]+$/\/help.zip/;
|
||||
if (-r $zip) {
|
||||
my @files;
|
||||
foreach my $o (@lang_order_list) {
|
||||
next if ($o eq "en");
|
||||
push(@files, $file.".".$o.".auto.html");
|
||||
push(@files, $file.".".$o.".html");
|
||||
}
|
||||
push(@files, $file.".html");
|
||||
foreach my $f (@files) {
|
||||
my $out = &backquote_command(
|
||||
"unzip -p ".quotemeta($zip)." ".
|
||||
quotemeta($f)." 2>/dev/null");
|
||||
return $out if ($out && !$?);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
# inchelp(path)
|
||||
sub inchelp
|
||||
{
|
||||
|
||||
@@ -1,484 +0,0 @@
|
||||
# html-editor-lib.pl
|
||||
# Quill HTML editor related subs
|
||||
|
||||
sub html_editor_load_bundle
|
||||
{
|
||||
my ($opts) = @_;
|
||||
$opts ||= {};
|
||||
my $html_editor_load_scripts;
|
||||
|
||||
# Load extra modules first
|
||||
$html_editor_load_scripts .=
|
||||
&html_editor_load_modules($opts);
|
||||
|
||||
# Load Quill HTML editor files
|
||||
$html_editor_load_scripts .=
|
||||
<<EOF;
|
||||
<link href="$opts->{'_'}->{'web'}->{'prefix'}/unauthenticated/css/quill.min.css?$opts->{'_'}->{'web'}->{'timestamp'}" rel="stylesheet">
|
||||
<script type="text/javascript" src="$opts->{'_'}->{'web'}->{'prefix'}/unauthenticated/js/quill.min.js?$opts->{'_'}->{'web'}->{'timestamp'}"></script>
|
||||
EOF
|
||||
|
||||
return $html_editor_load_scripts;
|
||||
}
|
||||
sub html_editor_load_modules
|
||||
{
|
||||
my ($opts) = @_;
|
||||
my $html_editor_load_modules;
|
||||
my $load_css_modules = sub {
|
||||
my ($css_modules) = @_;
|
||||
foreach my $module (@{$css_modules}) {
|
||||
$html_editor_load_modules .=
|
||||
"<link href='$opts->{'_'}->{'web'}->{'prefix'}/unauthenticated/css/$module.min.css?$opts->{'_'}->{'web'}->{'timestamp'}' rel='stylesheet'>\n";
|
||||
}
|
||||
};
|
||||
my $load_js_modules = sub {
|
||||
my ($js_modules) = @_;
|
||||
foreach my $module (@{$js_modules}) {
|
||||
$html_editor_load_modules .=
|
||||
"<script type='text/javascript' src='$opts->{'_'}->{'web'}->{'prefix'}/unauthenticated/js/$module.min.js?$opts->{'_'}->{'web'}->{'timestamp'}'></script>\n";
|
||||
}
|
||||
};
|
||||
|
||||
# Load extra CSS modules
|
||||
if ($opts->{'extra'}->{'css'}) {
|
||||
&$load_css_modules($opts->{'extra'}->{'css'})
|
||||
}
|
||||
|
||||
# Load extra JS modules
|
||||
if ($opts->{'extra'}->{'js'}) {
|
||||
&$load_js_modules($opts->{'extra'}->{'js'})
|
||||
}
|
||||
|
||||
# Automatically load dependencies
|
||||
# based on editor mode
|
||||
if ($opts->{'type'} eq "advanced") {
|
||||
my $highlight_bundle = ['highlight/highlight'];
|
||||
my @highlight_bundle = @{$highlight_bundle};
|
||||
if ($opts->{'_'}->{'client'}->{'palette'} eq 'dark') {
|
||||
foreach (@highlight_bundle) {
|
||||
$_ .= "-dark"
|
||||
if (-e "$root_directory/unauthenticated/css/$_-dark.min.css");
|
||||
}
|
||||
}
|
||||
&$load_css_modules(\@highlight_bundle);
|
||||
&$load_js_modules($highlight_bundle);
|
||||
}
|
||||
return $html_editor_load_modules;
|
||||
}
|
||||
|
||||
sub html_editor_template
|
||||
{
|
||||
my ($opts) = @_;
|
||||
$opts ||= {};
|
||||
$html_editor_template =
|
||||
<<EOF;
|
||||
$opts->{'before'}->{'container'}
|
||||
<div class="ql-compose-container $opts->{'class'}->{'container'}">
|
||||
$opts->{'before'}->{'editor'}
|
||||
<div data-composer="html" class="ql-compose ql-container $opts->{'class'}->{'editor'}"></div>
|
||||
$opts->{'after'}->{'editor'}
|
||||
</div>
|
||||
$opts->{'after'}->{'container'}
|
||||
EOF
|
||||
return $html_editor_template;
|
||||
}
|
||||
sub html_editor_styles
|
||||
{
|
||||
my ($type) = @_;
|
||||
|
||||
# HTML editor toolbar styles
|
||||
if ($type eq 'toolbar') {
|
||||
return
|
||||
<<EOF;
|
||||
<style>
|
||||
.ql-compose-container .ql-snow .ql-formats:empty {
|
||||
display: none;
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: '$text{'editor_fontfamily_default'}';
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="0.75em"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="0.75em"]::before {
|
||||
content: '$text{'editor_font_small'}';
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="0.75em"]::before {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
||||
content: '$text{'editor_font_normal'}';
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
||||
font-size: 1em;
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="1.15em"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="1.15em"]::before {
|
||||
content: '$text{'editor_font_medium'}';
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="1.15em"]::before {
|
||||
font-size: 1.15em;
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="1.3em"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="1.3em"]::before {
|
||||
content: '$text{'editor_font_large'}';
|
||||
}
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="1.3em"]::before {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
||||
content: '$text{'editor_paragraph'}';
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
|
||||
content: '$text{'editor_heading'} 1'
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
|
||||
content: '$text{'editor_heading'} 2'
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
|
||||
content: '$text{'editor_heading'} 3'
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
|
||||
content: '$text{'editor_heading'} 4'
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
|
||||
content: '$text{'editor_heading'} 5'
|
||||
}
|
||||
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
|
||||
.ql-compose-container .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
||||
content: '$text{'editor_heading'} 6'
|
||||
}
|
||||
</style>
|
||||
EOF
|
||||
}
|
||||
}
|
||||
|
||||
sub html_editor_toolbar
|
||||
{
|
||||
my ($opts) = @_;
|
||||
|
||||
# Toolbar modes
|
||||
if ($opts->{'type'} eq 'basic') {
|
||||
return
|
||||
<<EOF;
|
||||
[
|
||||
['bold', 'italic'],
|
||||
[{'color': []}],
|
||||
['blockquote']
|
||||
]
|
||||
EOF
|
||||
}
|
||||
if ($opts->{'type'} eq 'simple') {
|
||||
return
|
||||
<<EOF;
|
||||
[
|
||||
[{'font': [false, 'monospace']},
|
||||
{'size': ['0.75em', false, "1.15em", '1.3em']}],
|
||||
['bold', 'italic', 'underline'],
|
||||
[{'color': []}, {'background': []}],
|
||||
[{'align': []}],
|
||||
['blockquote'],
|
||||
['link'],
|
||||
['image'],
|
||||
['clean']
|
||||
]
|
||||
EOF
|
||||
}
|
||||
if ($opts->{'type'} eq 'advanced') {
|
||||
return
|
||||
<<EOF;
|
||||
[
|
||||
[{'font': [false, 'monospace']},
|
||||
{'size': ['0.75em', false, "1.15em", '1.3em']},
|
||||
{'header': [1, 2, 3, 4, 5, 6, false]}],
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{'script': 'sub'}, {'script': 'super'}],
|
||||
[{'color': []}, {'background': []}],
|
||||
[{'align': []}],
|
||||
[{'list': 'ordered'}, {'list': 'bullet'}],
|
||||
[{'indent': '-1'}, {'indent': '+1'}],
|
||||
['blockquote'],
|
||||
(typeof hljs === 'object' ? ['code-block'] : []),
|
||||
['link'],
|
||||
['image'],
|
||||
[{'direction': 'rtl'}],
|
||||
['clean']
|
||||
]
|
||||
EOF
|
||||
}
|
||||
}
|
||||
|
||||
sub html_editor_init_script
|
||||
{
|
||||
my ($opts) = @_;
|
||||
# Get target name and selector type
|
||||
my $target_text = $opts->{'textarea'}->{'target'};
|
||||
my $target_attr = $target_text->{'attr'} || 'name';
|
||||
my $target_type = $target_text->{'type'} || '=';
|
||||
my $target_name = $target_text->{'name'};
|
||||
|
||||
# HTML editor toolbar mode
|
||||
my $iframe_styles_mode = $opts->{'type'};
|
||||
my $iframe_styles =
|
||||
"e_escape(
|
||||
&read_file_contents("$root_directory/unauthenticated/css/_iframe/$iframe_styles_mode.min.css"), '"');
|
||||
$iframe_styles =~ s/\n/ /g;
|
||||
my $navigation_type = $ENV{'HTTP_X_NAVIGATION_TYPE'};
|
||||
$navigation_type ||= 'reload';
|
||||
my $html_editor_init_script =
|
||||
<<EOF;
|
||||
<script type="text/javascript">
|
||||
function fn_${module_name}_html_editor_init() {
|
||||
const targ = document.querySelector('[$target_attr$target_type"$target_name"]'),
|
||||
qs = Quill.import('attributors/style/size'),
|
||||
qf = Quill.import('attributors/style/font'),
|
||||
isMac = navigator.userAgent.toLowerCase().includes('mac'),
|
||||
navigation_type = '$navigation_type',
|
||||
iframe_styles = "$iframe_styles";
|
||||
|
||||
qs.whitelist = ["0.75em", "1.15em", "1.3em"];
|
||||
Quill.register(qs, true);
|
||||
qf.whitelist = ["monospace"],
|
||||
Quill.register(qf, true);
|
||||
|
||||
const editor = new Quill('.ql-container', {
|
||||
modules: {
|
||||
syntax: typeof hljs === 'object',
|
||||
imageDrop: true,
|
||||
imageResize: {
|
||||
modules: [
|
||||
'DisplaySize',
|
||||
'Resize',
|
||||
],
|
||||
},
|
||||
clipboard: {
|
||||
matchVisual: false
|
||||
},
|
||||
toolbar: @{[&html_editor_toolbar($opts)]},
|
||||
},
|
||||
bounds: '.ql-compose-container',
|
||||
theme: 'snow'
|
||||
});
|
||||
|
||||
// Google Mail editor like keybind for quoting
|
||||
editor.keyboard.addBinding({
|
||||
key: '9',
|
||||
shiftKey: true,
|
||||
ctrlKey: !isMac,
|
||||
metaKey: isMac,
|
||||
format: ['blockquote'],
|
||||
}, function(range, context) {
|
||||
this.quill.format('blockquote', false);
|
||||
});
|
||||
editor.keyboard.addBinding({
|
||||
key: '9',
|
||||
shiftKey: true,
|
||||
ctrlKey: !isMac,
|
||||
metaKey: isMac,
|
||||
}, function(range, context) {
|
||||
this.quill.format('blockquote', true);
|
||||
});
|
||||
editor.on('text-change', function() {
|
||||
// This should most probably go to onSubmit event
|
||||
targ.value = editor.root.innerHTML + "<br>";
|
||||
sessionStorage.setItem('$module_name/quill=last-message', editor.root.innerHTML);
|
||||
let extraValue = String(),
|
||||
sync = JSON.parse('@{[&convert_to_json($opts->{'textarea'}->{'sync'}->{'data'})]}'),
|
||||
position = '@{[$opts->{'textarea'}->{'sync'}->{'position'}]}',
|
||||
err = false;
|
||||
try {
|
||||
// Gather data from additional elements if given
|
||||
if (sync.constructor === Array) {
|
||||
sync.forEach(function(_) {
|
||||
let content_document = document;
|
||||
if (_.iframe) {
|
||||
content_document =
|
||||
document.querySelector(_.iframe).contentWindow.document;
|
||||
}
|
||||
_.elements.forEach(function(element) {
|
||||
const element_ = content_document.querySelector(element);
|
||||
(element_ && (extraValue += element_.innerHTML));
|
||||
})
|
||||
});
|
||||
}
|
||||
} catch(e) {
|
||||
err = true;
|
||||
}
|
||||
if (!err) {
|
||||
if (position === 'before') {
|
||||
targ.value = extraValue + targ.value;
|
||||
} else {
|
||||
targ.value = targ.value + extraValue;
|
||||
}
|
||||
}
|
||||
// Inject our styles (unless already injected) to be sent alongside
|
||||
// with the message. These styles later can be optionally turned in
|
||||
// inline styling to satisfy GMail strict rules about HTML emails
|
||||
if (!targ.value.match(/data-iframe-mode=(.*?)$iframe_styles_mode(.*?)/)) {
|
||||
targ.value = targ.value +
|
||||
'<style data-iframe-mode="$iframe_styles_mode">' + iframe_styles + '</style>';
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent loosing focus for toolbar selects (color picker, font select and etc)
|
||||
editor.getModule("toolbar").container.addEventListener("mousedown", (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Don't loose message content if the page
|
||||
// is reloaded or history back is clicked
|
||||
let restore_message = false;
|
||||
try {
|
||||
restore_message = window.performance.getEntriesByType("navigation")[0].type !== 'navigate' &&
|
||||
navigation_type !== 'navigate'
|
||||
} catch(e) {
|
||||
restore_message = false;
|
||||
}
|
||||
if (restore_message) {
|
||||
const quill_last_message = sessionStorage.getItem('$module_name/quill=last-message');
|
||||
if (quill_last_message) {
|
||||
editor.pasteHTML(quill_last_message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Update editor on initial load
|
||||
editor.pasteHTML(targ.value);
|
||||
sessionStorage.setItem('$module_name/quill=last-message', editor.root.innerHTML);
|
||||
}
|
||||
@{[$opts->{'load'} ? "fn_${module_name}_html_editor_init()" : '']}
|
||||
</script>
|
||||
EOF
|
||||
return $html_editor_init_script;
|
||||
}
|
||||
|
||||
sub html_editor
|
||||
{
|
||||
my ($opts) = @_;
|
||||
|
||||
# Populate defaults
|
||||
&html_editor_opts_populate_defaults($opts);
|
||||
|
||||
# Get template
|
||||
my $html_editor_template =
|
||||
&html_editor_template($opts);
|
||||
# Get toolbar styling
|
||||
my $html_editor_styles_toolbar =
|
||||
&html_editor_styles('toolbar');
|
||||
# Load bundles
|
||||
my ($html_editor_load_scripts);
|
||||
my %tinfo = &get_theme_info($current_theme);
|
||||
if (!$tinfo{'spa'}) {
|
||||
# Load HTML editor files and dependencies
|
||||
$html_editor_load_scripts =
|
||||
&html_editor_load_bundle($opts);
|
||||
}
|
||||
|
||||
# HTML editor init
|
||||
$opts->{'load'} = !$tinfo{'spa'};
|
||||
my $html_editor_init_scripts =
|
||||
&html_editor_init_script($opts);
|
||||
|
||||
# Return complete HTML editor
|
||||
return $html_editor_template .
|
||||
$html_editor_styles_toolbar .
|
||||
$html_editor_load_scripts .
|
||||
$html_editor_init_scripts;
|
||||
}
|
||||
|
||||
sub html_editor_opts_populate_defaults
|
||||
{
|
||||
my ($opts) = @_;
|
||||
# Miniserv webprefix
|
||||
$opts->{'_'}->{'web'}->{'prefix'} = &get_webprefix();
|
||||
# Webmin version to timestamp
|
||||
my $webmin_version = &get_webmin_version();
|
||||
$webmin_version =~ s/[.-]+//g;
|
||||
$opts->{'_'}->{'web'}->{'timestamp'} = $webmin_version;
|
||||
# Client color palette
|
||||
$opts->{'_'}->{'client'}->{'palette'} = $ENV{'HTTP_X_COLOR_PALETTE'};
|
||||
}
|
||||
|
||||
sub html_editor_substitute_classes_with_styles
|
||||
{
|
||||
my ($styled_html_email) = @_;
|
||||
my ($document_styles_string) = $styled_html_email =~ /<style\s+data-iframe-mode.*?>(.*)<\/style>/;
|
||||
if ($document_styles_string) {
|
||||
my (%document_styles_class_names) =
|
||||
$document_styles_string =~ /(\.[\w\-\_\d\,\.]+)\s*\{\s*([^}]*?)\s*\}/migx;
|
||||
my $class_string = sub {
|
||||
return "class=\"$_[0]\"";
|
||||
};
|
||||
my $style_string = sub {
|
||||
return "style=\"$_[0]\"";
|
||||
};
|
||||
|
||||
my $style_format = sub {
|
||||
my ($stl) = @_;
|
||||
# Format style nicely, as Google Mail insists
|
||||
# on having these formatted neatly
|
||||
$stl =~ s/(:|;)\s*/$1 /g;
|
||||
$stl =~ s/(?<!;)$/;/g;
|
||||
$stl =~ s/[;\s]+$/;/g;
|
||||
$stl =~ s/(\S)(\!important)/$1 $2/g;
|
||||
$stl =~ s/\s+$//;
|
||||
return $stl;
|
||||
};
|
||||
# Replace tags classes with inline styles
|
||||
foreach my $classes (reverse sort { length($a) <=> length($b) } keys %document_styles_class_names) {
|
||||
my @classes = split(/\s*,\s*/, $classes);
|
||||
foreach my $class (reverse sort { length($a) <=> length($b) } @classes) {
|
||||
my (@class_parts) = $class =~ /\.([\S][^\.]+)/migx;
|
||||
my (@style_exact_full) =
|
||||
map { &$style_format($document_styles_class_names{$_}) }
|
||||
grep { $_ =~ /(?<!\.)(\Q$class\E)(?!\.)(?!\-)(?!\_)/}
|
||||
keys %document_styles_class_names;
|
||||
# Class full
|
||||
if (@style_exact_full) {
|
||||
my $r = &$class_string("@class_parts");
|
||||
my $s = &$style_string("@style_exact_full");
|
||||
$styled_html_email =~ s/\Q$r\E/$s/migx;
|
||||
}
|
||||
|
||||
# Class parts
|
||||
$class =~ s/^\.//g;
|
||||
if ("@class_parts" ne $class) {
|
||||
foreach my $class_part (@class_parts) {
|
||||
my $style_exact_part = $document_styles_class_names{".$class_part"};
|
||||
if ($style_exact_part) {
|
||||
$style_exact_part = &$style_format($style_exact_part);
|
||||
my $r = &$class_string($class_part);
|
||||
my $s = &$style_string($style_exact_part);
|
||||
$styled_html_email =~ s/\Q$r\E/$s/migx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# Fill tags with our inline styles
|
||||
my (@document_styles_tag_names) = $styled_html_email =~ /<(?!style)(?!script)(?!s)(\w+)\s*.*?>/migx;
|
||||
foreach my $tag_name (&unique(@document_styles_tag_names)) {
|
||||
my (%document_styles_tag_names) = $document_styles_string =~ /(\Q$tag_name\E)\s*\{\s*([^}]*?)\s*\}/migx;
|
||||
foreach my $tag (keys %document_styles_tag_names) {
|
||||
my $tag_style = &$style_format($document_styles_tag_names{$tag});
|
||||
$styled_html_email =~ s/(<$tag)(?![^>]+style).*?>/$1 style="$tag_style">/mig;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $styled_html_email;
|
||||
}
|
||||
|
||||
1;
|
||||
5
lang/en
5
lang/en
@@ -306,7 +306,6 @@ ui_etime=Invalid time
|
||||
ui_paging=Showing rows $1 to $2 of $3
|
||||
ui_rowlabel=$2 in row $1 :
|
||||
ui_filterbox=Type to filter..
|
||||
ui_of=of
|
||||
|
||||
header_statusmsg=$1 logged into $2 $3 on $4 ($5)
|
||||
|
||||
@@ -380,10 +379,6 @@ nice_size_kB=kB
|
||||
nice_size_kiB=KiB
|
||||
nice_size_b=bytes
|
||||
|
||||
paginator_showing_start=Showing $1 to $2 of $3 items on page
|
||||
paginator_showing_end=of $1 pages
|
||||
paginator_nosearchrs=There are no results matching <tt>$1</tt> query
|
||||
|
||||
langauto_include=Include machine translations
|
||||
|
||||
file_truncated_message=fetched $1 of data, truncated $2 out of $3
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
line1=Configurable options,11
|
||||
lines=Default number of lines to display,0,6
|
||||
refresh=Seconds between log view refreshes,3,Never
|
||||
others=Show logs from other modules?,1,1-Yes,0-No
|
||||
|
||||
@@ -86,14 +86,12 @@ if ($config{'others'} && $access{'others'}) {
|
||||
foreach $o (@others) {
|
||||
local @cols;
|
||||
if ($o->{'file'}) {
|
||||
push(@cols, &text('index_file',
|
||||
"<tt>".&html_escape($o->{'file'})."</tt>"));
|
||||
push(@cols, &text('index_file',"<tt>$o->{'file'}</tt>"));
|
||||
}
|
||||
else {
|
||||
push(@cols, &text('index_cmd',
|
||||
"<tt>".&html_escape($o->{'cmd'})."</tt>"));
|
||||
push(@cols, &text('index_cmd', "<tt>".$o->{'cmd'}."</tt>"));
|
||||
}
|
||||
push(@cols, &html_escape($o->{'desc'}));
|
||||
push(@cols, $o->{'desc'});
|
||||
push(@cols, &ui_link("view_log.cgi?oidx=$o->{'mindex'}".
|
||||
"&omod=$o->{'mod'}&view=1", $text{'index_view'}) );
|
||||
push(@col2, \@cols);
|
||||
@@ -104,16 +102,9 @@ if ($config{'others'} && $access{'others'}) {
|
||||
# Display extra log files
|
||||
foreach $e (&extra_log_files()) {
|
||||
local @cols;
|
||||
if ($e->{'file'}) {
|
||||
push(@cols, &text('index_file',
|
||||
"<tt>".&html_escape($e->{'file'})."</tt>"));
|
||||
}
|
||||
else {
|
||||
push(@cols, &text('index_cmd',
|
||||
"<tt>".&html_escape($e->{'cmd'})."</tt>"));
|
||||
}
|
||||
push(@cols, &html_escape($e->{'desc'}));
|
||||
push(@cols, &ui_link("view_log.cgi?extra=".&urlize($e->{'file'} || $e->{'cmd'})."&view=1", $text{'index_view'}) );
|
||||
push(@cols, &text('index_file', $e->{'file'}));
|
||||
push(@cols, $e->{'desc'});
|
||||
push(@cols, &ui_link("view_log.cgi?extra=$e->{'file'}&view=1", $text{'index_view'}) );
|
||||
push(@col3, \@cols);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,12 +129,6 @@ foreach my $fd (split(/\t+/, $config{'extras'}), split(/\t+/, $access{'extras'})
|
||||
push(@rv, { 'file' => $fd });
|
||||
}
|
||||
}
|
||||
foreach my $f (@rv) {
|
||||
if ($f->{'file'} =~ /^(.*)\s*\|$/) {
|
||||
delete($f->{'file'});
|
||||
$f->{'cmd'} = $1;
|
||||
}
|
||||
}
|
||||
return @rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,12 +77,10 @@ if ($in{'view'}) {
|
||||
}
|
||||
elsif ($in{'extra'}) {
|
||||
# Extra log file
|
||||
($extra) = grep { $_->{'file'} eq $in{'extra'} ||
|
||||
$_->{'cmd'} eq $in{'extra'} } @extras;
|
||||
($extra) = grep { $_->{'file'} eq $in{'extra'} } @extras;
|
||||
$extra || &error($text{'save_ecannot7'});
|
||||
&can_edit_log($extra) || &error($text{'save_ecannot2'});
|
||||
$file = $extra->{'file'};
|
||||
$cmd = $extra->{'cmd'};
|
||||
}
|
||||
elsif ($in{'file'}) {
|
||||
# Explicitly named file
|
||||
|
||||
@@ -43,9 +43,9 @@ if (!&can_resize_lv_stat(@stat)) {
|
||||
else {
|
||||
# Details for new LV
|
||||
if ($stat[2]) {
|
||||
print &ui_table_row($text{'lv_name'},
|
||||
$lv->{'name'}.
|
||||
&ui_hidden("name", $lv->{'name'}));
|
||||
print &ui_table_row($text{'lv_name'}, $lv->{'name'},
|
||||
undef, [ "", "valign=top" ]);
|
||||
print &ui_hidden("name", $lv->{'name'});
|
||||
}
|
||||
else {
|
||||
print &ui_table_row($text{'lv_name'},
|
||||
|
||||
@@ -1480,7 +1480,7 @@ if ($u) {
|
||||
my $locale;
|
||||
if ($userconfig{'date_fmt'} eq 'auto' || $config{'date_fmt'} eq 'auto') {
|
||||
eval "use DateTime; use DateTime::Locale; use DateTime::TimeZone;";
|
||||
if (!$@ && $] > 5.011) {
|
||||
if (!$@) {
|
||||
$locale++;
|
||||
return &make_date($u, undef, $fmt);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ sort_mode=1
|
||||
fwd_mode=0
|
||||
delete_warn=y
|
||||
top_buttons=2
|
||||
view_html=2
|
||||
view_images=3
|
||||
view_html=0
|
||||
mail_usermin=mail
|
||||
sync_create=0
|
||||
sync_modify=1
|
||||
@@ -25,8 +24,7 @@ size_mode=1
|
||||
no_crlf=0
|
||||
sync_perms=0700
|
||||
show_mail=0
|
||||
html_edit=2
|
||||
html_edit_mode=simple
|
||||
html_edit=0
|
||||
check_mod=1
|
||||
spam_buttons=mail
|
||||
show_delall=0
|
||||
|
||||
@@ -10,9 +10,7 @@ show_sent=Show number of messages in sent mail folder?,1,1-Yes,0-No
|
||||
fwd_mode=Forward messages with quoting?,1,0-Yes,1-No
|
||||
delete_warn=Ask for confirmation before deleting?,10,y-Yes,n-No,For mbox files larger than
|
||||
view_html=Show message body as,4,0-Always plain text,1-Text if possible, HTML otherwise,2-HTML if possible, text otherwise,3-Convert HTML to plain text
|
||||
view_images=Show inline images by default?,1,0-Yes, client fetched,3-Yes, server fetched,1-No external images,2-No
|
||||
html_edit=Use HTML editor for composing?,4,2-Always,1-When replying to HTML email,0-Never
|
||||
html_edit_mode=HTML editor toolbar mode?,4,basic-Basic,simple-Simple,advanced-Advanced
|
||||
html_quote=HTML quoting mode,1,1-Message below <hr>,0-Message inside <blockquote>
|
||||
log_read=Record the reading of mail in the Webmin Actions Log?,1,1-Yes,0-No
|
||||
bcc_to=Bcc: sent messages to,0
|
||||
|
||||
@@ -2414,6 +2414,18 @@ $bodystuff = &safe_html($bodystuff) if ($bodystuff);
|
||||
return wantarray ? ($html, $bodystuff) : $html;
|
||||
}
|
||||
|
||||
# head_html(html)
|
||||
# Returns HTML in the <head> section of a document
|
||||
sub head_html
|
||||
{
|
||||
local $html = $_[0];
|
||||
return undef if ($html !~ /<HEAD[^>]*>/i || $html !~ /<\/HEAD[^>]*>/i);
|
||||
$html =~ s/^[\000-\377]*<HEAD[^>]*>//gi || &error("Failed to filter <pre>".&html_escape($html)."</pre>");
|
||||
$html =~ s/<\/HEAD[^>]*>[\000-\377]*//gi || &error("Failed to filter <pre>".&html_escape($html)."</pre>");
|
||||
$html =~ s/<base[^>]*>//i;
|
||||
return &filter_javascript($html);
|
||||
}
|
||||
|
||||
# safe_urls(html)
|
||||
# Replaces dangerous-looking URLs in HTML
|
||||
sub safe_urls
|
||||
@@ -2482,15 +2494,14 @@ return $rv;
|
||||
# Attempts to convert some HTML to text form
|
||||
sub html_to_text
|
||||
{
|
||||
my ($html) = @_;
|
||||
my ($h2, $lynx);
|
||||
local ($h2, $lynx);
|
||||
if (($h2 = &has_command("html2text")) || ($lynx = &has_command("lynx"))) {
|
||||
# Can use a commonly available external program
|
||||
local $temp = &transname().".html";
|
||||
open(TEMP, ">", $temp);
|
||||
print TEMP $html;
|
||||
print TEMP $_[0];
|
||||
close(TEMP);
|
||||
open(OUT, ($lynx ? "$lynx --display_charset=utf-8 -dump $temp" : "$h2 $temp")." 2>/dev/null |");
|
||||
open(OUT, ($lynx ? "$lynx -dump $temp" : "$h2 $temp")." 2>/dev/null |");
|
||||
while(<OUT>) {
|
||||
if ($lynx && $_ =~ /^\s*References\s*$/) {
|
||||
# Start of Lynx references output
|
||||
@@ -2509,35 +2520,13 @@ if (($h2 = &has_command("html2text")) || ($lynx = &has_command("lynx"))) {
|
||||
return $text;
|
||||
}
|
||||
else {
|
||||
# Can we use Perl HTML formatter
|
||||
# for the better conversion
|
||||
eval "use HTML::TreeBuilder";
|
||||
if (!$@) {
|
||||
eval "use HTML::FormatText";
|
||||
if (!$@) {
|
||||
my $html_parser = HTML::TreeBuilder->new();
|
||||
eval "use utf8";
|
||||
utf8::decode($html)
|
||||
if (!$@);
|
||||
$html_parser->parse($html);
|
||||
my $formatter = HTML::FormatText->new(leftmargin => 1, rightmargin => 79);
|
||||
return $formatter->format($html_parser);
|
||||
}
|
||||
}
|
||||
# Do conversion manually :(
|
||||
$html =~ s/(<|<)(style|script).*?(>|>).*?(<|<)\/(style|script)(>|>)//gs;
|
||||
local $html = $_[0];
|
||||
$html =~ s/\s+/ /g;
|
||||
$html =~ s/<p>/\n\n/gi;
|
||||
$html =~ s/<br>/\n/gi;
|
||||
$html =~ s/<[^>]+>//g;
|
||||
my $useutf8 = 0;
|
||||
eval "use utf8";
|
||||
$useutf8 = 1 if (!$@);
|
||||
utf8::decode($html)
|
||||
if ($useutf8);
|
||||
$html = &entities_to_ascii($html);
|
||||
utf8::encode($html)
|
||||
if ($useutf8);
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -2779,38 +2768,20 @@ else {
|
||||
# 2=All images. Returns the URL of images found in &urls
|
||||
sub disable_html_images
|
||||
{
|
||||
my ($html, $dis, $urls) = @_;
|
||||
my $newhtml;
|
||||
my $masked_img;
|
||||
while($html =~ /^([\000-\377]*?)(<\s*img[^>]*src=('[^']*'|"[^"]*"|\S+)[^>]*>)([\000-\377]*)/i &&
|
||||
# Inline images must be safe to skip
|
||||
$3 !~ /^['"]*data:.*?\/.*?base64,/) {
|
||||
my ($before, $allimg, $img, $after) = ($1, $2, $3, $4);
|
||||
local ($html, $dis, $urls) = @_;
|
||||
local $newhtml;
|
||||
while($html =~ /^([\000-\377]*?)(<\s*img[^>]*src=('[^']*'|"[^"]*"|\S+)[^>]*>)([\000-\377]*)/i) {
|
||||
local ($before, $allimg, $img, $after) = ($1, $2, $3, $4);
|
||||
$img =~ s/^'(.*)'$/$1/ || $img =~ s/^"(.*)"$/$1/;
|
||||
push(@$urls, $img) if ($urls);
|
||||
if ($dis == 3) {
|
||||
# Let server load it in async mode
|
||||
if ($img !~ /^cid:/) {
|
||||
my $imgcont = $allimg;
|
||||
$imgcont =~ s/src=/data-presrc=/g;
|
||||
$newhtml .= $before.$imgcont;
|
||||
$masked_img++;
|
||||
}
|
||||
else {
|
||||
$newhtml .= $before.$allimg;
|
||||
}
|
||||
}
|
||||
elsif ($dis == 0) {
|
||||
if ($dis == 0) {
|
||||
# Don't harm image
|
||||
$newhtml .= $before.$allimg;
|
||||
}
|
||||
elsif ($dis == 1) {
|
||||
# Don't touch unless offsite
|
||||
if ($img =~ /^(http|https|ftp):/) {
|
||||
my $imgcont = $allimg;
|
||||
$imgcont =~ s/src=/data-nosrc=/g;
|
||||
$newhtml .= $before.$imgcont;
|
||||
$masked_img++;
|
||||
$newhtml .= $before;
|
||||
}
|
||||
else {
|
||||
$newhtml .= $before.$allimg;
|
||||
@@ -2823,305 +2794,9 @@ while($html =~ /^([\000-\377]*?)(<\s*img[^>]*src=('[^']*'|"[^"]*"|\S+)[^>]*>)([\
|
||||
$html = $after;
|
||||
}
|
||||
$newhtml .= $html;
|
||||
if ($masked_img) {
|
||||
my $masked_img_style =
|
||||
"<style>
|
||||
img[data-nosrc]
|
||||
{
|
||||
border-radius: 0 !important;
|
||||
background: #e1567833 !important;
|
||||
border-color: transparent !important;
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
}
|
||||
</style>";
|
||||
$masked_img_style =~ s/[\n\r\s]+/ /g;
|
||||
$masked_img_style = &trim($masked_img_style);
|
||||
if ($newhtml =~ /<\/body>/) {
|
||||
$newhtml =~ s/<\/body>/$masked_img_style<\/body>/;
|
||||
}
|
||||
else {
|
||||
$newhtml .= $masked_img_style;
|
||||
}
|
||||
}
|
||||
return $newhtml;
|
||||
}
|
||||
|
||||
# iframe_body(body)
|
||||
# Returns email message in an iframe HTML element
|
||||
sub iframe_body
|
||||
{
|
||||
my ($body) = @_;
|
||||
|
||||
# Do we have theme styles to embed when
|
||||
# viewing an email? It can be useful for
|
||||
# themes with dark palettes
|
||||
my $iframe_theme_file = sub {
|
||||
my $f =
|
||||
"$root_directory/$current_theme/unauthenticated/css/_iframe/$_[0].min.css";
|
||||
return -r $f ? &read_file_contents($f) : '';
|
||||
};
|
||||
my $iframe_styles_theme =
|
||||
&$iframe_theme_file($ENV{'HTTP_X_COLOR_PALETTE_FILE'}) ||
|
||||
&$iframe_theme_file('quote');
|
||||
|
||||
# Mail iframe inner styles
|
||||
my $iframe_styles = <<EOF;
|
||||
<style>
|
||||
html, body { overflow-y: hidden; }
|
||||
$iframe_styles_theme
|
||||
</style>
|
||||
EOF
|
||||
# Add inner styles to the email body
|
||||
if ($body =~ /<\/body>/) {
|
||||
$body =~ s/<\/body>/$iframe_styles<\/body>/;
|
||||
}
|
||||
else {
|
||||
$body .= $iframe_styles;
|
||||
}
|
||||
$body = &trim("e_escape($body, '"'));
|
||||
# Email iframe stuff
|
||||
my $webprefix = &get_webprefix();
|
||||
my $image_mode = int(defined($in{'images'}) ? $in{'images'} : $userconfig{'view_images'});
|
||||
my $iframe_body = <<EOF;
|
||||
<div id="mail-iframe-spinner"></div>
|
||||
<style>
|
||||
#mail-iframe {
|
||||
border:0;
|
||||
width:100%;
|
||||
}
|
||||
\@keyframes mail-iframe-spinner {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
#mail-iframe-spinner:before {
|
||||
animation: mail-iframe-spinner .4s linear infinite;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #bbbbbb;
|
||||
border-top-color: #000000;
|
||||
box-sizing: border-box;
|
||||
content: '';
|
||||
height: 18px;
|
||||
margin-top: 3px;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
width: 18px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function mail_iframe_onload(iframe) {
|
||||
if (typeof theme_mail_iframe_onload === 'function') {
|
||||
theme_mail_iframe_onload(iframe);
|
||||
return;
|
||||
}
|
||||
const iframe_spinner = document.querySelector('#mail-iframe-spinner'),
|
||||
iframe_resize = function() {
|
||||
const iframeobj = document.querySelector('#mail-iframe'),
|
||||
iframe_height_bound = iframeobj.contentWindow.document.body.getBoundingClientRect().bottom,
|
||||
iframe_scroll_height = iframeobj.contentWindow.document.body.scrollHeight,
|
||||
iframe_height =
|
||||
iframe_height_bound > iframe_scroll_height ?
|
||||
iframe_height_bound : iframe_scroll_height;
|
||||
iframeobj.style.height = Math.ceil(iframe_height) + "px";
|
||||
};
|
||||
iframe_spinner && iframe_spinner.remove();
|
||||
iframe.classList.add("loaded");
|
||||
setTimeout(iframe_resize);
|
||||
setTimeout(function() {
|
||||
const imgPresrc = iframe.contentWindow.document.querySelectorAll('img[data-presrc]');
|
||||
imgPresrc.forEach(function(img) {
|
||||
(async function() {
|
||||
try {
|
||||
const response = await fetch("$webprefix/$module_name/xhr.cgi?action=fetch&type=download&subtype=blob&url=" + encodeURIComponent(img.dataset.presrc) + "");
|
||||
response.blob().then(function(blob) {
|
||||
try {
|
||||
const urlBlob = URL.createObjectURL(blob);
|
||||
img.removeAttribute('data-presrc');
|
||||
img.src = urlBlob;
|
||||
img.addEventListener('load', iframe_resize, { once: true });
|
||||
} catch(error) {
|
||||
console.warn(\`Cannot load image: \$\{error.message\}\`);
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
})();
|
||||
});
|
||||
}, 99);
|
||||
}
|
||||
</script>
|
||||
<iframe
|
||||
id="mail-iframe"
|
||||
class="mail-iframe mode-$image_mode"
|
||||
onload="mail_iframe_onload(this)"
|
||||
sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"
|
||||
src="about:blank" srcdoc="$body">
|
||||
</iframe>
|
||||
EOF
|
||||
return &trim($iframe_body);
|
||||
}
|
||||
|
||||
# iframe_quote(quote)
|
||||
# Returns quoted message in an iframe HTML element
|
||||
sub iframe_quote
|
||||
{
|
||||
my ($quote) = @_;
|
||||
return $quote if (!$quote);
|
||||
|
||||
# Do we have theme styles to embed
|
||||
# for local display purposes only
|
||||
my $iframe_theme_file = sub {
|
||||
my $f =
|
||||
"$root_directory/$current_theme/unauthenticated/css/_iframe/$_[0].min.css";
|
||||
return -r $f ? &read_file_contents($f) : '';
|
||||
};
|
||||
my $iframe_styles_theme =
|
||||
&$iframe_theme_file($ENV{'HTTP_X_COLOR_PALETTE_FILE'}) ||
|
||||
&$iframe_theme_file('quote');
|
||||
|
||||
# Quote mail iframe inner styles
|
||||
my $iframe_styles = <<EOF;
|
||||
<style>
|
||||
html, body { overflow-y: hidden; }
|
||||
div[contenteditable] { outline: none; }
|
||||
$iframe_styles_theme
|
||||
</style>
|
||||
EOF
|
||||
# Add inner styles to the email body
|
||||
if ($quote =~ /<\/body>/) {
|
||||
$quote =~ s/<\/body>/$iframe_styles<\/body>/;
|
||||
}
|
||||
else {
|
||||
$quote .= $iframe_styles;
|
||||
}
|
||||
$quote = &trim("e_escape($quote, '"'));
|
||||
# Email iframe stuff
|
||||
my $iframe_body = <<EOF;
|
||||
<style>
|
||||
#quote-mail-iframe {
|
||||
border: none;
|
||||
width: calc(100% - 12px);
|
||||
}
|
||||
details.iframe_quote_details summary::-webkit-details-marker {
|
||||
display:none;
|
||||
}
|
||||
details.iframe_quote_details summary {
|
||||
display: block;
|
||||
width: fit-content;
|
||||
outline: none;
|
||||
margin-left: 6px;
|
||||
margin-bottom: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
details.iframe_quote_details iframe {
|
||||
padding-left: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
details.iframe_quote_details summary::after {
|
||||
background-color: #e4e4e4;
|
||||
border: 1px solid #cfcfcf;
|
||||
border-radius: 18px;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
padding: 0;
|
||||
width: 25px;
|
||||
height: 11px;
|
||||
}
|
||||
details.iframe_quote_details summary:hover::after {
|
||||
background-color: #d4d4d4;
|
||||
border: 1px solid #bfbfbf;
|
||||
}
|
||||
details.iframe_quote_details summary > ul {
|
||||
display: inline-flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
margin-left: 7px;
|
||||
margin-top: 5px;
|
||||
pointer-events: none;
|
||||
}
|
||||
details.iframe_quote_details summary > ul > li {
|
||||
background-color: #000;
|
||||
height: 3px;
|
||||
width: 3px;
|
||||
line-height: 0;
|
||||
list-style: none;
|
||||
margin-right: 2px;
|
||||
margin-top: 0;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
details.iframe_quote_details[open] summary::after {
|
||||
background-color: #ccc;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function quote_mail_iframe_onload(iframe) {
|
||||
if (typeof theme_quote_mail_iframe_onload === 'function') {
|
||||
theme_quote_mail_iframe_onload(iframe);
|
||||
return;
|
||||
}
|
||||
const iframe_resize = function() {
|
||||
const iframeobj = document.querySelector('#quote-mail-iframe'),
|
||||
iframe_height_bound = iframeobj.contentWindow.document.body.getBoundingClientRect().bottom,
|
||||
iframe_scroll_height = iframeobj.contentWindow.document.body.scrollHeight,
|
||||
iframe_height =
|
||||
iframe_height_bound > iframe_scroll_height ?
|
||||
iframe_height_bound : iframe_scroll_height;
|
||||
iframeobj.style.height = Math.ceil(iframe_height) + "px";
|
||||
};
|
||||
setTimeout(iframe_resize);
|
||||
document.querySelector('.iframe_quote_details').addEventListener("click", function() {
|
||||
quote_mail_iframe_onload(this.querySelector('iframe'));
|
||||
}, { once: true });
|
||||
if (!iframe.dataset.imagesLoaded) {
|
||||
iframe.dataset.imagesLoaded = 1;
|
||||
setTimeout(function() {
|
||||
const imgPresrc = iframe.contentWindow.document.querySelectorAll('img[data-presrc]');
|
||||
imgPresrc.forEach(function(img) {
|
||||
(async function() {
|
||||
try {
|
||||
const response = await fetch("$webprefix/$module_name/xhr.cgi?action=fetch&type=download&subtype=blob&url=" + encodeURIComponent(img.dataset.presrc) + "");
|
||||
response.blob().then(function(blob) {
|
||||
try {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onloadend = function() {
|
||||
img.removeAttribute('data-presrc');
|
||||
img.src = reader.result;
|
||||
img.addEventListener('load', iframe_resize, { once: true });
|
||||
}
|
||||
} catch(error) {
|
||||
console.warn(\`Cannot load image: \$\{error.message\}\`);
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
})();
|
||||
});
|
||||
}, 99);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<iframe
|
||||
id="quote-mail-iframe"
|
||||
class="quote-mail-iframe"
|
||||
onload="quote_mail_iframe_onload(this)"
|
||||
sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"
|
||||
src="about:blank" srcdoc="<div contenteditable='true' id='webmin-iframe-quote' class='iframe_quote'>$quote</div>">
|
||||
</iframe>
|
||||
EOF
|
||||
$iframe_body = &ui_details({
|
||||
html => 1,
|
||||
title => "<ul><li></li><li></li><li></li></ul>",
|
||||
content => $iframe_body,
|
||||
class => 'iframe_quote_details'
|
||||
});
|
||||
|
||||
return &trim($iframe_body);
|
||||
}
|
||||
|
||||
# remove_body_attachments(&mail, &attach)
|
||||
# Returns attachments except for those that make up the message body, and those
|
||||
# that have sub-attachments.
|
||||
@@ -3183,8 +2858,9 @@ if ($writers[0]->[1]) {
|
||||
else {
|
||||
$writer = &decode_mimewords($writers[0]->[0])." wrote ..";
|
||||
}
|
||||
my $tm = &parse_mail_date($_[0]->{'header'}->{'date'});
|
||||
if ($tm) {
|
||||
local $tm;
|
||||
if ($cfg->{'reply_date'} &&
|
||||
($tm = &parse_mail_date($_[0]->{'header'}->{'date'}))) {
|
||||
local $tmstr = &make_date($tm);
|
||||
$writer = "On $tmstr $writer";
|
||||
}
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Outomatiese antwoord
|
||||
left_filter=E-posfilters
|
||||
left_pass=Verander wagwoord
|
||||
left_sig=Wysig handtekening
|
||||
|
||||
editor_fontfamily_default=Verstek
|
||||
editor_font_small=Klein
|
||||
editor_font_normal=Normaal
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Groot
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=رد آلي
|
||||
left_filter=مرشحات البريد الإلكتروني
|
||||
left_pass=تغيير كلمة السر
|
||||
left_sig=تعديل التوقيع
|
||||
|
||||
editor_fontfamily_default=تقصير
|
||||
editor_font_small=صغير
|
||||
editor_font_normal=طبيعي
|
||||
editor_font_medium=واسطة
|
||||
editor_font_large=كبير
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Аўтаматычны адказ
|
||||
left_filter=Фільтры электроннай пошты
|
||||
left_pass=Змена пароля
|
||||
left_sig=Рэдагаваць подпіс
|
||||
|
||||
editor_fontfamily_default=Па змаўчанні
|
||||
editor_font_small=Маленькі
|
||||
editor_font_normal=Нармальны
|
||||
editor_font_medium=Сярэдні
|
||||
editor_font_large=Вялікі
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Автоматичен отговор
|
||||
left_filter=Имейл филтри
|
||||
left_pass=Промяна на паролата
|
||||
left_sig=Редактиране на подписа
|
||||
|
||||
editor_fontfamily_default=По подразбиране
|
||||
editor_font_small=малък
|
||||
editor_font_normal=нормално
|
||||
editor_font_medium=Среден
|
||||
editor_font_large=Голям
|
||||
|
||||
@@ -1,7 +1 @@
|
||||
index_return=llista d'usuaris
|
||||
|
||||
editor_fontfamily_default=Per defecte
|
||||
editor_font_small=Petit
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Mitjana
|
||||
editor_font_large=Gran
|
||||
|
||||
@@ -39,9 +39,3 @@ left_autoreply=Automatická odpověď
|
||||
left_filter=E-mailové filtry
|
||||
left_pass=Změnit heslo
|
||||
left_sig=Upravit podpis
|
||||
|
||||
editor_fontfamily_default=Výchozí
|
||||
editor_font_small=Malý
|
||||
editor_font_normal=Normální
|
||||
editor_font_medium=Střední
|
||||
editor_font_large=Velký
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Automatisk svar
|
||||
left_filter=E-mail-filtre
|
||||
left_pass=Skift kodeord
|
||||
left_sig=Rediger underskrift
|
||||
|
||||
editor_fontfamily_default=Standard
|
||||
editor_font_small=Lille
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Stor
|
||||
|
||||
@@ -1,7 +1 @@
|
||||
index_return=Benutzerliste
|
||||
|
||||
editor_fontfamily_default=Standard
|
||||
editor_font_small=Klein
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Mittel
|
||||
editor_font_large=Groß
|
||||
|
||||
@@ -81,9 +81,3 @@ left_autoreply=Αυτόματη απάντηση
|
||||
left_filter=Φίλτρα ηλεκτρονικού ταχυδρομείου
|
||||
left_pass=Άλλαξε κωδικό
|
||||
left_sig=Επεξεργασία υπογραφής
|
||||
|
||||
editor_fontfamily_default=Προκαθορισμένο
|
||||
editor_font_small=Μικρό
|
||||
editor_font_normal=Κανονικός
|
||||
editor_font_medium=Μεσαίο
|
||||
editor_font_large=Μεγάλο
|
||||
|
||||
@@ -451,12 +451,4 @@ left_filter=Email Filters
|
||||
left_pass=Change Password
|
||||
left_sig=Edit Signature
|
||||
|
||||
editor_heading=Heading
|
||||
editor_paragraph=Paragraph
|
||||
editor_fontfamily_default=Default
|
||||
editor_font_small=Small
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Large
|
||||
|
||||
__norefs=1
|
||||
|
||||
@@ -347,9 +347,3 @@ left_autoreply=Respuesta automática
|
||||
left_filter=Filtros de correo electrónico
|
||||
left_pass=Cambia la contraseña
|
||||
left_sig=Editar firma
|
||||
|
||||
editor_fontfamily_default=Por defecto
|
||||
editor_font_small=Pequeño
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Medio
|
||||
editor_font_large=Grande
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Erantzun automatikoa
|
||||
left_filter=Posta elektronikoko iragazkiak
|
||||
left_pass=Aldatu pasahitza
|
||||
left_sig=Editatu Sinadura
|
||||
|
||||
editor_fontfamily_default=Lehenetsia
|
||||
editor_font_small=Txikia
|
||||
editor_font_normal=Normala
|
||||
editor_font_medium=Ertaina
|
||||
editor_font_large=Handia
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=پاسخ خودکار
|
||||
left_filter=فیلترهای ایمیل
|
||||
left_pass=تغییر رمز عبور
|
||||
left_sig=امضا را ویرایش کنید
|
||||
|
||||
editor_fontfamily_default=پیش فرض
|
||||
editor_font_small=کم اهمیت
|
||||
editor_font_normal=طبیعی
|
||||
editor_font_medium=متوسط
|
||||
editor_font_large=بزرگ
|
||||
|
||||
@@ -176,9 +176,3 @@ left_autoreply=Automaattinen vastaus
|
||||
left_filter=Sähköpostisuodattimet
|
||||
left_pass=Vaihda salasana
|
||||
left_sig=Muokkaa allekirjoitusta
|
||||
|
||||
editor_fontfamily_default=Oletus
|
||||
editor_font_small=Pieni
|
||||
editor_font_normal=Normaali
|
||||
editor_font_medium=Keskikokoinen
|
||||
editor_font_large=Suuri
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
editor_fontfamily_default=Défaut
|
||||
editor_font_small=Petit
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Moyen
|
||||
editor_font_large=Grand
|
||||
@@ -450,9 +450,3 @@ left_autoreply=מענה אוטומטי
|
||||
left_filter=מסנני דוא"ל
|
||||
left_pass=שנה סיסמא
|
||||
left_sig=ערוך חתימה
|
||||
|
||||
editor_fontfamily_default=בְּרִירַת מֶחדָל
|
||||
editor_font_small=קָטָן
|
||||
editor_font_normal=נוֹרמָלִי
|
||||
editor_font_medium=בינוני
|
||||
editor_font_large=גָדוֹל
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Automatski odgovor
|
||||
left_filter=Filteri e-pošte
|
||||
left_pass=Promijenite lozinku
|
||||
left_sig=Uredi potpis
|
||||
|
||||
editor_fontfamily_default=Zadano
|
||||
editor_font_small=Mali
|
||||
editor_font_normal=Normalan
|
||||
editor_font_medium=Srednji
|
||||
editor_font_large=velika
|
||||
|
||||
@@ -290,9 +290,3 @@ left_autoreply=Automatikus válasz
|
||||
left_filter=E-mail szűrők
|
||||
left_pass=Jelszó módosítása
|
||||
left_sig=Aláírás szerkesztése
|
||||
|
||||
editor_fontfamily_default=Alapértelmezett
|
||||
editor_font_small=Kicsi
|
||||
editor_font_normal=Normál
|
||||
editor_font_medium=Közepes
|
||||
editor_font_large=Nagy
|
||||
|
||||
@@ -16,9 +16,3 @@ left_autoreply=Risposta automatica
|
||||
left_filter=Filtri email
|
||||
left_pass=Cambia la password
|
||||
left_sig=Modifica firma
|
||||
|
||||
editor_fontfamily_default=Predefinito
|
||||
editor_font_small=Piccolo
|
||||
editor_font_normal=Normale
|
||||
editor_font_medium=medio
|
||||
editor_font_large=Grande
|
||||
|
||||
@@ -39,9 +39,3 @@ left_autoreply=自動返信
|
||||
left_filter=メールフィルター
|
||||
left_pass=パスワードを変更する
|
||||
left_sig=署名を編集
|
||||
|
||||
editor_fontfamily_default=デフォルト
|
||||
editor_font_small=小さい
|
||||
editor_font_normal=普通
|
||||
editor_font_medium=中くらい
|
||||
editor_font_large=大きい
|
||||
|
||||
@@ -52,9 +52,3 @@ left_autoreply=자동 회신
|
||||
left_filter=이메일 필터
|
||||
left_pass=비밀번호 변경
|
||||
left_sig=서명 편집
|
||||
|
||||
editor_fontfamily_default=기본
|
||||
editor_font_small=작은
|
||||
editor_font_normal=정상
|
||||
editor_font_medium=중간
|
||||
editor_font_large=크기가 큰
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Automatinis atsakymas
|
||||
left_filter=El. Pašto filtrai
|
||||
left_pass=Pakeisti slaptažodį
|
||||
left_sig=Redaguoti parašą
|
||||
|
||||
editor_fontfamily_default=Numatytas
|
||||
editor_font_small=Mažas
|
||||
editor_font_normal=Normalus
|
||||
editor_font_medium=Vidutinis
|
||||
editor_font_large=Didelis
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Automātiska atbilde
|
||||
left_filter=E-pasta filtri
|
||||
left_pass=Mainīt paroli
|
||||
left_sig=Rediģēt parakstu
|
||||
|
||||
editor_fontfamily_default=Noklusējums
|
||||
editor_font_small=Mazs
|
||||
editor_font_normal=Normāls
|
||||
editor_font_medium=Vidēja
|
||||
editor_font_large=Liels
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Balas Automatik
|
||||
left_filter=Penapis E-mel
|
||||
left_pass=Tukar kata laluan
|
||||
left_sig=Edit Tandatangan
|
||||
|
||||
editor_fontfamily_default=Lalai
|
||||
editor_font_small=Kecil
|
||||
editor_font_normal=Biasalah
|
||||
editor_font_medium=Sederhana
|
||||
editor_font_large=besar
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Risposta awtomatika
|
||||
left_filter=Email Filtri
|
||||
left_pass=Biddel il-password
|
||||
left_sig=Editja Firma
|
||||
|
||||
editor_fontfamily_default=Default
|
||||
editor_font_small=Żgħir
|
||||
editor_font_normal=Normali
|
||||
editor_font_medium=Medju
|
||||
editor_font_large=Kbir
|
||||
|
||||
@@ -14,9 +14,3 @@ left_autoreply=Automatisch antwoord
|
||||
left_filter=E-mailfilters
|
||||
left_pass=Verander wachtwoord
|
||||
left_sig=Handtekening bewerken
|
||||
|
||||
editor_fontfamily_default=Standaard
|
||||
editor_font_small=Klein
|
||||
editor_font_normal=Normaal
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Groot
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
editor_fontfamily_default=Misligholde
|
||||
editor_font_small=Liten
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Stor
|
||||
@@ -280,9 +280,3 @@ left_autoreply=Automatyczna odpowiedź
|
||||
left_filter=Filtry e-mail
|
||||
left_pass=Zmień hasło
|
||||
left_sig=Edytuj podpis
|
||||
|
||||
editor_fontfamily_default=Domyślny
|
||||
editor_font_small=Mały
|
||||
editor_font_normal=Normalna
|
||||
editor_font_medium=Średni
|
||||
editor_font_large=Duży
|
||||
|
||||
@@ -413,9 +413,3 @@ left_autoreply=Resposta automática
|
||||
left_filter=Filtros de Email
|
||||
left_pass=Mudar senha
|
||||
left_sig=editar assinatura
|
||||
|
||||
editor_fontfamily_default=Padrão
|
||||
editor_font_small=Pequeno
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Médio
|
||||
editor_font_large=Grande
|
||||
|
||||
@@ -447,9 +447,3 @@ left_autoreply=Resposta automática
|
||||
left_filter=Filtros de Email
|
||||
left_pass=Mudar senha
|
||||
left_sig=editar assinatura
|
||||
|
||||
editor_fontfamily_default=Padrão
|
||||
editor_font_small=Pequeno
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Médio
|
||||
editor_font_large=Grande
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Raspuns automat
|
||||
left_filter=Filtre de e-mail
|
||||
left_pass=Schimbați parola
|
||||
left_sig=Editează semnătură
|
||||
|
||||
editor_fontfamily_default=Mod implicit
|
||||
editor_font_small=Mic
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Mediu
|
||||
editor_font_large=Mare
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Автоматический ответ
|
||||
left_filter=Фильтры электронной почты
|
||||
left_pass=Изменить пароль
|
||||
left_sig=Изменить подпись
|
||||
|
||||
editor_fontfamily_default=По умолчанию
|
||||
editor_font_small=Маленький
|
||||
editor_font_normal=Нормальный
|
||||
editor_font_medium=Середина
|
||||
editor_font_large=Большой
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Automatická odpoveď
|
||||
left_filter=E-mailové filtre
|
||||
left_pass=Zmeniť heslo
|
||||
left_sig=Upraviť podpis
|
||||
|
||||
editor_fontfamily_default=Predvolené
|
||||
editor_font_small=Malý
|
||||
editor_font_normal=Normálne
|
||||
editor_font_medium=Stredná
|
||||
editor_font_large=Veľký
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Samodejni odgovor
|
||||
left_filter=E-poštni filtri
|
||||
left_pass=Spremeni geslo
|
||||
left_sig=Uredi podpis
|
||||
|
||||
editor_fontfamily_default=Privzeto
|
||||
editor_font_small=majhna
|
||||
editor_font_normal=normalno
|
||||
editor_font_medium=Srednje
|
||||
editor_font_large=Velik
|
||||
|
||||
@@ -374,9 +374,3 @@ left_autoreply=Automatisk svar
|
||||
left_filter=E-postfilter
|
||||
left_pass=Ändra lösenord
|
||||
left_sig=Redigera signatur
|
||||
|
||||
editor_fontfamily_default=Standard
|
||||
editor_font_small=Små
|
||||
editor_font_normal=Vanligt
|
||||
editor_font_medium=Medium
|
||||
editor_font_large=Stor
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=ตอบกลับอัตโนมัติ
|
||||
left_filter=ตัวกรองอีเมล
|
||||
left_pass=เปลี่ยนรหัสผ่าน
|
||||
left_sig=แก้ไขลายเซ็น
|
||||
|
||||
editor_fontfamily_default=ค่าเริ่มต้น
|
||||
editor_font_small=เล็ก
|
||||
editor_font_normal=ปกติ
|
||||
editor_font_medium=ปานกลาง
|
||||
editor_font_large=ใหญ่
|
||||
|
||||
@@ -65,9 +65,3 @@ slide_prev=Önceki
|
||||
slide_next=Sonraki
|
||||
|
||||
left_mail=Posta
|
||||
|
||||
editor_fontfamily_default=Varsayılan
|
||||
editor_font_small=Küçük
|
||||
editor_font_normal=Normal
|
||||
editor_font_medium=Orta
|
||||
editor_font_large=Büyük
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Автоматична відповідь
|
||||
left_filter=Фільтри електронної пошти
|
||||
left_pass=Змінити пароль
|
||||
left_sig=Редагувати підпис
|
||||
|
||||
editor_fontfamily_default=За замовчуванням
|
||||
editor_font_small=Маленький
|
||||
editor_font_normal=нормальний
|
||||
editor_font_medium=Середній
|
||||
editor_font_large=Великий
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=خودکار جواب
|
||||
left_filter=ای میل کے فلٹرز
|
||||
left_pass=پاس ورڈ تبدیل کریں
|
||||
left_sig=دستخط میں ترمیم کریں
|
||||
|
||||
editor_fontfamily_default=طے شدہ
|
||||
editor_font_small=چھوٹا
|
||||
editor_font_normal=نارمل
|
||||
editor_font_medium=درمیانہ
|
||||
editor_font_large=بڑا
|
||||
|
||||
@@ -450,9 +450,3 @@ left_autoreply=Trả lời tự động
|
||||
left_filter=Bộ lọc email
|
||||
left_pass=Đổi mật khẩu
|
||||
left_sig=Chỉnh sửa chữ ký
|
||||
|
||||
editor_fontfamily_default=Mặc định
|
||||
editor_font_small=Bé nhỏ
|
||||
editor_font_normal=Bình thường
|
||||
editor_font_medium=Trung bình
|
||||
editor_font_large=Lớn
|
||||
|
||||
@@ -343,9 +343,3 @@ left_autoreply=自动回复
|
||||
left_filter=电子邮件过滤器
|
||||
left_pass=更改密码
|
||||
left_sig=编辑签名
|
||||
|
||||
editor_fontfamily_default=默认
|
||||
editor_font_small=小的
|
||||
editor_font_normal=普通的
|
||||
editor_font_medium=中等的
|
||||
editor_font_large=大的
|
||||
|
||||
@@ -184,9 +184,3 @@ left_autoreply=自動回复
|
||||
left_filter=電子郵件過濾器
|
||||
left_pass=更改密碼
|
||||
left_sig=編輯簽名
|
||||
|
||||
editor_fontfamily_default=默認
|
||||
editor_font_small=小的
|
||||
editor_font_normal=普通的
|
||||
editor_font_medium=中等的
|
||||
editor_font_large=大的
|
||||
|
||||
@@ -1 +1 @@
|
||||
allowed=wrap_width,wrap_compose,perpage,show_to,top_buttons,arrows,show_delall,show_sent,fwd_mode,delete_warn,delete_warn_free,view_html,html_edit,html_edit_mode,html_quote,log_read,show_body,open_mode,link_mode,date_fmt,date_tz_def,date_tz
|
||||
allowed=wrap_width,wrap_compose,perpage,show_to,top_buttons,arrows,show_delall,show_sent,fwd_mode,delete_warn,delete_warn_free,view_html,html_edit,html_quote,log_read,show_body,open_mode,link_mode,date_fmt,date_tz_def,date_tz
|
||||
@@ -2,7 +2,6 @@
|
||||
# Display a form for replying to or composing an email
|
||||
|
||||
require './mailboxes-lib.pl';
|
||||
require '../html-editor-lib.pl';
|
||||
&ReadParse();
|
||||
&can_user($in{'user'}) || &error($text{'mail_ecannot'});
|
||||
@uinfo = &get_mail_user($in{'user'});
|
||||
@@ -20,16 +19,17 @@ if ($in{'new'}) {
|
||||
$html_edit = $config{'html_edit'} == 2 ? 1 : 0;
|
||||
}
|
||||
$sig = &get_signature($in{'user'});
|
||||
if ($html_edit && $sig) {
|
||||
if ($html_edit) {
|
||||
$sig =~ s/\n/<br>\n/g;
|
||||
$quote = "<html><body>$sig</body></html>";
|
||||
$quote = "<html><body></body></html>";
|
||||
}
|
||||
else {
|
||||
$quote = "\n\n$sig" if ($sig);
|
||||
}
|
||||
$to = $in{'to'};
|
||||
$main::force_charset = &get_charset();
|
||||
&mail_page_header($text{'compose_title'}, undef, undef,
|
||||
&mail_page_header($text{'compose_title'}, undef,
|
||||
$html_edit ? "onload='xinha_init()'" : "",
|
||||
&folder_link($in{'user'}, $folder));
|
||||
}
|
||||
else {
|
||||
@@ -316,30 +316,19 @@ else {
|
||||
# Construct the initial mail text
|
||||
$sig = &get_signature($in{'user'});
|
||||
($quote, $html_edit, $body) = "ed_message($mail, $qu, $sig);
|
||||
# Load images using server in replies
|
||||
$quote = &disable_html_images($quote, 3);
|
||||
|
||||
# Don't include the original body as an attachment
|
||||
@attach = &remove_body_attachments($mail, \@attach);
|
||||
if (!$in{'forward'} && !$in{'enew'}) {
|
||||
# When replying, lose non-cid attachments
|
||||
@attach = grep { $_->{'header'}->{'content-id'} ||
|
||||
$_->{'header'}->{'content-location'} } @attach;
|
||||
if ($in{'forward'} || $in{'enew'}) {
|
||||
@attach = grep { $_ ne $body } @attach;
|
||||
}
|
||||
|
||||
# For a HTML reply or forward, fix up the cid: to refer to attachments
|
||||
# in the original message.
|
||||
if ($html_edit) {
|
||||
my $uuser = &urlize($in{'user'});
|
||||
$quote = &fix_cids($quote, \@attach,
|
||||
"detach.cgi?user=$uuser&idx=$in{'idx'}&folder=$in{'folder'}$subs");
|
||||
else {
|
||||
undef(@attach);
|
||||
}
|
||||
|
||||
# Show header
|
||||
&mail_page_header(
|
||||
$in{'forward'} || @mailforward ? $text{'forward_title'} :
|
||||
$in{'enew'} ? $text{'enew_title'} :
|
||||
$text{'reply_title'}, undef, undef,
|
||||
$text{'reply_title'}, undef,
|
||||
$html_edit ? "onload='xinha_init()'" : "",
|
||||
&folder_link($in{'user'}, $folder));
|
||||
}
|
||||
|
||||
@@ -455,35 +444,35 @@ if ($in{'new'}) {
|
||||
# Output message body input
|
||||
print &ui_table_start($text{'reply_body'}, "width=100%", 2, undef,
|
||||
&ui_links_row(\@bodylinks));
|
||||
|
||||
# Process email quote
|
||||
my $iframe_quote;
|
||||
$iframe_quote = &iframe_quote($quote)
|
||||
if (!$in{'new'});
|
||||
|
||||
|
||||
if ($html_edit) {
|
||||
# Get HTML editor and replies
|
||||
my $html_editor = &html_editor(
|
||||
{ textarea =>
|
||||
{ target => { name => 'body', attr => 'name' },
|
||||
sync =>
|
||||
{ position => 'after',
|
||||
data => [ { iframe => '#quote-mail-iframe',
|
||||
elements => ['#webmin-iframe-quote'] } ] }
|
||||
},
|
||||
type => $config{'html_edit_mode'} || 'simple',
|
||||
after =>
|
||||
{ editor => $iframe_quote }
|
||||
});
|
||||
$sig =~ s/\n/<br>/g,
|
||||
$sig =~ s/^\s+//g,
|
||||
$sig = "<br><br>$sig<br><br>"
|
||||
if ($sig);
|
||||
if ($current_theme !~ /authentic-theme/) {
|
||||
# Output HTML editor textarea
|
||||
print <<EOF;
|
||||
<script type="text/javascript">
|
||||
_editor_url = "@{[&get_webprefix()]}/$module_name/xinha/";
|
||||
_editor_lang = "en";
|
||||
</script>
|
||||
<script type="text/javascript" src="xinha/XinhaCore.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
xinha_init = function()
|
||||
{
|
||||
xinha_editors = [ "body" ];
|
||||
xinha_plugins = [ ];
|
||||
xinha_config = new Xinha.Config();
|
||||
xinha_config.hideSomeButtons(" print showhelp about killword toggleborders ");
|
||||
xinha_editors = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);
|
||||
Xinha.startEditors(xinha_editors);
|
||||
}
|
||||
</script>
|
||||
EOF
|
||||
}
|
||||
else {
|
||||
print '<script type="text/javascript">xinha_init = function(){}</script>';
|
||||
}
|
||||
print &ui_table_row(undef,
|
||||
&ui_textarea("body", $sig, 12, 80, undef, 0,
|
||||
"style='display: none' id=body data-html-mode='$config{'html_edit_mode'}'").
|
||||
$html_editor, 2);
|
||||
&ui_textarea("body", $quote, 40, 80, undef, 0,
|
||||
"style='width:99%' id=body"), 2);
|
||||
}
|
||||
else {
|
||||
# Show text editing area
|
||||
@@ -491,13 +480,13 @@ else {
|
||||
$wm =~ s/^wrap=//g;
|
||||
$wcols = $config{'wrap_compose'};
|
||||
print &ui_table_row(undef,
|
||||
&ui_textarea("body", "\n\n$sig\n\n$quote", 12,
|
||||
&ui_textarea("body", $quote, 20,
|
||||
$wcols || 80,
|
||||
$wcols ? "hard" : "",
|
||||
0,
|
||||
$wcols ? "" : "style='width:100%'"), 2);
|
||||
}
|
||||
if (&has_command("ispell") && $config{'ispell_enabled'}) {
|
||||
if (&has_command("ispell")) {
|
||||
print &ui_table_row(undef,
|
||||
&ui_checkbox("spell", 1, $text{'reply_spell'}, 0), 2);
|
||||
}
|
||||
@@ -510,20 +499,10 @@ $viewurl = "view_mail.cgi?idx=$in{'idx'}&user=$euser&".
|
||||
$detachurl = "detach.cgi?idx=$in{'idx'}&user=$euser&".
|
||||
"&folder=$folder->{'index'}$subs";
|
||||
$mailurl = "view_mail.cgi?user=$euser&folder=$folder->{'index'}$subs";
|
||||
my @non_body_attach;
|
||||
if (@attach) {
|
||||
@non_body_attach = &remove_cid_attachments($mail, \@attach);
|
||||
}
|
||||
if (@non_body_attach) {
|
||||
&attachments_table(\@non_body_attach, $folder, $viewurl, $detachurl,
|
||||
&attachments_table(\@attach, $folder, $viewurl, $detachurl,
|
||||
$mailurl, 'idx', "forward");
|
||||
}
|
||||
foreach my $a (@attach) {
|
||||
if (&indexof($a, @non_body_attach) < 0) {
|
||||
# Body attachment .. always include
|
||||
print &ui_hidden("forward", $a->{'idx'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Display forwarded mails
|
||||
if (@fwdmail) {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Send off an email message
|
||||
|
||||
require './mailboxes-lib.pl';
|
||||
require '../html-editor-lib.pl';
|
||||
&ReadParse(\%getin, "GET");
|
||||
&ReadParseMime(undef, \&read_parse_mime_callback, [ $getin{'id'} ], 1);
|
||||
foreach my $k (keys %in) {
|
||||
@@ -47,8 +46,6 @@ if ($in{'from'} =~ /^(\S+)\@(\S+)$/ && $access{'fromname'}) {
|
||||
}
|
||||
@sub = split(/\0/, $in{'sub'});
|
||||
$subs = join("", map { "&sub=$_" } @sub);
|
||||
my @inline_images;
|
||||
my %cidmap;
|
||||
|
||||
# Construct the email
|
||||
$in{'from'} || &error($text{'send_efrom'});
|
||||
@@ -70,42 +67,9 @@ if ($in{'bcc'}) {
|
||||
push(@{$mail->{'headers'}}, [ 'X-Priority', $in{'pri'} ]) if ($in{'pri'});
|
||||
$in{'body'} =~ s/\r//g;
|
||||
if ($in{'body'} =~ /\S/) {
|
||||
if ($in{'html_edit'}) {
|
||||
$in{'body'} = &html_editor_substitute_classes_with_styles($in{'body'});
|
||||
}
|
||||
my $preplainbody = $in{'body'};
|
||||
my $prehtmlbody = $in{'body'};
|
||||
|
||||
# Extract inline images if any
|
||||
@inline_images = ($in{'body'} =~ /(data:image\/.*?;base64,)(.*?)"/g);
|
||||
if (@inline_images) {
|
||||
my $iid = 1;
|
||||
for (my $i = 0; $i < scalar(@inline_images) - 1; $i += 2) {
|
||||
if ($inline_images[$i] =~ /data:image/) {
|
||||
my ($type) = $inline_images[$i] =~ /data:image\/(.*?);base64,/;
|
||||
my $cid = "ii_".(time() + $i).'@'."$type";
|
||||
my $replace_html = "$inline_images[$i]$inline_images[$i+1]";
|
||||
my @data = split('@', $cid);
|
||||
$inline_images[$i] = \@data;
|
||||
$inline_images[$i+1] = decode_base64($inline_images[$i+1]);
|
||||
|
||||
# $cid = "cid:$cid\" style=\"width: 60%";
|
||||
$cid = "cid:$cid";
|
||||
|
||||
# Replace for HTML
|
||||
$in{'body'} =~ s/\Q$replace_html/$cid/;
|
||||
|
||||
# Replace for plain text
|
||||
$preplainbody =~ s/<img[^>]*>/[image: inline-image$iid.$type]/;
|
||||
$iid++;
|
||||
}
|
||||
}
|
||||
$prehtmlbody = $in{'body'};
|
||||
}
|
||||
# Perform spell check on body if requested
|
||||
local $plainbody = $in{'html_edit'} ? &html_to_text($preplainbody)
|
||||
: $prehtmlbody;
|
||||
|
||||
local $plainbody = $in{'html_edit'} ? &html_to_text($in{'body'})
|
||||
: $in{'body'};
|
||||
if ($in{'spell'}) {
|
||||
@errs = &spell_check_text($plainbody);
|
||||
if (@errs) {
|
||||
@@ -122,14 +86,6 @@ if ($in{'body'} =~ /\S/) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
# For a HTML body, replace images from detach.cgi on the original
|
||||
# email with cid: references.
|
||||
if ($in{'html_edit'}) {
|
||||
$in{'body'} = &create_cids($in{'body'}, \%cidmap);
|
||||
}
|
||||
|
||||
# Create the body attachment
|
||||
local $mt = $in{'html_edit'} ? "text/html" : "text/plain";
|
||||
if ($in{'charset'}) {
|
||||
$mt .= "; charset=$in{'charset'}";
|
||||
@@ -185,49 +141,29 @@ if ($in{'body'} =~ /\S/) {
|
||||
}
|
||||
}
|
||||
|
||||
# Add inline images
|
||||
if (@inline_images) {
|
||||
my $iid = 1;
|
||||
for (my $i = 0; $i < scalar(@inline_images) - 1; $i += 2) {
|
||||
my $cid = $inline_images[$i][0]."@".$inline_images[$i][1];
|
||||
my $type = $inline_images[$i][1];
|
||||
my $image_name = "inline-image$iid.$type";
|
||||
my $data = $inline_images[$i + 1];
|
||||
push(@attach,
|
||||
{ 'data' => $data,
|
||||
'headers' => [['Content-type', "image/$type; name=\"$image_name\""],
|
||||
['Content-Disposition', "inline; filename=\"$image_name\""],
|
||||
['Content-ID', "<$cid>"],
|
||||
['Content-Transfer-Encoding', 'base64']
|
||||
]
|
||||
});
|
||||
$iid++;
|
||||
}
|
||||
}
|
||||
|
||||
# Add uploaded attachment
|
||||
$attachsize = 0;
|
||||
for($i=0; defined($in{"attach$i"}); $i++) {
|
||||
next if (!$in{"attach$i"});
|
||||
for($j=0; $j<@{$in{"attach$i"}}; $j++) {
|
||||
next if (!$in{"attach${i}"}->[$j]);
|
||||
&test_max_attach(length($in{"attach${i}"}->[$j]));
|
||||
local $filename = $in{"attach${i}_filename"}->[$j];
|
||||
$filename =~ s/^.*(\\|\/)//;
|
||||
local $type = $in{"attach${i}_content_type"}->[$j].
|
||||
"; name=\"".$filename."\"";
|
||||
local $disp = "attachment; filename=\"".$filename."\"";
|
||||
push(@attach, { 'data' => $in{"attach${i}"}->[$j],
|
||||
'headers' => [ [ 'Content-type', $type ],
|
||||
[ 'Content-Disposition', $disp ],
|
||||
[ 'Content-Transfer-Encoding',
|
||||
'base64' ] ] });
|
||||
$atotal += length($in{"attach${i}"}->[$j]);
|
||||
}
|
||||
}
|
||||
# Add uploaded attachment
|
||||
next if (!$in{"attach$i"});
|
||||
for($j=0; $j<@{$in{"attach$i"}}; $j++) {
|
||||
next if (!$in{"attach${i}"}->[$j]);
|
||||
&test_max_attach(length($in{"attach${i}"}->[$j]));
|
||||
local $filename = $in{"attach${i}_filename"}->[$j];
|
||||
$filename =~ s/^.*(\\|\/)//;
|
||||
local $type = $in{"attach${i}_content_type"}->[$j].
|
||||
"; name=\"".$filename."\"";
|
||||
local $disp = "attachment; filename=\"".$filename."\"";
|
||||
push(@attach, { 'data' => $in{"attach${i}"}->[$j],
|
||||
'headers' => [ [ 'Content-type', $type ],
|
||||
[ 'Content-Disposition', $disp ],
|
||||
[ 'Content-Transfer-Encoding',
|
||||
'base64' ] ] });
|
||||
$atotal += length($in{"attach${i}"}->[$j]);
|
||||
}
|
||||
}
|
||||
|
||||
# Add server-side attachment
|
||||
for($i=0; defined($in{"file$i"}); $i++) {
|
||||
# Add server-side attachment
|
||||
next if (!$in{"file$i"} || !$access{'canattach'});
|
||||
@uinfo = &get_mail_user($in{'user'});
|
||||
@uinfo || &error($text{'view_eugone'});
|
||||
@@ -253,10 +189,9 @@ for($i=0; defined($in{"file$i"}); $i++) {
|
||||
'base64' ] ] });
|
||||
$atotal += length($data);
|
||||
}
|
||||
|
||||
# Add forwarded attachments
|
||||
@fwd = split(/\0/, $in{'forward'});
|
||||
if (@fwd) {
|
||||
# Add forwarded attachments
|
||||
@mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder);
|
||||
$fwdmail = $mail[$in{'idx'}];
|
||||
&parse_mail($fwdmail);
|
||||
@@ -268,26 +203,15 @@ if (@fwd) {
|
||||
$fwdmail = $amail;
|
||||
}
|
||||
|
||||
foreach my $f (@fwd) {
|
||||
foreach $f (@fwd) {
|
||||
&test_max_attach(length($fwdmail->{'attach'}->[$f]->{'data'}));
|
||||
$a = $fwdmail->{'attach'}->[$f];
|
||||
if ($cidmap{$f}) {
|
||||
# This attachment has been inlined .. set a content-id
|
||||
$a->{'headers'} = [
|
||||
grep { lc($_->[0]) ne 'content-id' &&
|
||||
lc($_->[0]) ne 'content-location' }
|
||||
@{$a->{'headers'}} ];
|
||||
push(@{$a->{'headers'}},
|
||||
[ 'Content-Id', "<$cidmap{$f}>" ]);
|
||||
}
|
||||
push(@attach, $a);
|
||||
push(@attach, $fwdmail->{'attach'}->[$f]);
|
||||
$atotal += length($fwdmail->{'attach'}->[$f]->{'data'});
|
||||
}
|
||||
}
|
||||
@mailfwd = split(/\0/, $in{'mailforward'});
|
||||
|
||||
# Add forwarded emails
|
||||
if (@mailfwd) {
|
||||
# Add forwarded emails
|
||||
@mail = &mailbox_list_mails($mailfwd[0], $mailfwd[@mailfwd-1], $folder);
|
||||
foreach $f (@mailfwd) {
|
||||
$fwdmail = $mail[$f];
|
||||
|
||||
@@ -56,6 +56,11 @@ $body = $htmlbody if ($in{'body'} == 2);
|
||||
$body = $textbody if ($in{'body'} == 1);
|
||||
@attach = @{$mail->{'attach'}};
|
||||
|
||||
# Show pre-body HTML
|
||||
if ($body && $body eq $htmlbody) {
|
||||
$headstuff = &head_html($body->{'data'});
|
||||
}
|
||||
|
||||
$mail_charset = &get_mail_charset($mail, $body);
|
||||
if ($body && &get_charset() eq 'UTF-8' &&
|
||||
&can_convert_to_utf8(undef, $mail_charset)) {
|
||||
@@ -67,7 +72,7 @@ else {
|
||||
$main::force_charset = &get_mail_charset($mail, $body);
|
||||
}
|
||||
|
||||
&mail_page_header($text{'view_title'}, undef, undef,
|
||||
&mail_page_header($text{'view_title'}, $headstuff, undef,
|
||||
&folder_link($in{'user'}, $folder));
|
||||
&show_arrows();
|
||||
|
||||
@@ -156,28 +161,19 @@ if ($body && $body->{'data'} =~ /\S/) {
|
||||
}
|
||||
elsif ($body eq $htmlbody) {
|
||||
# Attempt to show HTML
|
||||
$bodycontents = $body->{'data'};
|
||||
my @imageurls;
|
||||
my $image_mode = int(defined($in{'images'}) ? $in{'images'} : $config{'view_images'});
|
||||
$bodycontents = &disable_html_images($bodycontents, $image_mode, \@imageurls);
|
||||
$bodycontents = &safe_html($body->{'data'});
|
||||
$bodycontents = &fix_cids($bodycontents, \@attach,
|
||||
"detach.cgi?user=$uuser&idx=$in{'idx'}&folder=$in{'folder'}$subs");
|
||||
if ($textbody) {
|
||||
push(@bodyright,
|
||||
"<a href='$hbase&body=1'>$text{'view_astext'}</a>");
|
||||
}
|
||||
if (@imageurls && $image_mode && $image_mode != 3) {
|
||||
# Link to show images
|
||||
push(@bodyright, "<a href='$hbase&body=$in{'body'}&headers=$in{'headers'}&images=3'>$text{'view_images'}</a>");
|
||||
}
|
||||
}
|
||||
$bodycontents = &iframe_body($bodycontents)
|
||||
if ($bodycontents);
|
||||
}
|
||||
if ($bodycontents) {
|
||||
print &ui_table_start($text{'view_body'}, "width=100%", 1,
|
||||
undef, &ui_links_row(\@bodyright));
|
||||
print &ui_table_row(undef, $bodycontents, undef, undef, ["data-contents='email'"]);
|
||||
print &ui_table_row(undef, $bodycontents);
|
||||
print &ui_table_end();
|
||||
}
|
||||
else {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user