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
define(['jquery'], function($){
4
"use strict";
5
6
var ScrollManager = function(notebook, options) {
7
/**
8
* Public constructor.
9
*/
10
this.notebook = notebook;
11
this.element = $('#site');
12
options = options || {};
13
this.animation_speed = options.animation_speed || 250; //ms
14
};
15
16
ScrollManager.prototype.scroll = function (delta) {
17
/**
18
* Scroll the document.
19
*
20
* Parameters
21
* ----------
22
* delta: integer
23
* direction to scroll the document. Positive is downwards.
24
* Unit is one page length.
25
*/
26
this.scroll_some(delta);
27
return false;
28
};
29
30
ScrollManager.prototype.scroll_to = function(selector) {
31
/**
32
* Scroll to an element in the notebook.
33
*/
34
this.element.animate({'scrollTop': $(selector).offset().top + this.element.scrollTop() - this.element.offset().top}, this.animation_speed);
35
};
36
37
ScrollManager.prototype.scroll_some = function(pages) {
38
/**
39
* Scroll up or down a given number of pages.
40
*
41
* Parameters
42
* ----------
43
* pages: integer
44
* number of pages to scroll the document, may be positive or negative.
45
*/
46
this.element.animate({'scrollTop': this.element.scrollTop() + pages * this.element.height()}, this.animation_speed);
47
};
48
49
ScrollManager.prototype.get_first_visible_cell = function() {
50
/**
51
* Gets the index of the first visible cell in the document.
52
*
53
* First, attempt to be smart by guessing the index of the cell we are
54
* scrolled to. Then, walk from there up or down until the right cell
55
* is found. To guess the index, get the top of the last cell, and
56
* divide that by the number of cells to get an average cell height.
57
* Then divide the scroll height by the average cell height.
58
*/
59
var cell_count = this.notebook.ncells();
60
var first_cell_top = this.notebook.get_cell(0).element.offset().top;
61
var last_cell_top = this.notebook.get_cell(cell_count-1).element.offset().top;
62
var avg_cell_height = (last_cell_top - first_cell_top) / cell_count;
63
var i = Math.ceil(this.element.scrollTop() / avg_cell_height);
64
i = Math.min(Math.max(i , 0), cell_count - 1);
65
66
while (this.notebook.get_cell(i).element.offset().top - first_cell_top < this.element.scrollTop() && i < cell_count - 1) {
67
i += 1;
68
}
69
70
while (this.notebook.get_cell(i).element.offset().top - first_cell_top > this.element.scrollTop() - 50 && i >= 0) {
71
i -= 1;
72
}
73
return Math.min(i + 1, cell_count - 1);
74
};
75
76
77
var TargetScrollManager = function(notebook, options) {
78
/**
79
* Public constructor.
80
*/
81
ScrollManager.apply(this, [notebook, options]);
82
};
83
TargetScrollManager.prototype = Object.create(ScrollManager.prototype);
84
85
TargetScrollManager.prototype.is_target = function (index) {
86
/**
87
* Check if a cell should be a scroll stop.
88
*
89
* Returns `true` if the cell is a cell that the scroll manager
90
* should scroll to. Otherwise, false is returned.
91
*
92
* Parameters
93
* ----------
94
* index: integer
95
* index of the cell to test.
96
*/
97
return false;
98
};
99
100
TargetScrollManager.prototype.scroll = function (delta) {
101
/**
102
* Scroll the document.
103
*
104
* Parameters
105
* ----------
106
* delta: integer
107
* direction to scroll the document. Positive is downwards.
108
* Units are targets.
109
*
110
* Try to scroll to the next slide.
111
*/
112
var cell_count = this.notebook.ncells();
113
var selected_index = this.get_first_visible_cell() + delta;
114
while (0 <= selected_index && selected_index < cell_count && !this.is_target(selected_index)) {
115
selected_index += delta;
116
}
117
118
if (selected_index < 0 || cell_count <= selected_index) {
119
return ScrollManager.prototype.scroll.apply(this, [delta]);
120
} else {
121
this.scroll_to(this.notebook.get_cell(selected_index).element);
122
123
// Cancel browser keyboard scroll.
124
return false;
125
}
126
};
127
128
129
var SlideScrollManager = function(notebook, options) {
130
/**
131
* Public constructor.
132
*/
133
TargetScrollManager.apply(this, [notebook, options]);
134
};
135
SlideScrollManager.prototype = Object.create(TargetScrollManager.prototype);
136
137
SlideScrollManager.prototype.is_target = function (index) {
138
var cell = this.notebook.get_cell(index);
139
return cell.metadata && cell.metadata.slideshow &&
140
cell.metadata.slideshow.slide_type &&
141
(cell.metadata.slideshow.slide_type === "slide" ||
142
cell.metadata.slideshow.slide_type === "subslide");
143
};
144
145
146
var HeadingScrollManager = function(notebook, options) {
147
/**
148
* Public constructor.
149
*/
150
ScrollManager.apply(this, [notebook, options]);
151
options = options || {};
152
this._level = options.heading_level || 1;
153
};
154
HeadingScrollManager.prototype = Object.create(ScrollManager.prototype);
155
156
HeadingScrollManager.prototype.scroll = function (delta) {
157
/**
158
* Scroll the document.
159
*
160
* Parameters
161
* ----------
162
* delta: integer
163
* direction to scroll the document. Positive is downwards.
164
* Units are headers.
165
*
166
* Get all of the header elements that match the heading level or are of
167
* greater magnitude (a smaller header number).
168
*/
169
var headers = $();
170
var i;
171
for (i = 1; i <= this._level; i++) {
172
headers = headers.add('#notebook-container h' + i);
173
}
174
175
// Find the header the user is on or below.
176
var first_cell_top = this.notebook.get_cell(0).element.offset().top;
177
var current_scroll = this.element.scrollTop();
178
var header_scroll = 0;
179
i = -1;
180
while (current_scroll >= header_scroll && i < headers.length) {
181
if (++i < headers.length) {
182
header_scroll = $(headers[i]).offset().top - first_cell_top;
183
}
184
}
185
i--;
186
187
// Check if the user is below the header.
188
if (i < 0 || current_scroll > $(headers[i]).offset().top - first_cell_top + 30) {
189
// Below the header, count the header as a target.
190
if (delta < 0) {
191
delta += 1;
192
}
193
}
194
i += delta;
195
196
// Scroll!
197
if (0 <= i && i < headers.length) {
198
this.scroll_to(headers[i]);
199
return false;
200
} else {
201
// Default to the base's scroll behavior when target header doesn't
202
// exist.
203
return ScrollManager.prototype.scroll.apply(this, [delta]);
204
}
205
};
206
207
// Return naemspace for require.js loads
208
return {
209
'ScrollManager': ScrollManager,
210
'SlideScrollManager': SlideScrollManager,
211
'HeadingScrollManager': HeadingScrollManager,
212
'TargetScrollManager': TargetScrollManager
213
};
214
});
215
216