diff --git a/tools/test-js-with-node b/tools/test-js-with-node
index 813fea9fca..1eb786fae9 100755
--- a/tools/test-js-with-node
+++ b/tools/test-js-with-node
@@ -134,6 +134,7 @@ EXEMPT_FILES = make_set(
"web/src/overlays.ts",
"web/src/padded_widget.ts",
"web/src/page_params.ts",
+ "web/src/playground_links_popover.js",
"web/src/plotly.js.d.ts",
"web/src/pm_list.js",
"web/src/pm_list_dom.js",
diff --git a/web/src/playground_links_popover.js b/web/src/playground_links_popover.js
index 0348bfc4cb..8f6ff10b52 100644
--- a/web/src/playground_links_popover.js
+++ b/web/src/playground_links_popover.js
@@ -4,51 +4,60 @@ import url_template_lib from "url-template";
import render_playground_links_popover_content from "../templates/playground_links_popover_content.hbs";
import * as blueslip from "./blueslip";
-import * as message_viewport from "./message_viewport";
+import * as popover_menus from "./popover_menus";
import * as popovers from "./popovers";
import * as realm_playground from "./realm_playground";
+import * as ui_util from "./ui_util";
-let $current_playground_links_popover_elem;
+let playground_links_popover_instance;
// Playground_info contains all the data we need to generate a popover of
// playground links for each code block. The element is the target element
// to pop off of.
function toggle_playground_links_popover(element, playground_info) {
- const $last_popover_elem = $current_playground_links_popover_elem;
- popovers.hide_all();
- if ($last_popover_elem !== undefined && $last_popover_elem.get()[0] === element) {
- // We want it to be the case that a user can dismiss a popover
- // by clicking on the same element that caused the popover.
+ if (is_open()) {
return;
}
- const $elt = $(element);
- if ($elt.data("popover") === undefined) {
- const ypos = $elt.get_offset_to_window().top;
- $elt.popover({
- // It's unlikely we'll have more than 3-4 playground links
- // for one language, so it should be OK to hardcode 120 here.
- placement: message_viewport.height() - ypos < 120 ? "top" : "bottom",
- title: "",
- content: render_playground_links_popover_content({playground_info}),
- html: true,
- trigger: "manual",
- fixed: true,
- });
- $elt.popover("show");
- $elt.addClass("active-playground-links-reference");
- $current_playground_links_popover_elem = $elt;
- }
+
+ popover_menus.toggle_popover_menu(element, {
+ placement: "bottom",
+ popperOptions: {
+ modifiers: [
+ {
+ name: "flip",
+ options: {
+ fallbackPlacements: ["top"],
+ },
+ },
+ ],
+ },
+ onCreate(instance) {
+ playground_links_popover_instance = instance;
+ instance.setContent(
+ ui_util.parse_html(render_playground_links_popover_content({playground_info})),
+ );
+ },
+ onShow(instance) {
+ const $reference = $(instance.reference);
+ $reference.parent().addClass("active-playground-links-reference");
+ },
+ onHidden() {
+ hide();
+ },
+ });
}
export function is_open() {
- return Boolean($current_playground_links_popover_elem);
+ return Boolean(playground_links_popover_instance);
}
export function hide() {
if (is_open()) {
- $current_playground_links_popover_elem.removeClass("active-playground-links-reference");
- $current_playground_links_popover_elem.popover("destroy");
- $current_playground_links_popover_elem = undefined;
+ $(playground_links_popover_instance.reference)
+ .parent()
+ .removeClass("active-playground-links-reference");
+ playground_links_popover_instance.destroy();
+ playground_links_popover_instance = undefined;
}
}
@@ -58,13 +67,13 @@ function get_playground_links_popover_items() {
return undefined;
}
- const popover_data = $current_playground_links_popover_elem.data("popover");
- if (!popover_data) {
+ const $popover = $(playground_links_popover_instance.popper);
+ if (!$popover) {
blueslip.error("Cannot find playground links popover data");
return undefined;
}
- return $("li:not(.divider):visible a", popover_data.$tip);
+ return $("li:not(.divider):visible a", $popover);
}
export function handle_keyboard(key) {
@@ -99,7 +108,10 @@ function register_click_handlers() {
const url_template = url_template_lib.parse($playground.url_template);
$playground.playground_url = url_template.expand({code: extracted_code});
}
- toggle_playground_links_popover(this, playground_info);
+ const popover_target = $view_in_playground_button.find(
+ ".playground-links-popover-container",
+ )[0];
+ toggle_playground_links_popover(popover_target, playground_info);
}
},
);
diff --git a/web/templates/view_code_in_playground.hbs b/web/templates/view_code_in_playground.hbs
index 9a8904203f..fa9572947d 100644
--- a/web/templates/view_code_in_playground.hbs
+++ b/web/templates/view_code_in_playground.hbs
@@ -1,2 +1,2 @@
{{! Display the "view code in playground" option for code blocks}}
-
+