Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50654 views
1
// Copyright (c) IPython Development Team.
2
// Distributed under the terms of the Modified BSD License.
3
4
define([
5
'base/js/namespace',
6
'jquery',
7
'base/js/utils',
8
], function(IPython, $, utils) {
9
"use strict";
10
11
// tooltip constructor
12
var Tooltip = function (events) {
13
var that = this;
14
this.events = events;
15
this.time_before_tooltip = 1200;
16
17
// handle to html
18
this.tooltip = $('#tooltip');
19
this._hidden = true;
20
21
// variable for consecutive call
22
this._old_cell = null;
23
this._old_request = null;
24
this._consecutive_counter = 0;
25
26
// 'sticky ?'
27
this._sticky = false;
28
29
// display tooltip if the docstring is empty?
30
this._hide_if_no_docstring = false;
31
32
// contain the button in the upper right corner
33
this.buttons = $('<div/>').addClass('tooltipbuttons');
34
35
// will contain the docstring
36
this.text = $('<div/>').addClass('tooltiptext').addClass('smalltooltip');
37
38
// build the buttons menu on the upper right
39
// expand the tooltip to see more
40
var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner
41
.attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press shift-tab twice)').click(function () {
42
that.expand();
43
event.preventDefault();
44
}).append(
45
$('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus'));
46
47
// open in pager
48
var morelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button').attr('title', 'show the current docstring in pager (press shift-tab 4 times)');
49
var morespan = $('<span/>').text('Open in Pager').addClass('ui-icon').addClass('ui-icon-arrowstop-l-n');
50
morelink.append(morespan);
51
morelink.click(function () {
52
that.showInPager(that._old_cell);
53
event.preventDefault();
54
});
55
56
// close the tooltip
57
var closelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button');
58
var closespan = $('<span/>').text('Close').addClass('ui-icon').addClass('ui-icon-close');
59
closelink.append(closespan);
60
closelink.click(function () {
61
that.remove_and_cancel_tooltip(true);
62
event.preventDefault();
63
});
64
65
this._clocklink = $('<a/>').attr('href', "#");
66
this._clocklink.attr('role', "button");
67
this._clocklink.addClass('ui-button');
68
this._clocklink.attr('title', 'Tooltip will linger for 10 seconds while you type');
69
var clockspan = $('<span/>').text('Close');
70
clockspan.addClass('ui-icon');
71
clockspan.addClass('ui-icon-clock');
72
this._clocklink.append(clockspan);
73
this._clocklink.click(function () {
74
that.cancel_stick();
75
event.preventDefault();
76
});
77
78
79
80
81
//construct the tooltip
82
// add in the reverse order you want them to appear
83
this.buttons.append(closelink);
84
this.buttons.append(expandlink);
85
this.buttons.append(morelink);
86
this.buttons.append(this._clocklink);
87
this._clocklink.hide();
88
89
90
// we need a phony element to make the small arrow
91
// of the tooltip in css
92
// we will move the arrow later
93
this.arrow = $('<div/>').addClass('pretooltiparrow');
94
this.tooltip.append(this.buttons);
95
this.tooltip.append(this.arrow);
96
this.tooltip.append(this.text);
97
98
// function that will be called if you press tab 1, 2, 3... times in a row
99
this.tabs_functions = [function (cell, text, cursor) {
100
that._request_tooltip(cell, text, cursor);
101
}, function () {
102
that.expand();
103
}, function () {
104
that.stick();
105
}, function (cell) {
106
that.cancel_stick();
107
that.showInPager(cell);
108
}];
109
// call after all the tabs function above have bee call to clean their effects
110
// if necessary
111
this.reset_tabs_function = function (cell, text) {
112
this._old_cell = (cell) ? cell : null;
113
this._old_request = (text) ? text : null;
114
this._consecutive_counter = 0;
115
};
116
};
117
118
Tooltip.prototype.is_visible = function () {
119
return !this._hidden;
120
};
121
122
Tooltip.prototype.showInPager = function (cell) {
123
/**
124
* reexecute last call in pager by appending ? to show back in pager
125
*/
126
this.events.trigger('open_with_text.Pager', this._reply.content);
127
this.remove_and_cancel_tooltip();
128
};
129
130
// grow the tooltip verticaly
131
Tooltip.prototype.expand = function () {
132
this.text.removeClass('smalltooltip');
133
this.text.addClass('bigtooltip');
134
$('#expanbutton').hide('slow');
135
};
136
137
// deal with all the logic of hiding the tooltip
138
// and reset it's status
139
Tooltip.prototype._hide = function () {
140
this._hidden = true;
141
this.tooltip.fadeOut('fast');
142
$('#expanbutton').show('slow');
143
this.text.removeClass('bigtooltip');
144
this.text.addClass('smalltooltip');
145
// keep scroll top to be sure to always see the first line
146
this.text.scrollTop(0);
147
this.code_mirror = null;
148
};
149
150
// return true on successfully removing a visible tooltip; otherwise return
151
// false.
152
Tooltip.prototype.remove_and_cancel_tooltip = function (force) {
153
/**
154
* note that we don't handle closing directly inside the calltip
155
* as in the completer, because it is not focusable, so won't
156
* get the event.
157
*/
158
this.cancel_pending();
159
if (!this._hidden) {
160
if (force || !this._sticky) {
161
this.cancel_stick();
162
this._hide();
163
}
164
this.reset_tabs_function();
165
return true;
166
} else {
167
return false;
168
}
169
};
170
171
// cancel autocall done after '(' for example.
172
Tooltip.prototype.cancel_pending = function () {
173
if (this._tooltip_timeout !== null) {
174
clearTimeout(this._tooltip_timeout);
175
this._tooltip_timeout = null;
176
}
177
};
178
179
// will trigger tooltip after timeout
180
Tooltip.prototype.pending = function (cell, hide_if_no_docstring) {
181
var that = this;
182
this._tooltip_timeout = setTimeout(function () {
183
that.request(cell, hide_if_no_docstring);
184
}, that.time_before_tooltip);
185
};
186
187
// easy access for julia monkey patching.
188
Tooltip.last_token_re = /[a-z_][0-9a-z._]*$/gi;
189
190
Tooltip.prototype._request_tooltip = function (cell, text, cursor_pos) {
191
var callbacks = $.proxy(this._show, this);
192
var msg_id = cell.kernel.inspect(text, cursor_pos, callbacks);
193
};
194
195
// make an immediate completion request
196
Tooltip.prototype.request = function (cell, hide_if_no_docstring) {
197
/**
198
* request(codecell)
199
* Deal with extracting the text from the cell and counting
200
* call in a row
201
*/
202
this.cancel_pending();
203
var editor = cell.code_mirror;
204
var cursor = editor.getCursor();
205
var cursor_pos = utils.to_absolute_cursor_pos(editor, cursor);
206
var text = cell.get_text();
207
208
this._hide_if_no_docstring = hide_if_no_docstring;
209
210
if(editor.somethingSelected()){
211
// get only the most recent selection.
212
text = editor.getSelection();
213
}
214
215
// need a permanent handle to code_mirror for future auto recall
216
this.code_mirror = editor;
217
218
// now we treat the different number of keypress
219
// first if same cell, same text, increment counter by 1
220
if (this._old_cell == cell && this._old_request == text && this._hidden === false) {
221
this._consecutive_counter++;
222
} else {
223
// else reset
224
this.cancel_stick();
225
this.reset_tabs_function (cell, text);
226
}
227
228
this.tabs_functions[this._consecutive_counter](cell, text, cursor_pos);
229
230
// then if we are at the end of list function, reset
231
if (this._consecutive_counter == this.tabs_functions.length) {
232
this.reset_tabs_function (cell, text, cursor);
233
}
234
235
return;
236
};
237
238
// cancel the option of having the tooltip to stick
239
Tooltip.prototype.cancel_stick = function () {
240
clearTimeout(this._stick_timeout);
241
this._stick_timeout = null;
242
this._clocklink.hide('slow');
243
this._sticky = false;
244
};
245
246
// put the tooltip in a sicky state for 10 seconds
247
// it won't be removed by remove_and_cancell() unless you called with
248
// the first parameter set to true.
249
// remove_and_cancell_tooltip(true)
250
Tooltip.prototype.stick = function (time) {
251
time = (time !== undefined) ? time : 10;
252
var that = this;
253
this._sticky = true;
254
this._clocklink.show('slow');
255
this._stick_timeout = setTimeout(function () {
256
that._sticky = false;
257
that._clocklink.hide('slow');
258
}, time * 1000);
259
};
260
261
// should be called with the kernel reply to actually show the tooltip
262
Tooltip.prototype._show = function (reply) {
263
/**
264
* move the bubble if it is not hidden
265
* otherwise fade it
266
*/
267
this._reply = reply;
268
var content = reply.content;
269
if (!content.found) {
270
// object not found, nothing to show
271
return;
272
}
273
this.name = content.name;
274
275
// do some math to have the tooltip arrow on more or less on left or right
276
// position of the editor
277
var cm_pos = $(this.code_mirror.getWrapperElement()).position();
278
279
// anchor and head positions are local within CodeMirror element
280
var anchor = this.code_mirror.cursorCoords(false, 'local');
281
var head = this.code_mirror.cursorCoords(true, 'local');
282
// locate the target at the center of anchor, head
283
var center_left = (head.left + anchor.left) / 2;
284
// locate the left edge of the tooltip, at most 450 px left of the arrow
285
var edge_left = Math.max(center_left - 450, 0);
286
// locate the arrow at the cursor. A 24 px offset seems necessary.
287
var arrow_left = center_left - edge_left - 24;
288
289
// locate left, top within container element
290
var left = (cm_pos.left + edge_left) + 'px';
291
var top = (cm_pos.top + head.bottom + 10) + 'px';
292
293
if (this._hidden === false) {
294
this.tooltip.animate({
295
left: left,
296
top: top
297
});
298
} else {
299
this.tooltip.css({
300
left: left
301
});
302
this.tooltip.css({
303
top: top
304
});
305
}
306
this.arrow.animate({
307
'left': arrow_left + 'px'
308
});
309
310
this._hidden = false;
311
this.tooltip.fadeIn('fast');
312
this.text.children().remove();
313
314
// This should support rich data types, but only text/plain for now
315
// Any HTML within the docstring is escaped by the fixConsole() method.
316
var pre = $('<pre/>').html(utils.fixConsole(content.data['text/plain']));
317
this.text.append(pre);
318
// keep scroll top to be sure to always see the first line
319
this.text.scrollTop(0);
320
};
321
322
// Backwards compatibility.
323
IPython.Tooltip = Tooltip;
324
325
return {'Tooltip': Tooltip};
326
});
327
328