js: Convert static/js/timerender.js to ES6 module.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-02-27 16:14:36 -08:00 committed by Tim Abbott
parent 9a0fc5cc87
commit 7e9b5efa8a
27 changed files with 55 additions and 44 deletions

View File

@ -180,7 +180,6 @@
"StripeCheckout": false, "StripeCheckout": false,
"subs": false, "subs": false,
"message_view_header": false, "message_view_header": false,
"timerender": false,
"typing_events": false, "typing_events": false,
"ui": false, "ui": false,
"ui_init": false, "ui_init": false,

View File

@ -3,13 +3,17 @@
const {strict: assert} = require("assert"); const {strict: assert} = require("assert");
const _ = require("lodash"); const _ = require("lodash");
const rewiremock = require("rewiremock/node");
const {set_global, zrequire} = require("../zjsunit/namespace"); const {set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test"); const {run_test} = require("../zjsunit/test");
const page_params = set_global("page_params", {}); const page_params = set_global("page_params", {});
const timerender = set_global("timerender", {}); const timerender = {__esModule: true};
rewiremock("../../static/js/timerender").with(timerender);
rewiremock.enable();
const people = zrequire("people"); const people = zrequire("people");
const presence = zrequire("presence"); const presence = zrequire("presence");
@ -351,3 +355,4 @@ run_test("error handling", (override) => {
blueslip.expect("warn", "Got user_id in presence but not people: 42"); blueslip.expect("warn", "Got user_id in presence but not people: 42");
buddy_data.get_filtered_and_sorted_user_ids(); buddy_data.get_filtered_and_sorted_user_ids();
}); });
rewiremock.disable();

View File

@ -289,7 +289,7 @@ run_test("format_drafts", (override) => {
assert.deepEqual(draft_model.get(), data); assert.deepEqual(draft_model.get(), data);
const stub_render_now = timerender.render_now; const stub_render_now = timerender.render_now;
timerender.render_now = (time) => stub_render_now(time, new Date(1549958107000)); timerender.__Rewire__("render_now", (time) => stub_render_now(time, new Date(1549958107000)));
stub_templates((template_name, data) => { stub_templates((template_name, data) => {
assert.equal(template_name, "draft_table_body"); assert.equal(template_name, "draft_table_body");
@ -303,6 +303,6 @@ run_test("format_drafts", (override) => {
$.create("#drafts_table .draft-row", {children: []}); $.create("#drafts_table .draft-row", {children: []});
drafts.launch(); drafts.launch();
timerender.render_now = stub_render_now; timerender.__Rewire__("render_now", stub_render_now);
}); });
rewiremock.disable(); rewiremock.disable();

View File

@ -18,7 +18,7 @@ const page_params = set_global("page_params", {
set_global("home_msg_list", "stub"); set_global("home_msg_list", "stub");
set_global("unread", {message_unread() {}}); set_global("unread", {message_unread() {}});
// timerender calls setInterval when imported // timerender calls setInterval when imported
set_global("timerender", { rewiremock("../../static/js/timerender").with({
render_date(time1, time2) { render_date(time1, time2) {
if (time2 === undefined) { if (time2 === undefined) {
return [{outerHTML: String(time1.getTime())}]; return [{outerHTML: String(time1.getTime())}];

View File

@ -7,7 +7,6 @@ const {run_test} = require("../zjsunit/test");
const page_params = set_global("page_params", {}); const page_params = set_global("page_params", {});
zrequire("timerender");
const muting = zrequire("muting"); const muting = zrequire("muting");
const stream_data = zrequire("stream_data"); const stream_data = zrequire("stream_data");

View File

@ -29,7 +29,7 @@ set_global("message_view_header", {
render_title_area: noop, render_title_area: noop,
}); });
set_global("timerender", { rewiremock("../../static/js/timerender").with({
last_seen_status_from_date: () => "Just now", last_seen_status_from_date: () => "Just now",
get_full_datetime: () => ({ get_full_datetime: () => ({
date: "date", date: "date",

View File

@ -19,7 +19,6 @@ const rm = zrequire("rendered_markdown");
const people = zrequire("people"); const people = zrequire("people");
const user_groups = zrequire("user_groups"); const user_groups = zrequire("user_groups");
const stream_data = zrequire("stream_data"); const stream_data = zrequire("stream_data");
zrequire("timerender");
const iago = { const iago = {
email: "iago@zulip.com", email: "iago@zulip.com",

View File

@ -13,7 +13,6 @@ const muting_ui = {__esModule: true};
rewiremock("../../static/js/muting_ui").with(muting_ui); rewiremock("../../static/js/muting_ui").with(muting_ui);
rewiremock.enable(); rewiremock.enable();
zrequire("timerender");
const settings_muting = zrequire("settings_muting"); const settings_muting = zrequire("settings_muting");
const stream_data = zrequire("stream_data"); const stream_data = zrequire("stream_data");
const muting = zrequire("muting"); const muting = zrequire("muting");

View File

@ -96,7 +96,7 @@ set_global("settings_sections", {initialize() {}});
rewiremock("../../static/js/settings_panel_menu").with({initialize() {}}); rewiremock("../../static/js/settings_panel_menu").with({initialize() {}});
rewiremock("../../static/js/settings_toggle").with({initialize() {}}); rewiremock("../../static/js/settings_toggle").with({initialize() {}});
set_global("subs", {initialize() {}}); set_global("subs", {initialize() {}});
set_global("timerender", {initialize() {}}); rewiremock("../../static/js/timerender").with({initialize() {}});
const ui = set_global("ui", {initialize() {}}); const ui = set_global("ui", {initialize() {}});
rewiremock("../../static/js/unread_ui").with({initialize() {}}); rewiremock("../../static/js/unread_ui").with({initialize() {}});

View File

@ -4,6 +4,7 @@ import render_archive_message_group from "../templates/archive_message_group.hbs
import * as color_data from "./color_data"; import * as color_data from "./color_data";
import * as floating_recipient_bar from "./floating_recipient_bar"; import * as floating_recipient_bar from "./floating_recipient_bar";
import * as timerender from "./timerender";
const {format, isSameDay} = require("date-fns"); const {format, isSameDay} = require("date-fns");

View File

@ -4,6 +4,7 @@ import render_uploaded_files_list from "../templates/uploaded_files_list.hbs";
import * as channel from "./channel"; import * as channel from "./channel";
import * as ListWidget from "./list_widget"; import * as ListWidget from "./list_widget";
import * as loading from "./loading"; import * as loading from "./loading";
import * as timerender from "./timerender";
import * as ui_report from "./ui_report"; import * as ui_report from "./ui_report";
let attachments; let attachments;

View File

@ -2,6 +2,7 @@ import * as compose_fade from "./compose_fade";
import * as hash_util from "./hash_util"; import * as hash_util from "./hash_util";
import * as people from "./people"; import * as people from "./people";
import * as presence from "./presence"; import * as presence from "./presence";
import * as timerender from "./timerender";
import * as user_status from "./user_status"; import * as user_status from "./user_status";
import * as util from "./util"; import * as util from "./util";

View File

@ -33,7 +33,6 @@ import "../notifications";
import "../message_events"; import "../message_events";
import "../server_events"; import "../server_events";
import "../zulip"; import "../zulip";
import "../timerender";
import "../hotspots"; import "../hotspots";
import "../templates"; import "../templates";
import "../upload_widget"; import "../upload_widget";

View File

@ -19,6 +19,7 @@ const rows = require("./rows");
const settings_data = require("./settings_data"); const settings_data = require("./settings_data");
const stream_data = require("./stream_data"); const stream_data = require("./stream_data");
const stream_topic_history = require("./stream_topic_history"); const stream_topic_history = require("./stream_topic_history");
const timerender = require("./timerender");
const typeahead_helper = require("./typeahead_helper"); const typeahead_helper = require("./typeahead_helper");
const user_groups = require("./user_groups"); const user_groups = require("./user_groups");
const user_pill = require("./user_pill"); const user_pill = require("./user_pill");

View File

@ -13,6 +13,7 @@ import * as overlays from "./overlays";
import * as people from "./people"; import * as people from "./people";
import * as stream_color from "./stream_color"; import * as stream_color from "./stream_color";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as timerender from "./timerender";
import * as util from "./util"; import * as util from "./util";
function set_count(count) { function set_count(count) {

View File

@ -1,5 +1,6 @@
import * as message_store from "./message_store"; import * as message_store from "./message_store";
import * as rows from "./rows"; import * as rows from "./rows";
import * as timerender from "./timerender";
let is_floating_recipient_bar_showing = false; let is_floating_recipient_bar_showing = false;

View File

@ -51,7 +51,6 @@ declare let settings_users: any;
declare let stream_list: any; declare let stream_list: any;
declare let subs: any; declare let subs: any;
declare let message_view_header: any; declare let message_view_header: any;
declare let timerender: any;
declare let typing_events: any; declare let typing_events: any;
declare let ui: any; declare let ui: any;
declare let unread: any; declare let unread: any;

View File

@ -2,6 +2,7 @@ import render_message_edit_history from "../templates/message_edit_history.hbs";
import * as channel from "./channel"; import * as channel from "./channel";
import * as people from "./people"; import * as people from "./people";
import * as timerender from "./timerender";
import * as ui_report from "./ui_report"; import * as ui_report from "./ui_report";
const {format, isSameDay} = require("date-fns"); const {format, isSameDay} = require("date-fns");

View File

@ -22,6 +22,7 @@ import * as rows from "./rows";
import * as stream_color from "./stream_color"; import * as stream_color from "./stream_color";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as submessage from "./submessage"; import * as submessage from "./submessage";
import * as timerender from "./timerender";
import * as util from "./util"; import * as util from "./util";
function same_day(earlier_msg, later_msg) { function same_day(earlier_msg, later_msg) {

View File

@ -1,5 +1,6 @@
import {FoldDict} from "./fold_dict"; import {FoldDict} from "./fold_dict";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as timerender from "./timerender";
const muted_topics = new Map(); const muted_topics = new Map();

View File

@ -17,6 +17,7 @@ const notifications = require("./notifications");
const people = require("./people"); const people = require("./people");
const recent_senders = require("./recent_senders"); const recent_senders = require("./recent_senders");
const stream_data = require("./stream_data"); const stream_data = require("./stream_data");
const timerender = require("./timerender");
const top_left_corner = require("./top_left_corner"); const top_left_corner = require("./top_left_corner");
const topics = new Map(); // Key is stream-id:topic. const topics = new Map(); // Key is stream-id:topic.

View File

@ -7,6 +7,7 @@ import * as people from "./people";
import * as rtl from "./rtl"; import * as rtl from "./rtl";
import * as settings_config from "./settings_config"; import * as settings_config from "./settings_config";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as timerender from "./timerender";
import * as user_groups from "./user_groups"; import * as user_groups from "./user_groups";
const {parseISO, isValid} = require("date-fns"); const {parseISO, isValid} = require("date-fns");

View File

@ -6,6 +6,7 @@ const channel = require("./channel");
const ListWidget = require("./list_widget"); const ListWidget = require("./list_widget");
const loading = require("./loading"); const loading = require("./loading");
const people = require("./people"); const people = require("./people");
const timerender = require("./timerender");
const ui_report = require("./ui_report"); const ui_report = require("./ui_report");
const meta = { const meta = {

View File

@ -8,6 +8,7 @@ const ListWidget = require("./list_widget");
const loading = require("./loading"); const loading = require("./loading");
const people = require("./people"); const people = require("./people");
const settings_config = require("./settings_config"); const settings_config = require("./settings_config");
const timerender = require("./timerender");
const ui_report = require("./ui_report"); const ui_report = require("./ui_report");
const util = require("./util"); const util = require("./util");

View File

@ -14,6 +14,7 @@ const settings_config = require("./settings_config");
const settings_data = require("./settings_data"); const settings_data = require("./settings_data");
const settings_panel_menu = require("./settings_panel_menu"); const settings_panel_menu = require("./settings_panel_menu");
const settings_ui = require("./settings_ui"); const settings_ui = require("./settings_ui");
const timerender = require("./timerender");
const ui_report = require("./ui_report"); const ui_report = require("./ui_report");
const user_pill = require("./user_pill"); const user_pill = require("./user_pill");

View File

@ -1,5 +1,3 @@
"use strict";
const { const {
differenceInMinutes, differenceInMinutes,
differenceInCalendarDays, differenceInCalendarDays,
@ -20,7 +18,7 @@ let next_timerender_id = 0;
// needs_update: a boolean for if it will need to be updated when the // needs_update: a boolean for if it will need to be updated when the
// day changes // day changes
// } // }
exports.render_now = function (time, today = new Date()) { export function render_now(time, today = new Date()) {
let time_str = ""; let time_str = "";
let needs_update = false; let needs_update = false;
// render formal time to be used as title attr tooltip // render formal time to be used as title attr tooltip
@ -58,10 +56,10 @@ exports.render_now = function (time, today = new Date()) {
formal_time_str, formal_time_str,
needs_update, needs_update,
}; };
}; }
// Current date is passed as an argument for unit testing // Current date is passed as an argument for unit testing
exports.last_seen_status_from_date = function (last_active_date, current_date = new Date()) { export function last_seen_status_from_date(last_active_date, current_date = new Date()) {
const minutes = differenceInMinutes(current_date, last_active_date); const minutes = differenceInMinutes(current_date, last_active_date);
if (minutes <= 2) { if (minutes <= 2) {
return i18n.t("Just now"); return i18n.t("Just now");
@ -99,7 +97,7 @@ exports.last_seen_status_from_date = function (last_active_date, current_date =
return i18n.t("__last_active_date__", { return i18n.t("__last_active_date__", {
last_active_date: format(last_active_date, "MMM\u00A0dd,\u00A0yyyy"), last_active_date: format(last_active_date, "MMM\u00A0dd,\u00A0yyyy"),
}); });
}; }
// List of the dates that need to be updated when the day changes. // List of the dates that need to be updated when the day changes.
// Each timestamp is represented as a list of length 2: // Each timestamp is represented as a list of length 2:
@ -109,9 +107,10 @@ let update_list = [];
// The time at the beginning of the day, when the timestamps were updated. // The time at the beginning of the day, when the timestamps were updated.
// Represented as a Date with hour, minute, second, millisecond 0. // Represented as a Date with hour, minute, second, millisecond 0.
let last_update; let last_update;
exports.initialize = function () {
export function initialize() {
last_update = startOfToday(); last_update = startOfToday();
}; }
// time_above is an optional argument, to support dates that look like: // time_above is an optional argument, to support dates that look like:
// --- ▲ Yesterday ▲ ------ ▼ Today ▼ --- // --- ▲ Yesterday ▲ ------ ▼ Today ▼ ---
@ -147,13 +146,13 @@ function render_date_span(elem, rendered_time, rendered_time_above) {
// (What's actually spliced into the message template is the contents // (What's actually spliced into the message template is the contents
// of this DOM node as HTML, so effectively a copy of the node. That's // of this DOM node as HTML, so effectively a copy of the node. That's
// okay since to update the time later we look up the node by its id.) // okay since to update the time later we look up the node by its id.)
exports.render_date = function (time, time_above, today) { export function render_date(time, time_above, today) {
const className = "timerender" + next_timerender_id; const className = "timerender" + next_timerender_id;
next_timerender_id += 1; next_timerender_id += 1;
const rendered_time = exports.render_now(time, today); const rendered_time = render_now(time, today);
let node = $("<span />").attr("class", className); let node = $("<span />").attr("class", className);
if (time_above !== undefined) { if (time_above !== undefined) {
const rendered_time_above = exports.render_now(time_above, today); const rendered_time_above = render_now(time_above, today);
node = render_date_span(node, rendered_time, rendered_time_above); node = render_date_span(node, rendered_time, rendered_time_above);
} else { } else {
node = render_date_span(node, rendered_time); node = render_date_span(node, rendered_time);
@ -165,10 +164,10 @@ exports.render_date = function (time, time_above, today) {
time_above, time_above,
}); });
return node; return node;
}; }
// Renders the timestamp returned by the <time:> Markdown syntax. // Renders the timestamp returned by the <time:> Markdown syntax.
exports.render_markdown_timestamp = function (time, text) { export function render_markdown_timestamp(time, text) {
const hourformat = page_params.twenty_four_hour_time ? "HH:mm" : "h:mm a"; const hourformat = page_params.twenty_four_hour_time ? "HH:mm" : "h:mm a";
const timestring = format(time, "E, MMM d yyyy, " + hourformat); const timestring = format(time, "E, MMM d yyyy, " + hourformat);
const titlestring = "This time is in your timezone. Original text was '" + text + "'."; const titlestring = "This time is in your timezone. Original text was '" + text + "'.";
@ -176,11 +175,11 @@ exports.render_markdown_timestamp = function (time, text) {
text: timestring, text: timestring,
title: titlestring, title: titlestring,
}; };
}; }
// This isn't expected to be called externally except manually for // This isn't expected to be called externally except manually for
// testing purposes. // testing purposes.
exports.update_timestamps = function () { export function update_timestamps() {
const today = startOfToday(); const today = startOfToday();
if (today !== last_update) { if (today !== last_update) {
const to_process = update_list; const to_process = update_list;
@ -196,9 +195,9 @@ exports.update_timestamps = function () {
for (const element of elements) { for (const element of elements) {
const time = entry.time; const time = entry.time;
const time_above = entry.time_above; const time_above = entry.time_above;
const rendered_time = exports.render_now(time, today); const rendered_time = render_now(time, today);
if (time_above) { if (time_above) {
const rendered_time_above = exports.render_now(time_above, today); const rendered_time_above = render_now(time_above, today);
render_date_span($(element), rendered_time, rendered_time_above); render_date_span($(element), rendered_time, rendered_time_above);
} else { } else {
render_date_span($(element), rendered_time); render_date_span($(element), rendered_time);
@ -215,17 +214,17 @@ exports.update_timestamps = function () {
last_update = today; last_update = today;
} }
}; }
setInterval(exports.update_timestamps, 60 * 1000); setInterval(update_timestamps, 60 * 1000);
// Transform a Unix timestamp into a ISO 8601 formatted date string. // Transform a Unix timestamp into a ISO 8601 formatted date string.
// Example: 1978-10-31T13:37:42Z // Example: 1978-10-31T13:37:42Z
exports.get_full_time = function (timestamp) { export function get_full_time(timestamp) {
return formatISO(timestamp * 1000); return formatISO(timestamp * 1000);
}; }
exports.get_timestamp_for_flatpickr = (timestring) => { export function get_timestamp_for_flatpickr(timestring) {
let timestamp; let timestamp;
try { try {
// If there's already a valid time in the compose box, // If there's already a valid time in the compose box,
@ -238,18 +237,18 @@ exports.get_timestamp_for_flatpickr = (timestring) => {
} }
} }
return timestamp; return timestamp;
}; }
exports.stringify_time = function (time) { export function stringify_time(time) {
if (page_params.twenty_four_hour_time) { if (page_params.twenty_four_hour_time) {
return format(time, "HH:mm"); return format(time, "HH:mm");
} }
return format(time, "h:mm a"); return format(time, "h:mm a");
}; }
// this is for rendering absolute time based off the preferences for twenty-four // this is for rendering absolute time based off the preferences for twenty-four
// hour time in the format of "%mmm %d, %h:%m %p". // hour time in the format of "%mmm %d, %h:%m %p".
exports.absolute_time = (function () { export const absolute_time = (function () {
const MONTHS = [ const MONTHS = [
"Jan", "Jan",
"Feb", "Feb",
@ -302,7 +301,7 @@ exports.absolute_time = (function () {
}; };
})(); })();
exports.get_full_datetime = function (time) { export function get_full_datetime(time) {
// Convert to number of hours ahead/behind UTC. // Convert to number of hours ahead/behind UTC.
// The sign of getTimezoneOffset() is reversed wrt // The sign of getTimezoneOffset() is reversed wrt
// the conventional meaning of UTC+n / UTC-n // the conventional meaning of UTC+n / UTC-n
@ -311,23 +310,21 @@ exports.get_full_datetime = function (time) {
date: time.toLocaleDateString(), date: time.toLocaleDateString(),
time: time.toLocaleTimeString() + " (UTC" + (tz_offset < 0 ? "" : "+") + tz_offset + ")", time: time.toLocaleTimeString() + " (UTC" + (tz_offset < 0 ? "" : "+") + tz_offset + ")",
}; };
}; }
// Date.toLocaleDateString and Date.toLocaleTimeString are // Date.toLocaleDateString and Date.toLocaleTimeString are
// expensive, so we delay running the following code until we need // expensive, so we delay running the following code until we need
// the full date and time strings. // the full date and time strings.
exports.set_full_datetime = function timerender_set_full_datetime(message, time_elem) { export const set_full_datetime = function timerender_set_full_datetime(message, time_elem) {
if (message.full_date_str !== undefined) { if (message.full_date_str !== undefined) {
return; return;
} }
const time = new Date(message.timestamp * 1000); const time = new Date(message.timestamp * 1000);
const full_datetime = exports.get_full_datetime(time); const full_datetime = get_full_datetime(time);
message.full_date_str = full_datetime.date; message.full_date_str = full_datetime.date;
message.full_time_str = full_datetime.time; message.full_time_str = full_datetime.time;
time_elem.attr("title", message.full_date_str + " " + message.full_time_str); time_elem.attr("title", message.full_date_str + " " + message.full_time_str);
}; };
window.timerender = exports;

View File

@ -50,6 +50,7 @@ const starred_messages = require("./starred_messages");
const stream_color = require("./stream_color"); const stream_color = require("./stream_color");
const stream_data = require("./stream_data"); const stream_data = require("./stream_data");
const stream_edit = require("./stream_edit"); const stream_edit = require("./stream_edit");
const timerender = require("./timerender");
const topic_list = require("./topic_list"); const topic_list = require("./topic_list");
const topic_zoom = require("./topic_zoom"); const topic_zoom = require("./topic_zoom");
const tutorial = require("./tutorial"); const tutorial = require("./tutorial");