Bug 1266450 - part6: migrate EventDetails tooltip;r=bgrins

For now this is a 1 to 1 migration of the existing Tooltip
helper method from XUL to HTML.

MozReview-Commit-ID: 9YiJLgibV9h

--HG--
extra : rebase_source : af428055060a105d270d70b1e4694717e0869b2b
extra : source : d03cca0c048c9ba1f3062519650e37ae986d4bc7
This commit is contained in:
Julian Descottes 2016-05-31 11:25:43 +02:00
parent 3615d9843b
commit 0f7dbc517b
8 changed files with 348 additions and 326 deletions

View File

@ -35,11 +35,10 @@ const {editableField, InplaceEditor} =
const {HTMLEditor} = require("devtools/client/inspector/markup/html-editor");
const promise = require("promise");
const Services = require("Services");
const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");
const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
const {setImageTooltip, setBrokenImageTooltip} =
require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const {setEventTooltip} = require("devtools/client/shared/widgets/tooltip/EventTooltipHelper");
const EventEmitter = require("devtools/shared/event-emitter");
const Heritage = require("sdk/core/heritage");
const {parseAttribute} =
@ -174,7 +173,8 @@ MarkupView.prototype = {
_selectedContainer: null,
_initTooltips: function () {
this.eventDetailsTooltip = new Tooltip(this._inspector.panelDoc);
this.eventDetailsTooltip = new HTMLTooltip(this._inspector.toolbox,
{type: "arrow"});
this.imagePreviewTooltip = new HTMLTooltip(this._inspector.toolbox,
{type: "arrow"});
this._enableImagePreviewTooltip();
@ -2615,11 +2615,8 @@ MarkupElementContainer.prototype = Heritage.extend(MarkupContainer.prototype, {
tooltip.hide(target);
this.node.getEventListenerInfo().then(listenerInfo => {
tooltip.setEventContent({
eventListenerInfos: listenerInfo,
toolbox: this.markup._inspector.toolbox
});
let toolbox = this.markup._inspector.toolbox;
setEventTooltip(tooltip, listenerInfo, toolbox);
// Disable the image preview tooltip while we display the event details
this.markup._disableImagePreviewTooltip();
tooltip.once("hidden", () => {

View File

@ -43,7 +43,7 @@ add_task(function* () {
yield tooltip.once("shown");
info("EventTooltip visible.");
let container = tooltip.content;
let container = tooltip.panel;
let containerRect = container.getBoundingClientRect();
let headers = container.querySelectorAll(".event-header");

View File

@ -70,7 +70,7 @@ function* checkEventsForNode(test, inspector, testActor) {
info("tooltip shown");
// Check values
let headers = tooltip.content.querySelectorAll(".event-header");
let headers = tooltip.panel.querySelectorAll(".event-header");
let nodeFront = container.node;
let cssSelector = nodeFront.nodeName + "#" + nodeFront.id;
@ -83,19 +83,22 @@ function* checkEventsForNode(test, inspector, testActor) {
let attributes = header.querySelectorAll(".event-tooltip-attributes");
let contentBox = header.nextElementSibling;
is(type.getAttribute("value"), expected[i].type,
is(type.textContent, expected[i].type,
"type matches for " + cssSelector);
is(filename.getAttribute("value"), expected[i].filename,
is(filename.textContent, expected[i].filename,
"filename matches for " + cssSelector);
is(attributes.length, expected[i].attributes.length,
"we have the correct number of attributes");
for (let j = 0; j < expected[i].attributes.length; j++) {
is(attributes[j].getAttribute("value"), expected[i].attributes[j],
is(attributes[j].textContent, expected[i].attributes[j],
"attribute[" + j + "] matches for " + cssSelector);
}
// Make sure the header is not hidden by scrollbars before clicking.
header.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(header, {}, type.ownerGlobal);
yield tooltip.once("event-tooltip-ready");

View File

@ -110,14 +110,15 @@ HTMLTooltip.prototype = {
* The tooltip content, should be a HTML element.
* @param {Number} width
* Preferred width for the tooltip container
* @param {Number} height
* @param {Number} height (optional)
* Preferred height for the tooltip container. If the content height is
* smaller than the container's height, the tooltip will automatically
* shrink around the content.
* shrink around the content. If not specified, will use all the height
* available.
* @return {Promise} a promise that will resolve when the content has been
* added in the tooltip container.
*/
setContent: function (content, width, height) {
setContent: function (content, width, height = Infinity) {
let themeHeight = EXTRA_HEIGHT[this.type] + 2 * EXTRA_BORDER[this.type];
let themeWidth = 2 * EXTRA_BORDER[this.type];

View File

@ -16,7 +16,6 @@ const EventEmitter = require("devtools/shared/event-emitter");
const {colorUtils} = require("devtools/client/shared/css-color");
const Heritage = require("sdk/core/heritage");
const {Eyedropper} = require("devtools/client/eyedropper/eyedropper");
const Editor = require("devtools/client/sourceeditor/editor");
const Services = require("Services");
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
@ -434,19 +433,6 @@ Tooltip.prototype = {
}
},
/**
* Sets some event listener info as the content of this tooltip.
*
* @param {Object} (destructuring assignment)
* @0 {array} eventListenerInfos
* A list of event listeners.
* @1 {toolbox} toolbox
* Toolbox used to select debugger panel.
*/
setEventContent: function ({ eventListenerInfos, toolbox }) {
new EventTooltip(this, eventListenerInfos, toolbox);
},
/**
* Fill the tooltip with a variables view, inspecting an object via its
* corresponding object actor, as specified in the remote debugging protocol.
@ -1066,298 +1052,6 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
}
});
function EventTooltip(tooltip, eventListenerInfos, toolbox) {
this._tooltip = tooltip;
this._eventListenerInfos = eventListenerInfos;
this._toolbox = toolbox;
this._tooltip.eventEditors = new WeakMap();
this._headerClicked = this._headerClicked.bind(this);
this._debugClicked = this._debugClicked.bind(this);
this.destroy = this.destroy.bind(this);
this._init();
}
EventTooltip.prototype = {
_init: function () {
let config = {
mode: Editor.modes.js,
lineNumbers: false,
lineWrapping: false,
readOnly: true,
styleActiveLine: true,
extraKeys: {},
theme: "mozilla markup-view"
};
let doc = this._tooltip.doc;
let container = doc.createElement("vbox");
container.setAttribute("id", "devtools-tooltip-events-container");
for (let listener of this._eventListenerInfos) {
let phase = listener.capturing ? "Capturing" : "Bubbling";
let level = listener.DOM0 ? "DOM0" : "DOM2";
// Header
let header = doc.createElement("hbox");
header.className = "event-header devtools-toolbar";
container.appendChild(header);
if (!listener.hide.debugger) {
let debuggerIcon = doc.createElement("image");
debuggerIcon.className = "event-tooltip-debugger-icon";
debuggerIcon.setAttribute("src", "chrome://devtools/skin/images/tool-debugger.svg");
let openInDebugger =
l10n.strings.GetStringFromName("eventsTooltip.openInDebugger");
debuggerIcon.setAttribute("tooltiptext", openInDebugger);
header.appendChild(debuggerIcon);
}
if (!listener.hide.type) {
let eventTypeLabel = doc.createElement("label");
eventTypeLabel.className = "event-tooltip-event-type";
eventTypeLabel.setAttribute("value", listener.type);
eventTypeLabel.setAttribute("tooltiptext", listener.type);
header.appendChild(eventTypeLabel);
}
if (!listener.hide.filename) {
let filename = doc.createElement("label");
filename.className = "event-tooltip-filename devtools-monospace";
filename.setAttribute("value", listener.origin);
filename.setAttribute("tooltiptext", listener.origin);
filename.setAttribute("crop", "left");
header.appendChild(filename);
}
let attributesContainer = doc.createElement("hbox");
attributesContainer.setAttribute("class",
"event-tooltip-attributes-container");
header.appendChild(attributesContainer);
if (!listener.hide.capturing) {
let attributesBox = doc.createElement("box");
attributesBox.setAttribute("class", "event-tooltip-attributes-box");
attributesContainer.appendChild(attributesBox);
let capturing = doc.createElement("label");
capturing.className = "event-tooltip-attributes";
capturing.setAttribute("value", phase);
capturing.setAttribute("tooltiptext", phase);
attributesBox.appendChild(capturing);
}
if (listener.tags) {
for (let tag of listener.tags.split(",")) {
let attributesBox = doc.createElement("box");
attributesBox.setAttribute("class", "event-tooltip-attributes-box");
attributesContainer.appendChild(attributesBox);
let tagBox = doc.createElement("label");
tagBox.className = "event-tooltip-attributes";
tagBox.setAttribute("value", tag);
tagBox.setAttribute("tooltiptext", tag);
attributesBox.appendChild(tagBox);
}
}
if (!listener.hide.dom0) {
let attributesBox = doc.createElement("box");
attributesBox.setAttribute("class", "event-tooltip-attributes-box");
attributesContainer.appendChild(attributesBox);
let dom0 = doc.createElement("label");
dom0.className = "event-tooltip-attributes";
dom0.setAttribute("value", level);
dom0.setAttribute("tooltiptext", level);
attributesBox.appendChild(dom0);
}
// Content
let content = doc.createElement("box");
let editor = new Editor(config);
this._tooltip.eventEditors.set(content, {
editor: editor,
handler: listener.handler,
searchString: listener.searchString,
uri: listener.origin,
dom0: listener.DOM0,
appended: false
});
content.className = "event-tooltip-content-box";
container.appendChild(content);
this._addContentListeners(header);
}
this._tooltip.content = container;
this._tooltip.panel.setAttribute("clamped-dimensions-no-max-or-min-height",
"");
this._tooltip.panel.setAttribute("wide", "");
this._tooltip.panel.addEventListener("popuphiding", () => {
this.destroy(container);
}, false);
},
_addContentListeners: function (header) {
header.addEventListener("click", this._headerClicked);
},
_headerClicked: function (event) {
if (event.target.classList.contains("event-tooltip-debugger-icon")) {
this._debugClicked(event);
event.stopPropagation();
return;
}
let doc = this._tooltip.doc;
let header = event.currentTarget;
let content = header.nextElementSibling;
if (content.hasAttribute("open")) {
content.removeAttribute("open");
} else {
let contentNodes = doc.querySelectorAll(".event-tooltip-content-box");
for (let node of contentNodes) {
if (node !== content) {
node.removeAttribute("open");
}
}
content.setAttribute("open", "");
let eventEditors = this._tooltip.eventEditors.get(content);
if (eventEditors.appended) {
return;
}
let {editor, handler} = eventEditors;
let iframe = doc.createElement("iframe");
iframe.setAttribute("style", "width:100%;");
editor.appendTo(content, iframe).then(() => {
/* eslint-disable camelcase */
let tidied = beautify.js(handler, { indent_size: 2 });
/* eslint-enable */
editor.setText(tidied);
eventEditors.appended = true;
let container = header.parentElement.getBoundingClientRect();
if (header.getBoundingClientRect().top < container.top) {
header.scrollIntoView(true);
} else if (content.getBoundingClientRect().bottom > container.bottom) {
content.scrollIntoView(false);
}
this._tooltip.emit("event-tooltip-ready");
});
}
},
_debugClicked: function (event) {
let header = event.currentTarget;
let content = header.nextElementSibling;
let {uri, searchString, dom0} =
this._tooltip.eventEditors.get(content);
if (uri && uri !== "?") {
// Save a copy of toolbox as it will be set to null when we hide the
// tooltip.
let toolbox = this._toolbox;
this._tooltip.hide();
uri = uri.replace(/"/g, "");
let showSource = ({ DebuggerView }) => {
let matches = uri.match(/(.*):(\d+$)/);
let line = 1;
if (matches) {
uri = matches[1];
line = matches[2];
}
let item = DebuggerView.Sources.getItemForAttachment(
a => a.source.url === uri
);
if (item) {
let actor = item.attachment.source.actor;
DebuggerView.setEditorLocation(
actor, line, {noDebug: true}
).then(() => {
if (dom0) {
let text = DebuggerView.editor.getText();
let index = text.indexOf(searchString);
let lastIndex = text.lastIndexOf(searchString);
// To avoid confusion we only search for DOM0 event handlers when
// there is only one possible match in the file.
if (index !== -1 && index === lastIndex) {
text = text.substr(0, index);
let newlineMatches = text.match(/\n/g);
if (newlineMatches) {
DebuggerView.editor.setCursor({
line: newlineMatches.length
});
}
}
}
});
}
};
let debuggerAlreadyOpen = toolbox.getPanel("jsdebugger");
toolbox.selectTool("jsdebugger").then(({ panelWin: dbg }) => {
if (debuggerAlreadyOpen) {
showSource(dbg);
} else {
dbg.once(dbg.EVENTS.SOURCES_ADDED, () => showSource(dbg));
}
});
}
},
destroy: function (container) {
if (this._tooltip) {
this._tooltip.panel.removeEventListener("popuphiding", this.destroy,
false);
let boxes = container.querySelectorAll(".event-tooltip-content-box");
for (let box of boxes) {
let {editor} = this._tooltip.eventEditors.get(box);
editor.destroy();
}
this._tooltip.eventEditors = null;
}
let headerNodes = container.querySelectorAll(".event-header");
for (let node of headerNodes) {
node.removeEventListener("click", this._headerClicked);
}
let sourceNodes =
container.querySelectorAll(".event-tooltip-debugger-icon");
for (let node of sourceNodes) {
node.removeEventListener("click", this._debugClicked);
}
this._eventListenerInfos = this._toolbox = this._tooltip = null;
}
};
/**
* The swatch cubic-bezier tooltip class is a specific class meant to be used
* along with rule-view's generated cubic-bezier swatches.

View File

@ -0,0 +1,315 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Services = require("Services");
loader.lazyGetter(this, "GetStringFromName", () => {
let bundle = Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties");
return key => {
return bundle.GetStringFromName(key);
};
});
loader.lazyRequireGetter(this, "Editor", "devtools/client/sourceeditor/editor");
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const CONTAINER_WIDTH = 500;
/**
* Set the content of a provided HTMLTooltip instance to display a list of event
* listeners, with their event type, capturing argument and a link to the code
* of the event handler.
*
* @param {HTMLTooltip} tooltip
* The tooltip instance on which the event details content should be set
* @param {Array} eventListenerInfos
* A list of event listeners
* @param {Toolbox} toolbox
* Toolbox used to select debugger panel
*/
function setEventTooltip(tooltip, eventListenerInfos, toolbox) {
let eventTooltip = new EventTooltip(tooltip, eventListenerInfos, toolbox);
eventTooltip.init();
}
function EventTooltip(tooltip, eventListenerInfos, toolbox) {
this._tooltip = tooltip;
this._eventListenerInfos = eventListenerInfos;
this._toolbox = toolbox;
this._tooltip.eventEditors = new WeakMap();
this._headerClicked = this._headerClicked.bind(this);
this._debugClicked = this._debugClicked.bind(this);
this.destroy = this.destroy.bind(this);
}
EventTooltip.prototype = {
init: function () {
let config = {
mode: Editor.modes.js,
lineNumbers: false,
lineWrapping: true,
readOnly: true,
styleActiveLine: true,
extraKeys: {},
theme: "mozilla markup-view"
};
let doc = this._tooltip.doc;
this.container = doc.createElementNS(XHTML_NS, "div");
this.container.className = "devtools-tooltip-events-container";
for (let listener of this._eventListenerInfos) {
let phase = listener.capturing ? "Capturing" : "Bubbling";
let level = listener.DOM0 ? "DOM0" : "DOM2";
// Header
let header = doc.createElementNS(XHTML_NS, "div");
header.className = "event-header devtools-toolbar";
this.container.appendChild(header);
if (!listener.hide.debugger) {
let debuggerIcon = doc.createElementNS(XHTML_NS, "img");
debuggerIcon.className = "event-tooltip-debugger-icon";
debuggerIcon.setAttribute("src",
"chrome://devtools/skin/images/tool-debugger.svg");
let openInDebugger = GetStringFromName("eventsTooltip.openInDebugger");
debuggerIcon.setAttribute("title", openInDebugger);
header.appendChild(debuggerIcon);
}
if (!listener.hide.type) {
let eventTypeLabel = doc.createElementNS(XHTML_NS, "span");
eventTypeLabel.className = "event-tooltip-event-type";
eventTypeLabel.textContent = listener.type;
eventTypeLabel.setAttribute("title", listener.type);
header.appendChild(eventTypeLabel);
}
if (!listener.hide.filename) {
let filename = doc.createElementNS(XHTML_NS, "span");
filename.className = "event-tooltip-filename devtools-monospace";
filename.textContent = listener.origin;
filename.setAttribute("title", listener.origin);
header.appendChild(filename);
}
let attributesContainer = doc.createElementNS(XHTML_NS, "div");
attributesContainer.className = "event-tooltip-attributes-container";
header.appendChild(attributesContainer);
if (!listener.hide.capturing) {
let attributesBox = doc.createElementNS(XHTML_NS, "div");
attributesBox.className = "event-tooltip-attributes-box";
attributesContainer.appendChild(attributesBox);
let capturing = doc.createElementNS(XHTML_NS, "span");
capturing.className = "event-tooltip-attributes";
capturing.textContent = phase;
capturing.setAttribute("title", phase);
attributesBox.appendChild(capturing);
}
if (listener.tags) {
for (let tag of listener.tags.split(",")) {
let attributesBox = doc.createElementNS(XHTML_NS, "div");
attributesBox.className = "event-tooltip-attributes-box";
attributesContainer.appendChild(attributesBox);
let tagBox = doc.createElementNS(XHTML_NS, "span");
tagBox.className = "event-tooltip-attributes";
tagBox.textContent = tag;
tagBox.setAttribute("title", tag);
attributesBox.appendChild(tagBox);
}
}
if (!listener.hide.dom0) {
let attributesBox = doc.createElementNS(XHTML_NS, "div");
attributesBox.className = "event-tooltip-attributes-box";
attributesContainer.appendChild(attributesBox);
let dom0 = doc.createElementNS(XHTML_NS, "span");
dom0.className = "event-tooltip-attributes";
dom0.textContent = level;
dom0.setAttribute("title", level);
attributesBox.appendChild(dom0);
}
// Content
let content = doc.createElementNS(XHTML_NS, "div");
let editor = new Editor(config);
this._tooltip.eventEditors.set(content, {
editor: editor,
handler: listener.handler,
searchString: listener.searchString,
uri: listener.origin,
dom0: listener.DOM0,
appended: false
});
content.className = "event-tooltip-content-box";
this.container.appendChild(content);
this._addContentListeners(header);
}
this._tooltip.setContent(this.container, CONTAINER_WIDTH);
this._tooltip.on("hidden", this.destroy);
},
_addContentListeners: function (header) {
header.addEventListener("click", this._headerClicked);
},
_headerClicked: function (event) {
if (event.target.classList.contains("event-tooltip-debugger-icon")) {
this._debugClicked(event);
event.stopPropagation();
return;
}
let doc = this._tooltip.doc;
let header = event.currentTarget;
let content = header.nextElementSibling;
if (content.hasAttribute("open")) {
content.removeAttribute("open");
} else {
let contentNodes = doc.querySelectorAll(".event-tooltip-content-box");
for (let node of contentNodes) {
if (node !== content) {
node.removeAttribute("open");
}
}
content.setAttribute("open", "");
let eventEditors = this._tooltip.eventEditors.get(content);
if (eventEditors.appended) {
return;
}
let {editor, handler} = eventEditors;
let iframe = doc.createElementNS(XHTML_NS, "iframe");
iframe.setAttribute("style", "width: 100%; height: 100%; border-style: none;");
editor.appendTo(content, iframe).then(() => {
let tidied = beautify.js(handler, { "indent_size": 2 });
editor.setText(tidied);
eventEditors.appended = true;
let container = header.parentElement.getBoundingClientRect();
if (header.getBoundingClientRect().top < container.top) {
header.scrollIntoView(true);
} else if (content.getBoundingClientRect().bottom > container.bottom) {
content.scrollIntoView(false);
}
this._tooltip.emit("event-tooltip-ready");
});
}
},
_debugClicked: function (event) {
let header = event.currentTarget;
let content = header.nextElementSibling;
let {uri, searchString, dom0} = this._tooltip.eventEditors.get(content);
if (uri && uri !== "?") {
// Save a copy of toolbox as it will be set to null when we hide the tooltip.
let toolbox = this._toolbox;
this._tooltip.hide();
uri = uri.replace(/"/g, "");
let showSource = ({ DebuggerView }) => {
let matches = uri.match(/(.*):(\d+$)/);
let line = 1;
if (matches) {
uri = matches[1];
line = matches[2];
}
let item = DebuggerView.Sources.getItemForAttachment(a => a.source.url === uri);
if (item) {
let actor = item.attachment.source.actor;
DebuggerView.setEditorLocation(
actor, line, {noDebug: true}
).then(() => {
if (dom0) {
let text = DebuggerView.editor.getText();
let index = text.indexOf(searchString);
let lastIndex = text.lastIndexOf(searchString);
// To avoid confusion we only search for DOM0 event handlers when
// there is only one possible match in the file.
if (index !== -1 && index === lastIndex) {
text = text.substr(0, index);
let newlineMatches = text.match(/\n/g);
if (newlineMatches) {
DebuggerView.editor.setCursor({
line: newlineMatches.length
});
}
}
}
});
}
};
let debuggerAlreadyOpen = toolbox.getPanel("jsdebugger");
toolbox.selectTool("jsdebugger").then(({ panelWin: dbg }) => {
if (debuggerAlreadyOpen) {
showSource(dbg);
} else {
dbg.once(dbg.EVENTS.SOURCES_ADDED, () => showSource(dbg));
}
});
}
},
destroy: function () {
if (this._tooltip) {
this._tooltip.off("hidden", this.destroy);
let boxes = this.container.querySelectorAll(".event-tooltip-content-box");
for (let box of boxes) {
let {editor} = this._tooltip.eventEditors.get(box);
editor.destroy();
}
this._tooltip.eventEditors = null;
}
let headerNodes = this.container.querySelectorAll(".event-header");
for (let node of headerNodes) {
node.removeEventListener("click", this._headerClicked);
}
let sourceNodes = this.container.querySelectorAll(".event-tooltip-debugger-icon");
for (let node of sourceNodes) {
node.removeEventListener("click", this._debugClicked);
}
this._eventListenerInfos = this._toolbox = this._tooltip = null;
}
};
module.exports.setEventTooltip = setEventTooltip;

View File

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'EventTooltipHelper.js',
'ImageTooltipHelper.js',
'TooltipToggle.js',
)

View File

@ -199,8 +199,6 @@
/* Tooltip: Events */
#devtools-tooltip-events-container {
margin: -4px; /* Compensate for the .panel-arrowcontent padding. */
max-width: 590px;
overflow-y: auto;
}
@ -208,6 +206,7 @@
display: flex;
align-items: center;
cursor: pointer;
overflow: hidden;
}
.event-header:first-child {
@ -218,6 +217,11 @@
border-width: 1px 0 0 0;
}
.devtools-tooltip-events-container {
height: 100%;
overflow-y: auto;
}
.event-tooltip-event-type,
.event-tooltip-filename,
.event-tooltip-attributes {
@ -232,9 +236,14 @@
}
.event-tooltip-filename {
margin-inline-end: 0;
margin: 0 5px;
font-size: 100%;
flex-shrink: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* Force ellipsis to be displayed on the left */
direction: rtl;
}
.event-tooltip-debugger-icon {
@ -251,7 +260,7 @@
.event-tooltip-content-box {
display: none;
height: 100px;
height: 54px;
overflow: hidden;
margin-inline-end: 0;
border: 1px solid var(--theme-splitter-color);
@ -260,6 +269,7 @@
.event-toolbox-content-box iframe {
height: 100%;
border-style: none;
}
.event-tooltip-content-box[open] {
@ -288,6 +298,7 @@
display: flex;
flex-shrink: 0;
align-items: center;
height: 14px;
border-radius: 3px;
padding: 2px;
margin-inline-start: 5px;