##// END OF EJS Templates
Rebase cleanup
Jonathan Frederic -
Show More
@@ -1,347 +1,328 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 "widgets/js/widget",
5 "widgets/js/widget",
6 "jqueryui",
6 "jqueryui",
7 "bootstrap",
7 "bootstrap",
8 ], function(widget, $){
8 ], function(widget, $){
9
9
10 var ContainerView = widget.DOMWidgetView.extend({
10 var ContainerView = widget.DOMWidgetView.extend({
11 initialize: function(){
11 initialize: function(){
12 // Public constructor
12 // Public constructor
13 ContainerView.__super__.initialize.apply(this, arguments);
13 ContainerView.__super__.initialize.apply(this, arguments);
14 this.update_children([], this.model.get('children'));
14 this.update_children([], this.model.get('children'));
15 this.model.on('change:children', function(model, value) {
15 this.model.on('change:children', function(model, value) {
16 this.update_children(model.previous('children'), value);
16 this.update_children(model.previous('children'), value);
17 }, this);
17 }, this);
18 },
18 },
19
19
20 render: function(){
20 render: function(){
21 // Called when view is rendered.
21 // Called when view is rendered.
22 this.$el.addClass('widget-container');
22 this.$el.addClass('widget-container');
23 },
23 },
24
24
25 update_children: function(old_list, new_list) {
25 update_children: function(old_list, new_list) {
26 // Called when the children list changes.
26 // Called when the children list changes.
27 this.do_diff(old_list, new_list,
27 this.do_diff(old_list, new_list,
28 $.proxy(this.remove_child_model, this),
28 $.proxy(this.remove_child_model, this),
29 $.proxy(this.add_child_model, this));
29 $.proxy(this.add_child_model, this));
30 },
30 },
31
31
32 remove_child_model: function(model) {
32 remove_child_model: function(model) {
33 // Called when a model is removed from the children list.
33 // Called when a model is removed from the children list.
34 this.pop_child_view(model).remove();
34 this.pop_child_view(model).remove();
35 },
35 },
36
36
37 add_child_model: function(model) {
37 add_child_model: function(model) {
38 // Called when a model is added to the children list.
38 // Called when a model is added to the children list.
39 var view = this.create_child_view(model);
39 var view = this.create_child_view(model);
40 this.$el.append(view.$el);
40 this.$el.append(view.$el);
41
41
42 // Trigger the displayed event of the child view.
42 // Trigger the displayed event of the child view.
43 this.after_displayed(function() {
43 this.after_displayed(function() {
44 view.trigger('displayed');
44 view.trigger('displayed');
45 });
45 });
46 },
46 },
47 });
47 });
48
48
49
49
50 var FlexContainerView = ContainerView.extend({
50 var FlexContainerView = ContainerView.extend({
51 render: function(){
51 render: function(){
52 FlexContainerView.__super__.render.apply(this);
52 FlexContainerView.__super__.render.apply(this);
53 this.model.on('change:orientation', this.update_orientation, this);
53 this.model.on('change:orientation', this.update_orientation, this);
54 this.model.on('change:flex', this._flex_changed, this);
54 this.model.on('change:flex', this._flex_changed, this);
55 this.model.on('change:pack', this._pack_changed, this);
55 this.model.on('change:pack', this._pack_changed, this);
56 this.model.on('change:align', this._align_changed, this);
56 this.model.on('change:align', this._align_changed, this);
57 this._flex_changed();
57 this._flex_changed();
58 this._pack_changed();
58 this._pack_changed();
59 this._align_changed();
59 this._align_changed();
60 that.update_orientation();
60 that.update_orientation();
61 },
61 },
62
62
63 update_orientation: function(){
63 update_orientation: function(){
64 var orientation = this.model.get("orientation");
64 var orientation = this.model.get("orientation");
65 if (orientation == "vertical") {
65 if (orientation == "vertical") {
66 this.$el.removeClass("hbox").addClass("vbox");
66 this.$el.removeClass("hbox").addClass("vbox");
67 } else {
67 } else {
68 this.$el.removeClass("vbox").addClass("hbox");
68 this.$el.removeClass("vbox").addClass("hbox");
69 }
69 }
70 },
70 },
71
71
72 _flex_changed: function(){
72 _flex_changed: function(){
73 if (this.model.previous('flex')) {
73 if (this.model.previous('flex')) {
74 this.$el.removeClass('box-flex' + this.model.previous('flex'));
74 this.$el.removeClass('box-flex' + this.model.previous('flex'));
75 }
75 }
76 this.$el.addClass('box-flex' + this.model.get('flex'));
76 this.$el.addClass('box-flex' + this.model.get('flex'));
77 },
77 },
78
78
79 _pack_changed: function(){
79 _pack_changed: function(){
80 if (this.model.previous('pack')) {
80 if (this.model.previous('pack')) {
81 this.$el.removeClass(this.model.previous('pack'));
81 this.$el.removeClass(this.model.previous('pack'));
82 }
82 }
83 this.$el.addClass(this.model.get('pack'));
83 this.$el.addClass(this.model.get('pack'));
84 },
84 },
85
85
86 _align_changed: function(){
86 _align_changed: function(){
87 if (this.model.previous('align')) {
87 if (this.model.previous('align')) {
88 this.$el.removeClass('align-' + this.model.previous('align'));
88 this.$el.removeClass('align-' + this.model.previous('align'));
89 }
89 }
90 this.$el.addClass('align-' + this.model.get('align'));
90 this.$el.addClass('align-' + this.model.get('align'));
91 },
91 },
92 });
92 });
93
93
94
95 var VBoxContainerView = FlexContainerView.extend({
96 render: function(){
97 this.$el.addClass('vbox');
98 FlexContainerView.__super__.render.apply(this);
99 },
100 });
101
102
103 var HBoxContainerView = FlexContainerView.extend({
104 render: function(){
105 this.$el.addClass('hbox');
106 FlexContainerView.__super__.render.apply(this);
107 },
108 });
109
110
111 var PopupView = widget.DOMWidgetView.extend({
94 var PopupView = widget.DOMWidgetView.extend({
112 render: function(){
95 render: function(){
113 // Called when view is rendered.
96 // Called when view is rendered.
114 var that = this;
97 var that = this;
115
98
116 this.$el.on("remove", function(){
99 this.$el.on("remove", function(){
117 that.$backdrop.remove();
100 that.$backdrop.remove();
118 });
101 });
119 this.$backdrop = $('<div />')
102 this.$backdrop = $('<div />')
120 .appendTo($('#notebook-container'))
103 .appendTo($('#notebook-container'))
121 .addClass('modal-dialog')
104 .addClass('modal-dialog')
122 .css('position', 'absolute')
105 .css('position', 'absolute')
123 .css('left', '0px')
106 .css('left', '0px')
124 .css('top', '0px');
107 .css('top', '0px');
125 this.$window = $('<div />')
108 this.$window = $('<div />')
126 .appendTo(this.$backdrop)
109 .appendTo(this.$backdrop)
127 .addClass('modal-content widget-modal')
110 .addClass('modal-content widget-modal')
128 .mousedown(function(){
111 .mousedown(function(){
129 that.bring_to_front();
112 that.bring_to_front();
130 });
113 });
131
114
132 // Set the elements array since the this.$window element is not child
115 // Set the elements array since the this.$window element is not child
133 // of this.$el and the parent widget manager or other widgets may
116 // of this.$el and the parent widget manager or other widgets may
134 // need to know about all of the top-level widgets. The IPython
117 // need to know about all of the top-level widgets. The IPython
135 // widget manager uses this to register the elements with the
118 // widget manager uses this to register the elements with the
136 // keyboard manager.
119 // keyboard manager.
137 this.additional_elements = [this.$window];
120 this.additional_elements = [this.$window];
138
121
139 this.$title_bar = $('<div />')
122 this.$title_bar = $('<div />')
140 .addClass('popover-title')
123 .addClass('popover-title')
141 .appendTo(this.$window)
124 .appendTo(this.$window)
142 .mousedown(function(){
125 .mousedown(function(){
143 that.bring_to_front();
126 that.bring_to_front();
144 });
127 });
145 this.$close = $('<button />')
128 this.$close = $('<button />')
146 .addClass('close fa fa-remove')
129 .addClass('close fa fa-remove')
147 .css('margin-left', '5px')
130 .css('margin-left', '5px')
148 .appendTo(this.$title_bar)
131 .appendTo(this.$title_bar)
149 .click(function(){
132 .click(function(){
150 that.hide();
133 that.hide();
151 event.stopPropagation();
134 event.stopPropagation();
152 });
135 });
153 this.$minimize = $('<button />')
136 this.$minimize = $('<button />')
154 .addClass('close fa fa-arrow-down')
137 .addClass('close fa fa-arrow-down')
155 .appendTo(this.$title_bar)
138 .appendTo(this.$title_bar)
156 .click(function(){
139 .click(function(){
157 that.popped_out = !that.popped_out;
140 that.popped_out = !that.popped_out;
158 if (!that.popped_out) {
141 if (!that.popped_out) {
159 that.$minimize
142 that.$minimize
160 .removeClass('fa fa-arrow-down')
143 .removeClass('fa fa-arrow-down')
161 .addClass('fa fa-arrow-up');
144 .addClass('fa fa-arrow-up');
162
145
163 that.$window
146 that.$window
164 .draggable('destroy')
147 .draggable('destroy')
165 .resizable('destroy')
148 .resizable('destroy')
166 .removeClass('widget-modal modal-content')
149 .removeClass('widget-modal modal-content')
167 .addClass('docked-widget-modal')
150 .addClass('docked-widget-modal')
168 .detach()
151 .detach()
169 .insertBefore(that.$show_button);
152 .insertBefore(that.$show_button);
170 that.$show_button.hide();
153 that.$show_button.hide();
171 that.$close.hide();
154 that.$close.hide();
172 } else {
155 } else {
173 that.$minimize
156 that.$minimize
174 .addClass('fa fa-arrow-down')
157 .addClass('fa fa-arrow-down')
175 .removeClass('fa fa-arrow-up');
158 .removeClass('fa fa-arrow-up');
176
159
177 that.$window
160 that.$window
178 .removeClass('docked-widget-modal')
161 .removeClass('docked-widget-modal')
179 .addClass('widget-modal modal-content')
162 .addClass('widget-modal modal-content')
180 .detach()
163 .detach()
181 .appendTo(that.$backdrop)
164 .appendTo(that.$backdrop)
182 .draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'})
165 .draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'})
183 .resizable()
166 .resizable()
184 .children('.ui-resizable-handle').show();
167 .children('.ui-resizable-handle').show();
185 that.show();
168 that.show();
186 that.$show_button.show();
169 that.$show_button.show();
187 that.$close.show();
170 that.$close.show();
188 }
171 }
189 event.stopPropagation();
172 event.stopPropagation();
190 });
173 });
191 this.$title = $('<div />')
174 this.$title = $('<div />')
192 .addClass('widget-modal-title')
175 .addClass('widget-modal-title')
193 .html("&nbsp;")
176 .html("&nbsp;")
194 .appendTo(this.$title_bar);
177 .appendTo(this.$title_bar);
195 this.$body = $('<div />')
178 this.$body = $('<div />')
196 .addClass('modal-body')
179 .addClass('modal-body')
197 .addClass('widget-modal-body')
180 .addClass('widget-modal-body')
198 .addClass('widget-container')
181 .addClass('widget-container')
199 .addClass('vbox')
182 .addClass('vbox')
200 .appendTo(this.$window);
183 .appendTo(this.$window);
201
184
202 this.$show_button = $('<button />')
185 this.$show_button = $('<button />')
203 .html("&nbsp;")
186 .html("&nbsp;")
204 .addClass('btn btn-info widget-modal-show')
187 .addClass('btn btn-info widget-modal-show')
205 .appendTo(this.$el)
188 .appendTo(this.$el)
206 .click(function(){
189 .click(function(){
207 that.show();
190 that.show();
208 });
191 });
209
192
210 this.$window.draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'});
193 this.$window.draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'});
211 this.$window.resizable();
194 this.$window.resizable();
212 this.$window.on('resize', function(){
195 this.$window.on('resize', function(){
213 that.$body.outerHeight(that.$window.innerHeight() - that.$title_bar.outerHeight());
196 that.$body.outerHeight(that.$window.innerHeight() - that.$title_bar.outerHeight());
214 });
197 });
215
198
216 this._shown_once = false;
199 this._shown_once = false;
217 this.popped_out = true;
200 this.popped_out = true;
218
201
219 this.update_children([], this.model.get('children'));
202 this.update_children([], this.model.get('children'));
220 this.model.on('change:children', function(model, value) {
203 this.model.on('change:children', function(model, value) {
221 this.update_children(model.previous('children'), value);
204 this.update_children(model.previous('children'), value);
222 }, this);
205 }, this);
223 },
206 },
224
207
225 hide: function() {
208 hide: function() {
226 // Called when the modal hide button is clicked.
209 // Called when the modal hide button is clicked.
227 this.$window.hide();
210 this.$window.hide();
228 this.$show_button.removeClass('btn-info');
211 this.$show_button.removeClass('btn-info');
229 },
212 },
230
213
231 show: function() {
214 show: function() {
232 // Called when the modal show button is clicked.
215 // Called when the modal show button is clicked.
233 this.$show_button.addClass('btn-info');
216 this.$show_button.addClass('btn-info');
234 this.$window.show();
217 this.$window.show();
235 if (this.popped_out) {
218 if (this.popped_out) {
236 this.$window.css("positon", "absolute");
219 this.$window.css("positon", "absolute");
237 this.$window.css("top", "0px");
220 this.$window.css("top", "0px");
238 this.$window.css("left", Math.max(0, (($('body').outerWidth() - this.$window.outerWidth()) / 2) +
221 this.$window.css("left", Math.max(0, (($('body').outerWidth() - this.$window.outerWidth()) / 2) +
239 $(window).scrollLeft()) + "px");
222 $(window).scrollLeft()) + "px");
240 this.bring_to_front();
223 this.bring_to_front();
241 }
224 }
242 },
225 },
243
226
244 bring_to_front: function() {
227 bring_to_front: function() {
245 // Make the modal top-most, z-ordered about the other modals.
228 // Make the modal top-most, z-ordered about the other modals.
246 var $widget_modals = $(".widget-modal");
229 var $widget_modals = $(".widget-modal");
247 var max_zindex = 0;
230 var max_zindex = 0;
248 $widget_modals.each(function (index, el){
231 $widget_modals.each(function (index, el){
249 var zindex = parseInt($(el).css('z-index'));
232 var zindex = parseInt($(el).css('z-index'));
250 if (!isNaN(zindex)) {
233 if (!isNaN(zindex)) {
251 max_zindex = Math.max(max_zindex, zindex);
234 max_zindex = Math.max(max_zindex, zindex);
252 }
235 }
253 });
236 });
254
237
255 // Start z-index of widget modals at 2000
238 // Start z-index of widget modals at 2000
256 max_zindex = Math.max(max_zindex, 2000);
239 max_zindex = Math.max(max_zindex, 2000);
257
240
258 $widget_modals.each(function (index, el){
241 $widget_modals.each(function (index, el){
259 $el = $(el);
242 $el = $(el);
260 if (max_zindex == parseInt($el.css('z-index'))) {
243 if (max_zindex == parseInt($el.css('z-index'))) {
261 $el.css('z-index', max_zindex - 1);
244 $el.css('z-index', max_zindex - 1);
262 }
245 }
263 });
246 });
264 this.$window.css('z-index', max_zindex);
247 this.$window.css('z-index', max_zindex);
265 },
248 },
266
249
267 update_children: function(old_list, new_list) {
250 update_children: function(old_list, new_list) {
268 // Called when the children list is modified.
251 // Called when the children list is modified.
269 this.do_diff(old_list, new_list,
252 this.do_diff(old_list, new_list,
270 $.proxy(this.remove_child_model, this),
253 $.proxy(this.remove_child_model, this),
271 $.proxy(this.add_child_model, this));
254 $.proxy(this.add_child_model, this));
272 },
255 },
273
256
274 remove_child_model: function(model) {
257 remove_child_model: function(model) {
275 // Called when a child is removed from children list.
258 // Called when a child is removed from children list.
276 this.pop_child_view(model).remove();
259 this.pop_child_view(model).remove();
277 },
260 },
278
261
279 add_child_model: function(model) {
262 add_child_model: function(model) {
280 // Called when a child is added to children list.
263 // Called when a child is added to children list.
281 var view = this.create_child_view(model);
264 var view = this.create_child_view(model);
282 this.$body.append(view.$el);
265 this.$body.append(view.$el);
283
266
284 // Trigger the displayed event of the child view.
267 // Trigger the displayed event of the child view.
285 this.after_displayed(function() {
268 this.after_displayed(function() {
286 view.trigger('displayed');
269 view.trigger('displayed');
287 });
270 });
288 },
271 },
289
272
290 update: function(){
273 update: function(){
291 // Update the contents of this view
274 // Update the contents of this view
292 //
275 //
293 // Called when the model is changed. The model may have been
276 // Called when the model is changed. The model may have been
294 // changed by another view or by a state update from the back-end.
277 // changed by another view or by a state update from the back-end.
295 var description = this.model.get('description');
278 var description = this.model.get('description');
296 if (description.trim().length === 0) {
279 if (description.trim().length === 0) {
297 this.$title.html("&nbsp;"); // Preserve title height
280 this.$title.html("&nbsp;"); // Preserve title height
298 } else {
281 } else {
299 this.$title.text(description);
282 this.$title.text(description);
300 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$title.get(0)]);
283 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$title.get(0)]);
301 }
284 }
302
285
303 var button_text = this.model.get('button_text');
286 var button_text = this.model.get('button_text');
304 if (button_text.trim().length === 0) {
287 if (button_text.trim().length === 0) {
305 this.$show_button.html("&nbsp;"); // Preserve button height
288 this.$show_button.html("&nbsp;"); // Preserve button height
306 } else {
289 } else {
307 this.$show_button.text(button_text);
290 this.$show_button.text(button_text);
308 }
291 }
309
292
310 if (!this._shown_once) {
293 if (!this._shown_once) {
311 this._shown_once = true;
294 this._shown_once = true;
312 this.show();
295 this.show();
313 }
296 }
314
297
315 return PopupView.__super__.update.apply(this);
298 return PopupView.__super__.update.apply(this);
316 },
299 },
317
300
318 _get_selector_element: function(selector) {
301 _get_selector_element: function(selector) {
319 // Get an element view a 'special' jquery selector. (see widget.js)
302 // Get an element view a 'special' jquery selector. (see widget.js)
320 //
303 //
321 // Since the modal actually isn't within the $el in the DOM, we need to extend
304 // Since the modal actually isn't within the $el in the DOM, we need to extend
322 // the selector logic to allow the user to set css on the modal if need be.
305 // the selector logic to allow the user to set css on the modal if need be.
323 // The convention used is:
306 // The convention used is:
324 // "modal" - select the modal div
307 // "modal" - select the modal div
325 // "modal [selector]" - select element(s) within the modal div.
308 // "modal [selector]" - select element(s) within the modal div.
326 // "[selector]" - select elements within $el
309 // "[selector]" - select elements within $el
327 // "" - select the $el
310 // "" - select the $el
328 if (selector.substring(0, 5) == 'modal') {
311 if (selector.substring(0, 5) == 'modal') {
329 if (selector == 'modal') {
312 if (selector == 'modal') {
330 return this.$window;
313 return this.$window;
331 } else {
314 } else {
332 return this.$window.find(selector.substring(6));
315 return this.$window.find(selector.substring(6));
333 }
316 }
334 } else {
317 } else {
335 return PopupView.__super__._get_selector_element.apply(this, [selector]);
318 return PopupView.__super__._get_selector_element.apply(this, [selector]);
336 }
319 }
337 },
320 },
338 });
321 });
339
322
340 return {
323 return {
341 'ContainerView': ContainerView,
324 'ContainerView': ContainerView,
342 'PopupView': PopupView,
325 'PopupView': PopupView,
343 'FlexContainerView': FlexContainerView,
326 'FlexContainerView': FlexContainerView,
344 'VBoxContainerView': VBoxContainerView,
345 'HBoxContainerView': HBoxContainerView,
346 };
327 };
347 });
328 });
General Comments 0
You need to be logged in to leave comments. Login now