// Copyright (c) IPython Development Team. // Distributed under the terms of the Modified BSD License. define([ "widgets/js/widget", "jqueryui", "underscore", "base/js/utils", "bootstrap", ], function(widget, $, _, utils){ "use strict"; var unpack_models = function unpack_models(value, model) { /** * Replace model ids with models recursively. */ var unpacked; if ($.isArray(value)) { unpacked = []; _.each(value, function(sub_value, key) { unpacked.push(unpack_models(sub_value, model)); }); return Promise.all(unpacked); } else if (value instanceof Object) { unpacked = {}; _.each(value, function(sub_value, key) { unpacked[key] = unpack_models(sub_value, model); }); return utils.resolve_promises_dict(unpacked); } else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") { // get_model returns a promise already return model.widget_manager.get_model(value.slice(10, value.length)); } else { return Promise.resolve(value); } }; var BoxModel = widget.WidgetModel.extend({}, { serializers: _.extend({ children: {deserialize: unpack_models} }, widget.WidgetModel.serializers) }); var BoxView = widget.DOMWidgetView.extend({ initialize: function(){ /** * Public constructor */ BoxView.__super__.initialize.apply(this, arguments); this.children_views = new widget.ViewList(this.add_child_model, null, this); this.listenTo(this.model, 'change:children', function(model, value) { this.children_views.update(value); }, this); this.listenTo(this.model, 'change:overflow_x', function(model, value) { this.update_overflow_x(); }, this); this.listenTo(this.model, 'change:overflow_y', function(model, value) { this.update_overflow_y(); }, this); this.listenTo(this.model, 'change:box_style', function(model, value) { this.update_box_style(); }, this); }, update_attr: function(name, value) { /** * Set a css attr of the widget view. */ this.$box.css(name, value); }, render: function(){ /** * Called when view is rendered. */ this.$box = this.$el; this.$box.addClass('widget-box'); this.children_views.update(this.model.get('children')); this.update_overflow_x(); this.update_overflow_y(); this.update_box_style(''); }, update_overflow_x: function() { /** * Called when the x-axis overflow setting is changed. */ this.$box.css('overflow-x', this.model.get('overflow_x')); }, update_overflow_y: function() { /** * Called when the y-axis overflow setting is changed. */ this.$box.css('overflow-y', this.model.get('overflow_y')); }, update_box_style: function(previous_trait_value) { var class_map = { success: ['alert', 'alert-success'], info: ['alert', 'alert-info'], warning: ['alert', 'alert-warning'], danger: ['alert', 'alert-danger'] }; this.update_mapped_classes(class_map, 'box_style', previous_trait_value, this.$box); }, add_child_model: function(model) { /** * Called when a model is added to the children list. */ var that = this; var dummy = $('
'); that.$box.append(dummy); return this.create_child_view(model).then(function(view) { dummy.replaceWith(view.el); // Trigger the displayed event of the child view. that.after_displayed(function() { view.trigger('displayed'); }); return view; }).catch(utils.reject("Couldn't add child view to box", true)); }, remove: function() { /** * We remove this widget before removing the children as an optimization * we want to remove the entire container from the DOM first before * removing each individual child separately. */ BoxView.__super__.remove.apply(this, arguments); this.children_views.remove(); }, }); var FlexBoxView = BoxView.extend({ render: function(){ FlexBoxView.__super__.render.apply(this); this.listenTo(this.model, 'change:orientation', this.update_orientation, this); this.listenTo(this.model, 'change:flex', this._flex_changed, this); this.listenTo(this.model, 'change:pack', this._pack_changed, this); this.listenTo(this.model, 'change:align', this._align_changed, this); this._flex_changed(); this._pack_changed(); this._align_changed(); this.update_orientation(); }, update_orientation: function(){ var orientation = this.model.get("orientation"); if (orientation == "vertical") { this.$box.removeClass("hbox").addClass("vbox"); } else { this.$box.removeClass("vbox").addClass("hbox"); } }, _flex_changed: function(){ if (this.model.previous('flex')) { this.$box.removeClass('box-flex' + this.model.previous('flex')); } this.$box.addClass('box-flex' + this.model.get('flex')); }, _pack_changed: function(){ if (this.model.previous('pack')) { this.$box.removeClass(this.model.previous('pack')); } this.$box.addClass(this.model.get('pack')); }, _align_changed: function(){ if (this.model.previous('align')) { this.$box.removeClass('align-' + this.model.previous('align')); } this.$box.addClass('align-' + this.model.get('align')); }, }); return { 'unpack_models': unpack_models, 'BoxModel': BoxModel, 'BoxView': BoxView, 'FlexBoxView': FlexBoxView, }; });