Module: tools
Branch: master
Commit: 78f2c0fd53ea53647db8157c3b890882bd5d7b95
URL: https://source.winehq.org/git/tools.git/?a=commit;h=78f2c0fd53ea53647db8157…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Thu Apr 21 16:27:58 2022 +0200
testbot/cgi: Handle the timestamp formatting in ValueFormatter.
Also move the JavaScript code to a separate file so it does not have to
be downloaded with every page.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
testbot/lib/ObjectModel/CGI/CollectionBlock.pm | 56 +++-----------
testbot/lib/ObjectModel/CGI/ValueFormatter.pm | 101 +++++++++++++++++++++++--
testbot/web/js/datetime.js | 42 ++++++++++
3 files changed, 148 insertions(+), 51 deletions(-)
diff --git a/testbot/lib/ObjectModel/CGI/CollectionBlock.pm b/testbot/lib/ObjectModel/CGI/CollectionBlock.pm
index e849d5a..03f1d18 100644
--- a/testbot/lib/ObjectModel/CGI/CollectionBlock.pm
+++ b/testbot/lib/ObjectModel/CGI/CollectionBlock.pm
@@ -44,7 +44,6 @@ package ObjectModel::CGI::CollectionBlock;
use Exporter 'import';
our @EXPORT = qw(new);
-use POSIX qw(strftime);
use URI::Escape;
use ObjectModel::CGI::Table;
@@ -291,18 +290,7 @@ sub GenerateDataView($$$)
my $PropertyName = $PropertyDescriptor->GetName();
my $Value = $Row->{Item}->$PropertyName;
-
- if ($PropertyDescriptor->GetClass() eq "Basic" and
- $PropertyDescriptor->GetType() eq "DT" and defined $Value)
- {
- print "<script type='text/javascript'><!--\n",
- "ShowDateTime($Value);\n",
- "//--></script><noscript><div>",
- strftime("%Y-%m-%d %H:%M:%S", localtime($Value)),
- "</div></noscript>\n";
- return;
- }
- print defined $Value ? $self->escapeHTML($Value) : " ";
+ GenerateValueHTML($self, $PropertyDescriptor, $Value);
}
@@ -414,42 +402,20 @@ sub GenerateList($)
my $Collection = $self->{Collection};
my $PropertyDescriptors = $Collection->GetPropertyDescriptors();
- my $HasDT = !1;
- foreach my $PropertyDescriptor (@{$PropertyDescriptors})
+
+ my $Items = $self->{Collection}->GetSortedItems();
+ if (@$Items != 0)
{
- if ($PropertyDescriptor->GetClass() eq "Basic" &&
- $PropertyDescriptor->GetType() eq "DT")
+ foreach my $PropertyDescriptor (@$PropertyDescriptors)
{
- $HasDT = 1;
+ if ($PropertyDescriptor->GetClass() eq "Basic" and
+ $PropertyDescriptor->GetType() eq "DT")
+ {
+ $self->{EnclosingPage}->GenerateImportJS(GetDateTimeJSFile());
+ last;
+ }
}
}
- if ($HasDT)
- {
- print <<"EOF";
-<script type='text/javascript'><!--\
-function Pad2(n)
-{
- return n < 10 ? '0' + n : n;
-}
-
-function ShowDateTime(Sec1970, Id, Attr)
-{
- var Dt = new Date(Sec1970 * 1000);
- var Pretty = Dt.getFullYear() + '-' + Pad2(Dt.getMonth() + 1) + '-' +
- Pad2(Dt.getDate()) + ' ' + Pad2(Dt.getHours()) + ':' +
- Pad2(Dt.getMinutes()) + ':' + Pad2(Dt.getSeconds())
- if (Id != null)
- {
- document.getElementById(Id).setAttribute(Attr || "title", Pretty);
- }
- else
- {
- document.write(Pretty);
- }
-}
-//--></script>
-EOF
- }
print "<div class='CollectionBlock'>\n";
$self->GenerateFormStart();
diff --git a/testbot/lib/ObjectModel/CGI/ValueFormatter.pm b/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
index cad6eee..47236c7 100644
--- a/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
+++ b/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
@@ -22,8 +22,90 @@ use strict;
package ObjectModel::CGI::ValueFormatter;
use Exporter 'import';
-our @EXPORT = qw(GenerateValueHTML);
+our @EXPORT = qw(GetDateTimeJSFile GenerateDateTime GenerateValueHTML);
+use POSIX qw(strftime);
+
+
+#
+# Timestamp formatting
+#
+
+=pod
+=over 12
+
+=item C<GetDateTimeJSFile()>
+
+Returns the path to the file containing the JavaScript code to format
+timestamps.
+
+See GenerateDateTime().
+
+=back
+=cut
+
+sub GetDateTimeJSFile()
+{
+ return "/js/datetime.js";
+}
+
+=pod
+=over 12
+
+=item C<GenerateDateTime()>
+
+Returns an HTML snippet that uses the JavaScript ShowDateTime() function
+to show a timestamp in ISO 8601 format in the user's local timezone.
+
+Note that the timestamp will be shown based on the server's timezone in case
+JavaScript is disabled.
+=over
+
+=item Sec1970
+The timestamp to display as the number of seconds since the Epoch.
+
+=item Class
+A string containing additional classes for the <span> tag used to show the
+date + time.
+
+=item TagAttrs
+A string containing the tag name without the initial bracket, and any
+additional attributes except class and timestamp. By default this is 'span'.
+
+=back
+=back
+=cut
+
+sub GenerateDateTime($;$$)
+{
+ my ($Sec1970, $Class, $TagAttrs) = @_;
+
+ if (defined $Sec1970)
+ {
+ my $Tag;
+ if ($TagAttrs)
+ {
+ $Tag = $TagAttrs;
+ $Tag =~ s/ .*$//;
+ }
+ else
+ {
+ $TagAttrs = $Tag = "span";
+ }
+ $Class = "$Class " if ($Class);
+ print "<$TagAttrs class='${Class}datetime' timestamp='$Sec1970'>",
+ strftime("%Y-%m-%d %H:%M:%S", localtime($Sec1970)), "</$Tag>";
+ }
+ else
+ {
+ print " ";
+ }
+}
+
+
+#
+# Property value formatting
+#
=pod
=over 12
@@ -44,13 +126,20 @@ sub GenerateValueHTML($$$)
{
my ($Parent, $PropertyDescriptor, $Value) = @_;
- if ($PropertyDescriptor->GetClass() eq "Basic" and
- $PropertyDescriptor->GetType() eq "B")
+ if ($PropertyDescriptor->GetClass() eq "Basic")
{
- print $Value ? "Yes" : "No";
- return;
+ if ($PropertyDescriptor->GetType() eq "B")
+ {
+ print $Value ? "Yes" : "No";
+ return;
+ }
+ if ($PropertyDescriptor->GetType() eq "DT")
+ {
+ GenerateDateTime($Value);
+ return;
+ }
}
- if ($PropertyDescriptor->GetClass() eq "Itemref" and defined $Value)
+ elsif ($PropertyDescriptor->GetClass() eq "Itemref" and defined $Value)
{
# Note: This only supports single-key Itemrefs
foreach my $ValuePD (@{$Value->GetPropertyDescriptors()})
diff --git a/testbot/web/js/datetime.js b/testbot/web/js/datetime.js
new file mode 100644
index 0000000..8f56719
--- /dev/null
+++ b/testbot/web/js/datetime.js
@@ -0,0 +1,42 @@
+/* Format timestamps
+ *
+ * Copyright 2022 Francois Gouget
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+"use strict";
+
+function Pad2(n)
+{
+ return n < 10 ? '0' + n : n;
+}
+
+function ShowDateTime(dom)
+{
+ const sec1970 = dom.getAttribute("timestamp");
+ const dt = new Date(sec1970 * 1000);
+ dom.innerHTML = dt.getFullYear() +'-'+ Pad2(dt.getMonth() + 1) +'-'+
+ Pad2(dt.getDate()) +' '+ Pad2(dt.getHours()) +':'+
+ Pad2(dt.getMinutes()) +':'+ Pad2(dt.getSeconds())
+}
+
+function init()
+{
+ document.querySelectorAll(".datetime").forEach(dom => {
+ ShowDateTime(dom);
+ });
+}
+
+window.addEventListener('load', init);