summaryrefslogtreecommitdiffstats
path: root/install/ui/src/freeipa/facets/Facet.js
diff options
context:
space:
mode:
Diffstat (limited to 'install/ui/src/freeipa/facets/Facet.js')
-rw-r--r--install/ui/src/freeipa/facets/Facet.js329
1 files changed, 329 insertions, 0 deletions
diff --git a/install/ui/src/freeipa/facets/Facet.js b/install/ui/src/freeipa/facets/Facet.js
new file mode 100644
index 000000000..8b55cec12
--- /dev/null
+++ b/install/ui/src/freeipa/facets/Facet.js
@@ -0,0 +1,329 @@
+/* Authors:
+ * Petr Vobornik <pvoborni@redhat.com>
+ *
+ * Copyright (C) 2013 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+define(['dojo/_base/declare',
+ 'dojo/_base/lang',
+ 'dojo/Evented',
+ 'dojo/dom-construct',
+ 'dojo/dom-class',
+ 'dojo/on',
+ '../builder',
+ '../facet',
+ '../ipa', // for util functions
+ '../jquery',
+ '../text',
+ '../widgets/ContainerMixin'
+ ],
+ function(declare, lang, Evented, construct, dom_class,
+ on, builder, mod_facet, IPA, $, text, ContainerMixin) {
+
+ /**
+ * Base class of Facet
+ *
+ * A future replacement/base class for `facet.facet`
+ *
+ * @class facets.Facet
+ * @mixins widgets.ContainerMixin
+ */
+ var Facet = declare([Evented, ContainerMixin], {
+
+ /**
+ * Name of preferred facet container
+ *
+ * Leave unset to use default container.
+ * @property {string}
+ */
+ preferred_container: null,
+
+ /**
+ * Facet name
+ * @property {string}
+ */
+ name: null,
+
+ /**
+ * Facet label
+ * @property {string}
+ */
+ label: null,
+
+ /**
+ * Facet title
+ * @property {string}
+ */
+ title: null,
+
+ /**
+ * Facet element's CSS class
+ * @property {string}
+ */
+ 'class': null,
+
+ /**
+ * Class which tells that the facet should be visible
+ * @property {string}
+ */
+ active_class: 'active',
+
+ /**
+ * dom_node of container
+ * Suppose to contain dom_node of this and other facets.
+ * @property {jQuery}
+ */
+ container_node: null,
+
+ /**
+ * dom_node which contains all content of this Facet.
+ * @property {HTMLElement}
+ * @readonly
+ */
+ dom_node: null,
+
+ /**
+ * DOM node which serves as container for child widgets
+ * @property {HTMLElement}
+ */
+ children_node: null,
+
+ /**
+ * Redirection target information.
+ *
+ * Can be facet and/or entity name.
+ * @property {Object}
+ * @param {string} entity entity name
+ * @param {string} facet facet name
+ */
+ redirect_info: null,
+
+ /**
+ * Public state
+ * @property {facet.FacetState}
+ * @protected
+ */
+ state: null,
+
+ /**
+ * Checks if two objects has the same properties with equal values.
+ *
+ * @param {Object} a
+ * @param {Object} b
+ * @return {boolean} `a` and `b` are value-equal
+ * @protected
+ */
+ state_diff: function(a, b) {
+ var diff = false;
+ var checked = {};
+
+ var check_diff = function(a, b, skip) {
+
+ var same = true;
+ skip = skip || {};
+
+ for (var key in a) {
+ if (a.hasOwnProperty(key) && !(key in skip)) {
+ var va = a[key];
+ var vb = b[key];
+ if (lang.isArray(va)) {
+ if (IPA.array_diff(va,vb)) {
+ same = false;
+ skip[a] = true;
+ break;
+ }
+ } else {
+ if (va != vb) {
+ same = false;
+ skip[a] = true;
+ break;
+ }
+ }
+ }
+ }
+ return !same;
+ };
+
+ diff = check_diff(a,b, checked);
+ diff = diff || check_diff(b,a, checked);
+ return diff;
+ },
+
+ /**
+ * Reset facet state to supplied
+ *
+ * @param {Object} state state to set
+ */
+ reset_state: function(state) {
+ this.state.reset(state);
+ },
+
+ /**
+ * Get copy of current state
+ *
+ * @return {Object} state
+ */
+ get_state: function() {
+ return this.state.clone();
+ },
+
+ /**
+ * Merges state into current and notifies it.
+ *
+ * @param {Object} state object to merge into current state
+ */
+ set_state: function(state) {
+ this.state.set(state);
+ },
+
+ /**
+ * Handle state set
+ * @param {Object} old_state
+ * @param {Object} state
+ * @protected
+ */
+ on_state_set: function(old_state, state) {
+ this.on_state_change(state);
+ },
+
+ /**
+ * Handle state change
+ * @param {Object} state
+ * @protected
+ */
+ on_state_change: function(state) {
+
+ this._notify_state_change(state);
+ },
+
+ /**
+ * Fires `facet-state-change` event with given state as event parameter.
+ *
+ * @fires facet-state-change
+ * @protected
+ * @param {Object} state
+ */
+ _notify_state_change: function(state) {
+ this.emit('facet-state-change', {
+ facet: this,
+ state: state
+ });
+ },
+
+ /**
+ * Create facet's HTML representation
+ * NOTE: may be renamed to render
+ */
+ create: function() {
+
+ if (this.dom_node) {
+ construct.empty(this.dom_node);
+ } else {
+ this.dom_node = construct.create('div', {
+ 'class': 'facet',
+ name: this.name,
+ 'data-name': this.name
+ });
+ }
+ if (this.container_node) {
+ construct.place(this.dom_node, this.container_node);
+ }
+ this.children_node = this.dom_node;
+ return this.dom_node;
+ },
+
+ /**
+ * Render child widgets
+ */
+ render_children: function() {
+ var widgets = this.get_widgets();
+
+ for (var i=0;i<widgets.length; i++) {
+ var widget = widgets[i];
+ var modern = typeof widget.render === 'function';
+
+ if (modern) {
+ widget.container_node = this.children_node;
+ widget.render();
+ } else {
+ var container = $('<div/>').appendTo(this.children_node);
+ widget.create(container);
+ }
+ }
+ },
+
+ /**
+ * Show facet
+ *
+ * - mark itself as active facet
+ */
+ show: function() {
+
+ if (!this.dom_node) {
+ this.create();
+ this.render_children();
+ }
+
+ dom_class.add(this.dom_node, 'active-facet');
+ this.emit('show', { source: this });
+ },
+
+ /**
+ * Un-mark itself as active facet
+ */
+ hide: function() {
+ dom_class.remove(this.dom_node, 'active-facet');
+ this.emit('hide', { source: this });
+ },
+
+ /**
+ * Initializes facet
+ *
+ * Facet builder should run this method after instantiation.
+ * @param {Object} spec
+ */
+ init: function(spec) {
+
+ this.add_widgets(spec.widgets || []);
+ },
+
+ can_leave: function() {
+ return true;
+ },
+
+ show_leave_dialog: function(callback) {
+ window.console.warning('Unimplemented');
+ },
+
+ /** Constructor */
+ constructor: function(spec) {
+
+ this.preferred_container = spec.preferred_container;
+ this.name = spec.name;
+ this.label = text.get(spec.label);
+ this.title = text.get(spec.title || spec.label);
+ this['class'] = spec['class'];
+ this.container_node = spec.container_node;
+ this.dom_node = spec.dom_node;
+ this.redirect_info = spec.redirect_info;
+ this.state = new mod_facet.FacetState();
+ on(this.state, 'set', lang.hitch(this, this.on_state_set));
+ }
+ });
+
+ return Facet;
+}); \ No newline at end of file