mirror of https://github.com/zulip/zulip.git
tippyjs: Convert module to TypeScript.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
a8bc7ceb15
commit
1dd386a65a
|
@ -239,7 +239,7 @@ EXEMPT_FILES = make_set(
|
||||||
"web/src/submessage.js",
|
"web/src/submessage.js",
|
||||||
"web/src/subscriber_api.js",
|
"web/src/subscriber_api.js",
|
||||||
"web/src/timerender.ts",
|
"web/src/timerender.ts",
|
||||||
"web/src/tippyjs.js",
|
"web/src/tippyjs.ts",
|
||||||
"web/src/todo_widget.js",
|
"web/src/todo_widget.js",
|
||||||
"web/src/topic_list.js",
|
"web/src/topic_list.js",
|
||||||
"web/src/topic_popover.js",
|
"web/src/topic_popover.js",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
import assert from "minimalistic-assert";
|
||||||
import tippy, {delegate} from "tippy.js";
|
import tippy, {delegate} from "tippy.js";
|
||||||
|
|
||||||
import render_tooltip_templates from "../templates/tooltip_templates.hbs";
|
import render_tooltip_templates from "../templates/tooltip_templates.hbs";
|
||||||
|
@ -8,12 +9,16 @@ import {user_settings} from "./user_settings";
|
||||||
|
|
||||||
// For tooltips without data-tippy-content, we use the HTML content of
|
// For tooltips without data-tippy-content, we use the HTML content of
|
||||||
// a <template> whose id is given by data-tooltip-template-id.
|
// a <template> whose id is given by data-tooltip-template-id.
|
||||||
function get_tooltip_content(reference) {
|
function get_tooltip_content(reference: Element): string | Element | DocumentFragment {
|
||||||
if ("tooltipTemplateId" in reference.dataset) {
|
if (reference instanceof HTMLElement && reference.dataset.tooltipTemplateId !== undefined) {
|
||||||
const template = document.querySelector(
|
const template = document.querySelector<HTMLTemplateElement>(
|
||||||
`template#${CSS.escape(reference.dataset.tooltipTemplateId)}`,
|
`template#${CSS.escape(reference.dataset.tooltipTemplateId)}`,
|
||||||
);
|
);
|
||||||
return template.content.cloneNode(true);
|
if (template !== null) {
|
||||||
|
const fragment = template.content.cloneNode(true);
|
||||||
|
assert(fragment instanceof DocumentFragment);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -23,19 +28,19 @@ function get_tooltip_content(reference) {
|
||||||
// transition, while the "long" version is intended for elements where
|
// transition, while the "long" version is intended for elements where
|
||||||
// we want to avoid distracting the user with the tooltip
|
// we want to avoid distracting the user with the tooltip
|
||||||
// unnecessarily.
|
// unnecessarily.
|
||||||
const INSTANT_HOVER_DELAY = [100, 20];
|
const INSTANT_HOVER_DELAY: [number, number] = [100, 20];
|
||||||
// INTERACTIVE_HOVER_DELAY is for elements like the emoji reactions, where
|
// INTERACTIVE_HOVER_DELAY is for elements like the emoji reactions, where
|
||||||
// the tooltip includes useful information (who reacted?), but that
|
// the tooltip includes useful information (who reacted?), but that
|
||||||
// needs a short delay for users who are just tapping a reaction
|
// needs a short delay for users who are just tapping a reaction
|
||||||
// element and not interested in the tooltip's contents.
|
// element and not interested in the tooltip's contents.
|
||||||
export const INTERACTIVE_HOVER_DELAY = [425, 20];
|
export const INTERACTIVE_HOVER_DELAY: [number, number] = [425, 20];
|
||||||
export const LONG_HOVER_DELAY = [750, 20];
|
export const LONG_HOVER_DELAY: [number, number] = [750, 20];
|
||||||
// EXTRA_LONG_HOVER_DELAY is for elements like the compose box send
|
// EXTRA_LONG_HOVER_DELAY is for elements like the compose box send
|
||||||
// button where the tooltip content is almost exactly the same as the
|
// button where the tooltip content is almost exactly the same as the
|
||||||
// text in the button, and the tooltip exists just to advertise a
|
// text in the button, and the tooltip exists just to advertise a
|
||||||
// keyboard shortcut. For these tooltips, it's very important to avoid
|
// keyboard shortcut. For these tooltips, it's very important to avoid
|
||||||
// distracting users unnecessarily.
|
// distracting users unnecessarily.
|
||||||
export const EXTRA_LONG_HOVER_DELAY = [1500, 20];
|
export const EXTRA_LONG_HOVER_DELAY: [number, number] = [1500, 20];
|
||||||
|
|
||||||
// We override the defaults set by tippy library here,
|
// We override the defaults set by tippy library here,
|
||||||
// so make sure to check this too after checking tippyjs
|
// so make sure to check this too after checking tippyjs
|
||||||
|
@ -65,7 +70,7 @@ tippy.setDefaultProps({
|
||||||
content: get_tooltip_content,
|
content: get_tooltip_content,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function initialize() {
|
export function initialize(): void {
|
||||||
$("#tooltip-templates-container").html(render_tooltip_templates());
|
$("#tooltip-templates-container").html(render_tooltip_templates());
|
||||||
|
|
||||||
// Our default tooltip configuration. For this, one simply needs to:
|
// Our default tooltip configuration. For this, one simply needs to:
|
||||||
|
@ -152,9 +157,9 @@ export function initialize() {
|
||||||
delay: EXTRA_LONG_HOVER_DELAY,
|
delay: EXTRA_LONG_HOVER_DELAY,
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
onShow(instance) {
|
onShow(instance) {
|
||||||
const container = instance.popper.querySelector(".views-tooltip-container");
|
const $container = $(instance.popper).find(".views-tooltip-container");
|
||||||
if ($(container).data("view-code") === user_settings.web_home_view) {
|
if ($container.data("view-code") === user_settings.web_home_view) {
|
||||||
$(container).find(".views-tooltip-home-view-note").removeClass("hide");
|
$container.find(".views-tooltip-home-view-note").removeClass("hide");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onHidden(instance) {
|
onHidden(instance) {
|
||||||
|
@ -188,7 +193,6 @@ export function initialize() {
|
||||||
content = $t({defaultMessage: "Deselect draft"});
|
content = $t({defaultMessage: "Deselect draft"});
|
||||||
}
|
}
|
||||||
instance.setContent(content);
|
instance.setContent(content);
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -202,7 +206,6 @@ export function initialize() {
|
||||||
content = $t({defaultMessage: "No drafts selected"});
|
content = $t({defaultMessage: "No drafts selected"});
|
||||||
}
|
}
|
||||||
instance.setContent(content);
|
instance.setContent(content);
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -230,7 +233,7 @@ export function initialize() {
|
||||||
".error-icon-message-recipient .zulip-icon",
|
".error-icon-message-recipient .zulip-icon",
|
||||||
"#personal-menu-dropdown .status-circle",
|
"#personal-menu-dropdown .status-circle",
|
||||||
"#copy_generated_invite_link",
|
"#copy_generated_invite_link",
|
||||||
],
|
].join(","),
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -238,7 +241,7 @@ export function initialize() {
|
||||||
target: [
|
target: [
|
||||||
"#compose_top_right [data-tippy-content]",
|
"#compose_top_right [data-tippy-content]",
|
||||||
"#compose_top_right [data-tooltip-template-id]",
|
"#compose_top_right [data-tooltip-template-id]",
|
||||||
],
|
].join(","),
|
||||||
delay: LONG_HOVER_DELAY,
|
delay: LONG_HOVER_DELAY,
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
onHidden(instance) {
|
onHidden(instance) {
|
||||||
|
@ -251,6 +254,9 @@ export function initialize() {
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
onShow(instance) {
|
onShow(instance) {
|
||||||
const title = $(instance.reference).attr("aria-label");
|
const title = $(instance.reference).attr("aria-label");
|
||||||
|
if (title === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const filename = $(instance.reference).prop("data-filename");
|
const filename = $(instance.reference).prop("data-filename");
|
||||||
const $markup = $("<span>").text(title);
|
const $markup = $("<span>").text(title);
|
||||||
if (title !== filename) {
|
if (title !== filename) {
|
||||||
|
@ -260,6 +266,7 @@ export function initialize() {
|
||||||
$markup.append($("<br>"), $("<span>").text(second_line));
|
$markup.append($("<br>"), $("<span>").text(second_line));
|
||||||
}
|
}
|
||||||
instance.setContent($markup[0]);
|
instance.setContent($markup[0]);
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
onHidden(instance) {
|
onHidden(instance) {
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
|
@ -289,7 +296,7 @@ export function initialize() {
|
||||||
"#profile-field-settings .display_in_profile_summary_tooltip",
|
"#profile-field-settings .display_in_profile_summary_tooltip",
|
||||||
"#edit-custom-profile-field-form-modal .display_in_profile_summary_tooltip",
|
"#edit-custom-profile-field-form-modal .display_in_profile_summary_tooltip",
|
||||||
"#add-new-custom-profile-field-form .display_in_profile_summary_tooltip",
|
"#add-new-custom-profile-field-form .display_in_profile_summary_tooltip",
|
||||||
],
|
].join(","),
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage: "Only 2 custom profile fields can be displayed on the user card.",
|
defaultMessage: "Only 2 custom profile fields can be displayed on the user card.",
|
||||||
}),
|
}),
|
||||||
|
@ -304,7 +311,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#full_name_input_container.disabled_setting_tooltip"],
|
target: "#full_name_input_container.disabled_setting_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"Name changes are disabled in this organization. Contact an administrator to change your name.",
|
"Name changes are disabled in this organization. Contact an administrator to change your name.",
|
||||||
|
@ -316,7 +323,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#change_email_button_container.disabled_setting_tooltip"],
|
target: "#change_email_button_container.disabled_setting_tooltip",
|
||||||
content: $t({defaultMessage: "Email address changes are disabled in this organization."}),
|
content: $t({defaultMessage: "Email address changes are disabled in this organization."}),
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
onHidden(instance) {
|
onHidden(instance) {
|
||||||
|
@ -328,7 +335,7 @@ export function initialize() {
|
||||||
target: [
|
target: [
|
||||||
"#deactivate_account_container.disabled_setting_tooltip",
|
"#deactivate_account_container.disabled_setting_tooltip",
|
||||||
"#edit-user-form .deactivate_user_button_tooltip",
|
"#edit-user-form .deactivate_user_button_tooltip",
|
||||||
],
|
].join(","),
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"Because you are the only organization owner, you cannot deactivate your account.",
|
"Because you are the only organization owner, you cannot deactivate your account.",
|
||||||
|
@ -340,7 +347,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#deactivate_realm_button_container.disabled_setting_tooltip"],
|
target: "#deactivate_realm_button_container.disabled_setting_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage: "Only organization owners may deactivate an organization.",
|
defaultMessage: "Only organization owners may deactivate an organization.",
|
||||||
}),
|
}),
|
||||||
|
@ -351,7 +358,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: [".settings-radio-input-parent.default_stream_private_tooltip"],
|
target: ".settings-radio-input-parent.default_stream_private_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage: "Default streams for new users cannot be made private.",
|
defaultMessage: "Default streams for new users cannot be made private.",
|
||||||
}),
|
}),
|
||||||
|
@ -362,7 +369,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: [".default-stream.default_stream_private_tooltip"],
|
target: ".default-stream.default_stream_private_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage: "Private streams cannot be default streams for new users.",
|
defaultMessage: "Private streams cannot be default streams for new users.",
|
||||||
}),
|
}),
|
||||||
|
@ -373,7 +380,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#generate_multiuse_invite_radio_container.disabled_setting_tooltip"],
|
target: "#generate_multiuse_invite_radio_container.disabled_setting_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"You do not have permissions to generate invite links in this organization.",
|
"You do not have permissions to generate invite links in this organization.",
|
||||||
|
@ -388,7 +395,7 @@ export function initialize() {
|
||||||
target: [
|
target: [
|
||||||
"#api_key_button_container.disabled_setting_tooltip",
|
"#api_key_button_container.disabled_setting_tooltip",
|
||||||
"#user_email_address_dropdown_container.disabled_setting_tooltip",
|
"#user_email_address_dropdown_container.disabled_setting_tooltip",
|
||||||
],
|
].join(","),
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage: "You must configure your email to access this feature.",
|
defaultMessage: "You must configure your email to access this feature.",
|
||||||
}),
|
}),
|
||||||
|
@ -399,7 +406,7 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#email_invite_radio_container.disabled_setting_tooltip"],
|
target: "#email_invite_radio_container.disabled_setting_tooltip",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"You do not have permissions to send email invitations in this organization.",
|
"You do not have permissions to send email invitations in this organization.",
|
||||||
|
@ -422,7 +429,6 @@ export function initialize() {
|
||||||
} else {
|
} else {
|
||||||
instance.setContent($t({defaultMessage: "Expand views"}));
|
instance.setContent($t({defaultMessage: "Expand views"}));
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
delay: EXTRA_LONG_HOVER_DELAY,
|
delay: EXTRA_LONG_HOVER_DELAY,
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
|
@ -444,14 +450,14 @@ export function initialize() {
|
||||||
} else {
|
} else {
|
||||||
instance.setContent($t({defaultMessage: "Expand direct messages"}));
|
instance.setContent($t({defaultMessage: "Expand direct messages"}));
|
||||||
}
|
}
|
||||||
return true;
|
return undefined;
|
||||||
},
|
},
|
||||||
delay: EXTRA_LONG_HOVER_DELAY,
|
delay: EXTRA_LONG_HOVER_DELAY,
|
||||||
appendTo: () => document.body,
|
appendTo: () => document.body,
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: ["#stream_creation_form .add_subscribers_disabled"],
|
target: "#stream_creation_form .add_subscribers_disabled",
|
||||||
content: $t({
|
content: $t({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"You do not have permission to add other users to streams in this organization.",
|
"You do not have permission to add other users to streams in this organization.",
|
||||||
|
@ -463,15 +469,15 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate("body", {
|
delegate("body", {
|
||||||
target: [".user_row .actions button"],
|
target: ".user_row .actions button",
|
||||||
trigger: "mouseenter",
|
trigger: "mouseenter",
|
||||||
onShow(instance) {
|
onShow(instance) {
|
||||||
if ($(instance.reference).hasClass("deactivate")) {
|
if ($(instance.reference).hasClass("deactivate")) {
|
||||||
instance.setContent($t({defaultMessage: "Deactivate"}));
|
instance.setContent($t({defaultMessage: "Deactivate"}));
|
||||||
return true;
|
return undefined;
|
||||||
} else if ($(instance.reference).hasClass("reactivate")) {
|
} else if ($(instance.reference).hasClass("reactivate")) {
|
||||||
instance.setContent($t({defaultMessage: "Reactivate"}));
|
instance.setContent($t({defaultMessage: "Reactivate"}));
|
||||||
return true;
|
return undefined;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
Loading…
Reference in New Issue