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