1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
18 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
19 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
20 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
21 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
22 | };
|
23 | var __metadata = (this && this.__metadata) || function (k, v) {
|
24 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
25 | };
|
26 | var HoverService_1;
|
27 | Object.defineProperty(exports, "__esModule", { value: true });
|
28 | exports.HoverService = exports.HoverPosition = void 0;
|
29 | const inversify_1 = require("inversify");
|
30 | const common_1 = require("../common");
|
31 | const browser_1 = require("./browser");
|
32 | const markdown_renderer_1 = require("./markdown-rendering/markdown-renderer");
|
33 | const preferences_1 = require("./preferences");
|
34 | require("../../src/browser/style/hover-service.css");
|
35 | var HoverPosition;
|
36 | (function (HoverPosition) {
|
37 | function invertIfNecessary(position, target, host, totalWidth, totalHeight) {
|
38 | if (position === 'left') {
|
39 | if (target.left - host.width - 5 < 0) {
|
40 | return 'right';
|
41 | }
|
42 | }
|
43 | else if (position === 'right') {
|
44 | if (target.right + host.width + 5 > totalWidth) {
|
45 | return 'left';
|
46 | }
|
47 | }
|
48 | else if (position === 'top') {
|
49 | if (target.top - host.height - 5 < 0) {
|
50 | return 'bottom';
|
51 | }
|
52 | }
|
53 | else if (position === 'bottom') {
|
54 | if (target.bottom + host.height + 5 > totalHeight) {
|
55 | return 'top';
|
56 | }
|
57 | }
|
58 | return position;
|
59 | }
|
60 | HoverPosition.invertIfNecessary = invertIfNecessary;
|
61 | })(HoverPosition = exports.HoverPosition || (exports.HoverPosition = {}));
|
62 | let HoverService = HoverService_1 = class HoverService {
|
63 | constructor() {
|
64 | this.lastHidHover = Date.now();
|
65 | this.disposeOnHide = new common_1.DisposableCollection();
|
66 | }
|
67 | get markdownRenderer() {
|
68 | this._markdownRenderer || (this._markdownRenderer = this.markdownRendererFactory());
|
69 | return this._markdownRenderer;
|
70 | }
|
71 | get hoverHost() {
|
72 | if (!this._hoverHost) {
|
73 | this._hoverHost = document.createElement('div');
|
74 | this._hoverHost.classList.add(HoverService_1.hostClassName);
|
75 | this._hoverHost.style.position = 'absolute';
|
76 | }
|
77 | return this._hoverHost;
|
78 | }
|
79 | requestHover(request) {
|
80 | if (request.target !== this.hoverTarget) {
|
81 | this.cancelHover();
|
82 | this.pendingTimeout = (0, common_1.disposableTimeout)(() => this.renderHover(request), this.getHoverDelay());
|
83 | }
|
84 | }
|
85 | getHoverDelay() {
|
86 | return Date.now() - this.lastHidHover < 200
|
87 | ? 0
|
88 | : this.preferences.get('workbench.hover.delay', common_1.isOSX ? 1500 : 500);
|
89 | }
|
90 | async renderHover(request) {
|
91 | const host = this.hoverHost;
|
92 | let firstChild;
|
93 | const { target, content, position, cssClasses } = request;
|
94 | if (cssClasses) {
|
95 | host.classList.add(...cssClasses);
|
96 | }
|
97 | this.hoverTarget = target;
|
98 | if (content instanceof HTMLElement) {
|
99 | host.appendChild(content);
|
100 | firstChild = content;
|
101 | }
|
102 | else if (typeof content === 'string') {
|
103 | host.textContent = content;
|
104 | }
|
105 | else {
|
106 | const renderedContent = this.markdownRenderer.render(content);
|
107 | this.disposeOnHide.push(renderedContent);
|
108 | host.appendChild(renderedContent.element);
|
109 | firstChild = renderedContent.element;
|
110 | }
|
111 |
|
112 |
|
113 | host.style.left = '0px';
|
114 | host.style.top = '0px';
|
115 | document.body.append(host);
|
116 | if (request.visualPreview) {
|
117 |
|
118 | const width = firstChild ? firstChild.offsetWidth : this.hoverHost.offsetWidth;
|
119 | const visualPreview = request.visualPreview(width);
|
120 | if (visualPreview) {
|
121 | host.appendChild(visualPreview);
|
122 | }
|
123 | }
|
124 | await (0, browser_1.animationFrame)();
|
125 | const updatedPosition = this.setHostPosition(target, host, position);
|
126 | this.disposeOnHide.push({
|
127 | dispose: () => {
|
128 | this.lastHidHover = Date.now();
|
129 | host.classList.remove(updatedPosition);
|
130 | if (cssClasses) {
|
131 | host.classList.remove(...cssClasses);
|
132 | }
|
133 | }
|
134 | });
|
135 | this.listenForMouseOut();
|
136 | }
|
137 | setHostPosition(target, host, position) {
|
138 | const targetDimensions = target.getBoundingClientRect();
|
139 | const hostDimensions = host.getBoundingClientRect();
|
140 | const documentWidth = document.body.getBoundingClientRect().width;
|
141 |
|
142 |
|
143 | const documentHeight = document.documentElement.scrollHeight;
|
144 | position = HoverPosition.invertIfNecessary(position, targetDimensions, hostDimensions, documentWidth, documentHeight);
|
145 | if (position === 'top' || position === 'bottom') {
|
146 | const targetMiddleWidth = targetDimensions.left + (targetDimensions.width / 2);
|
147 | const middleAlignment = targetMiddleWidth - (hostDimensions.width / 2);
|
148 | const furthestRight = Math.min(documentWidth - hostDimensions.width, middleAlignment);
|
149 | const left = Math.max(0, furthestRight);
|
150 | const top = position === 'top'
|
151 | ? targetDimensions.top - hostDimensions.height - 5
|
152 | : targetDimensions.bottom + 5;
|
153 | host.style.setProperty('--theia-hover-before-position', `${targetMiddleWidth - left - 5}px`);
|
154 | host.style.top = `${top}px`;
|
155 | host.style.left = `${left}px`;
|
156 | }
|
157 | else {
|
158 | const targetMiddleHeight = targetDimensions.top + (targetDimensions.height / 2);
|
159 | const middleAlignment = targetMiddleHeight - (hostDimensions.height / 2);
|
160 | const furthestTop = Math.min(documentHeight - hostDimensions.height, middleAlignment);
|
161 | const top = Math.max(0, furthestTop);
|
162 | const left = position === 'left'
|
163 | ? targetDimensions.left - hostDimensions.width - 5
|
164 | : targetDimensions.right + 5;
|
165 | host.style.setProperty('--theia-hover-before-position', `${targetMiddleHeight - top - 5}px`);
|
166 | host.style.left = `${left}px`;
|
167 | host.style.top = `${top}px`;
|
168 | }
|
169 | host.classList.add(position);
|
170 | return position;
|
171 | }
|
172 | listenForMouseOut() {
|
173 | const handleMouseMove = (e) => {
|
174 | var _a;
|
175 | if (e.target instanceof Node && !this.hoverHost.contains(e.target) && !((_a = this.hoverTarget) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
|
176 | this.cancelHover();
|
177 | }
|
178 | };
|
179 | document.addEventListener('mousemove', handleMouseMove);
|
180 | this.disposeOnHide.push({ dispose: () => document.removeEventListener('mousemove', handleMouseMove) });
|
181 | }
|
182 | cancelHover() {
|
183 | var _a;
|
184 | (_a = this.pendingTimeout) === null || _a === void 0 ? void 0 : _a.dispose();
|
185 | this.unRenderHover();
|
186 | this.disposeOnHide.dispose();
|
187 | this.hoverTarget = undefined;
|
188 | }
|
189 | unRenderHover() {
|
190 | this.hoverHost.remove();
|
191 | this.hoverHost.replaceChildren();
|
192 | }
|
193 | };
|
194 | HoverService.hostClassName = 'theia-hover';
|
195 | HoverService.styleSheetId = 'theia-hover-style';
|
196 | __decorate([
|
197 | (0, inversify_1.inject)(preferences_1.PreferenceService),
|
198 | __metadata("design:type", Object)
|
199 | ], HoverService.prototype, "preferences", void 0);
|
200 | __decorate([
|
201 | (0, inversify_1.inject)(markdown_renderer_1.MarkdownRendererFactory),
|
202 | __metadata("design:type", Function)
|
203 | ], HoverService.prototype, "markdownRendererFactory", void 0);
|
204 | HoverService = HoverService_1 = __decorate([
|
205 | (0, inversify_1.injectable)()
|
206 | ], HoverService);
|
207 | exports.HoverService = HoverService;
|
208 |
|
\ | No newline at end of file |