blob: 5bf5fda0db1e0587de9b67232b2b8816c39e544a [file] [log] [blame]
// Copyright 2016 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
// A Series of time based utilites for Milo.
// Requires: moment.js, moment-timezone.js, jquery, jquery-ui
// This file cannot use EcmaScript6: crbug.com/791528
(function(window) {
'use strict';
const tz = moment.tz.guess();
/**
* Given a Date, return a time string in the user's local timezone.
* Also return the time string in relative time from now, MTV time, and UTC
* time.
*/
function formatDate(t) {
var mt = moment.tz(t, tz);
if (!mt.isValid()) {
return null;
}
return {
local: mt.format("YYYY-MM-DD LT (z)"),
localLong: mt.format("YYYY-MM-DD LTS (z)"),
MTVLong: moment.tz(mt, "America/Los_Angeles").format(
"YYYY-MM-DD LTS [(MTV)]"),
UTCLong: moment.tz(mt, "UTC").format("YYYY-MM-DD LTS [(UTC)]"),
fromNow: mt.fromNow(),
}
}
/**
* Given two Dates (or a Date and null, prepresenting "now"), return
* a duration string, with a hover string of the start/end time in the user's
* timezone and locale.
*/
function formatDuration(start, end) {
var st = moment.tz(start, tz);
if (!st.isValid()) {
return null;
}
var hover = st.format("[Started: ] YYYY-MM-DD LTS (z)");
hover += "\nEnded: ";
if (end == null) {
hover += "N/A";
} else {
var et = moment.tz(end, tz);
if (!et.isValid()) {
return null
}
hover += et.format("YYYY-MM-DD LTS (z)");
}
return hover;
}
function makeTimesLocal(locale) {
// Moment.js does not set the locale automatically, it must be done by the
// caller.
locale = locale || window.navigator.userLanguage || window.navigator.language;
moment.locale(locale);
var timeSpans = document.getElementsByClassName('local-time');
for (var i = 0; i < timeSpans.length; i++) {
var span = timeSpans[i];
try {
var oldTimestamp = span.innerText;
var timestamp = span.getAttribute('data-timestamp');
var date = new Date(parseInt(timestamp, 10));
var newTimestamp = formatDate(date);
if (newTimestamp != null) {
span.setAttribute(
"title", [
newTimestamp.fromNow,
newTimestamp.localLong,
newTimestamp.MTVLong,
newTimestamp.UTCLong,
].join("\n")
)
if (!$(span).hasClass('tooltip-only'))
span.innerText = newTimestamp.local;
}
} catch (e) {
console.error('could not convert time of span', span, 'to local:', e)
}
}
}
function annotateDurations() {
var durations = document.getElementsByClassName('duration');
for (var i = 0; i < durations.length; i++) {
var dur = durations[i];
try {
var start = dur.getAttribute('data-starttime');
var end = dur.getAttribute('data-endtime');
var hover = formatDuration(start, end);
if (hover != null) {
dur.setAttribute("title", hover);
}
} catch (e) {
console.error('could not annotate duration', dur, e)
}
}
}
// Export all methods and attributes as module level functions.
Object.assign(window.milo = window.milo || {}, {
makeTimesLocal: makeTimesLocal,
annotateDurations: annotateDurations
});
}(window));