[tools 1/2] testbot/cgi: Handle the timestamp formatting in ValueFormatter.

Francois Gouget fgouget at codeweavers.com
Thu Apr 21 09:27:58 CDT 2022


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 at codeweavers.com>
---
This can be tested on the Wine-devel page (it relies on the
CollectionBlock for the formatting of the Received column).
Later patches will extend datetime.js so other pages can use it too.
---
 .../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(-)
 create mode 100644 testbot/web/js/datetime.js

diff --git a/testbot/lib/ObjectModel/CGI/CollectionBlock.pm b/testbot/lib/ObjectModel/CGI/CollectionBlock.pm
index e849d5a59..03f1d18cd 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 cad6eee1b..47236c748 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 000000000..8f56719ca
--- /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);
-- 
2.30.2




More information about the wine-devel mailing list