From efafd7fe871bc368b91db78bb132abb027141a24 Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Fri, 6 Sep 2013 15:27:06 +0200 Subject: Web UI source code annotation Part of ongoing Web UI documentation effort. Source code is annotated in a way that it can be processed by documentation generator. --- install/ui/src/freeipa/dialog.js | 306 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 303 insertions(+), 3 deletions(-) (limited to 'install/ui/src/freeipa/dialog.js') diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js index d1428fec..a31c9f45 100644 --- a/install/ui/src/freeipa/dialog.js +++ b/install/ui/src/freeipa/dialog.js @@ -22,16 +22,25 @@ define(['./ipa', './jquery', './text', './field', './widget'], function(IPA, $, text) { +/** + * Opened dialogs + * + * @class + * @singleton + */ IPA.opened_dialogs = { + /** Opened dialogs */ dialogs: [], + /** Get top dialog */ top_dialog: function() { var top = null; if (this.dialogs.length) top = this.dialogs[this.dialogs.length - 1]; return top; }, + /** Focus to dialog */ focus_top: function() { var top = this.top_dialog(); if (top) { @@ -40,30 +49,44 @@ IPA.opened_dialogs = { } }, + /** Add dialog */ add_dialog: function(dialog) { this.dialogs.push(dialog); }, + /** Remove dialog */ remove_dialog: function(dialog) { var index = this.dialogs.indexOf(dialog); if (index > -1) this.dialogs.splice(index, 1); } }; +/** + * Dialog button + * @class + */ IPA.dialog_button = function(spec) { spec = spec || {}; var that = IPA.object(); + /** @property {string} name Name */ that.name = spec.name; + /** @property {string} label Label */ that.label = text.get(spec.label || spec.name); + /** @property {Function} click Click handler */ that.click = spec.click || click; + /** @property {boolean} visible=true Button should be visible */ that.visible = spec.visible !== undefined ? spec.visible : true; function click() { } + /** + * Enabled setter + * @param {boolean} enabled + */ that.set_enabled = function(enabled) { if (enabled) { that.element.removeClass('ui-state-disabled'); @@ -72,6 +95,10 @@ IPA.dialog_button = function(spec) { } }; + /** + * Enabled getter + * @return {boolean} + */ that.is_enabled = function() { return !that.element.hasClass('ui-state-disabled'); }; @@ -81,6 +108,7 @@ IPA.dialog_button = function(spec) { /** * This is a base class for dialog boxes. + * @class */ IPA.dialog = function(spec) { @@ -88,28 +116,48 @@ IPA.dialog = function(spec) { var that = IPA.object(); + /** @property {entity.entity} entity Entity */ that.entity = IPA.get_entity(spec.entity); + /** @property {string} name="dialog" Name */ that.name = spec.name || 'dialog'; + /** @property {string} id ID */ that.id = spec.id; + /** @property {string} title Dialog title */ that.title = text.get(spec.title); + /** @property {number} width=500 Dialog width */ that.width = spec.width || 500; + /** @property {number} height Dialog height */ that.height = spec.height; + + /** + * Close dialog on Escape key press + * @property {boolean} close_on_escape=true + */ that.close_on_escape = spec.close_on_escape !== undefined ? spec.close_on_escape : true; // FIXME: remove facet reference // Purpose of facet reference is to obtain pkeys or ability to reload // facet. Such usage makes the code more spaghetti. It should be replaced. + /** + * Facet + * @property {facet.facet} + */ that.facet = spec.facet; + /** @property {IPA.widget_container} widgets Widgets */ that.widgets = IPA.widget_container(); + /** @property {IPA.field_container} fields Fields */ that.fields = IPA.field_container({ container: that }); + /** @property {ordered_map} buttons Buttons */ that.buttons = $.ordered_map(); + /** @property {details.facet_policies} policies Policies */ that.policies = IPA.facet_policies({ container: that, policies: spec.policies }); + /** Create and add button */ that.create_button = function(spec) { var factory = spec.$factory || IPA.dialog_button; var button = factory(spec); @@ -117,19 +165,32 @@ IPA.dialog = function(spec) { return button; }; + /** + * Add button + * @param {IPA.dialog_button} button + */ that.add_button = function(button) { that.buttons.put(button.name, button); }; + /** + * Get button + * @param {string} name + */ that.get_button = function(name) { return that.buttons.get(name); }; + /** + * Add field + * @param {IPA.field} field + */ that.field = function(field) { that.fields.add_field(field); return that; }; + /** Validate dialog fields */ that.validate = function() { var valid = true; var fields = that.fields.get_fields(); @@ -140,6 +201,7 @@ IPA.dialog = function(spec) { return valid; }; + /** Get ID */ that.get_id = function() { if (that.id) return that.id; if (that.name) return that.name; @@ -172,17 +234,23 @@ IPA.dialog = function(spec) { that.policies.post_create(); }; + /** + * Show message in dialog's message container + * @param {string} message + */ that.show_message = function(message) { that.message_container.text(message); that.message_container.css('display', ''); }; + /** Hide dialog message */ that.hide_message = function() { that.message_container.css('display', 'none'); }; /** * Open dialog + * @param {jQuery} container */ that.open = function(container) { @@ -217,9 +285,11 @@ IPA.dialog = function(spec) { that.focus_first_element(); }; + /** + * Set focus to the first tabbable element in the content area or the first button. + * If there are no tabbable elements, set focus on the dialog itself. + */ that.focus_first_element = function() { - // set focus to the first tabbable element in the content area or the first button - // if there are no tabbable elements, set focus on the dialog itself var element = that.container; var ui_dialog = that.container.parent('.ui-dialog'); // jq dialog div @@ -230,10 +300,20 @@ IPA.dialog = function(spec) { ui_dialog.get()))).eq(0).focus(); }; + /** + * Set jQuery dialog option + * @protected + * @param {string} name + * @param {Mixed} value + */ that.option = function(name, value) { that.container.dialog('option', name, value); }; + /** + * Set dialog buttons as jQuery dialog buttons + * @protected + */ that.set_buttons = function() { // create a map of button labels and handlers @@ -258,6 +338,10 @@ IPA.dialog = function(spec) { }); }; + /** + * Make buttons visible + * @param {string[]} names button names + */ that.display_buttons = function(names) { for (var i=0; i', { @@ -702,6 +919,13 @@ IPA.deleter_dialog = function (spec) { return that; }; +/** + * Message dialog + * + * Displays a message. + * @class + * @extends IPA.confirm_dialog + */ IPA.message_dialog = function(spec) { spec = spec || {}; @@ -710,6 +934,7 @@ IPA.message_dialog = function(spec) { var that = IPA.confirm_dialog(spec); + /** @inheritDoc */ that.open = function(container) { that.confirm_dialog_open(container); @@ -723,6 +948,19 @@ IPA.message_dialog = function(spec) { return that; }; +/** + * Confirmation dialog + * + * Presents user a proposal(message). User then decides whether he would accept or + * decline the proposal. + * + * Acceptation is done by clicking on 'OK' button or hitting 'ENTER' key, + * refusal by clicking on 'Cancel' button or hitting 'ESCAPE' key. + * + * @class + * @extends IPA.dialog + * @mixins IPA.confirm_mixin + */ IPA.confirm_dialog = function(spec) { spec = spec || {}; @@ -732,20 +970,42 @@ IPA.confirm_dialog = function(spec) { var that = IPA.dialog(spec); IPA.confirm_mixin().apply(that); + /** @property {string} message Confirmation message */ that.message = text.get(spec.message); + + /** @property {Function} on_ok OK handler */ that.on_ok = spec.on_ok; + + /** @property {Function} on_cancel Cancel handler */ that.on_cancel = spec.on_cancel; + + /** @property {Function} ok_label OK button label */ that.ok_label = text.get(spec.ok_label || '@i18n:buttons.ok'); + + /** @property {Function} cancel_label Cancel button label */ that.cancel_label = text.get(spec.cancel_label || '@i18n:buttons.cancel'); + + /** + * Dialog is confirmed + * @protected + * @property {boolean} + */ that.confirmed = false; + + /** + * Dialog can be confirmed by hitting 'ENTER' key + * @property {boolean} confirm_on_enter=true + */ that.confirm_on_enter = spec.confirm_on_enter !== undefined ? spec.confirm_on_enter : true; + /** @inheritDoc */ that.create = function() { $('

', { 'text': that.message }).appendTo(that.container); }; + /** @inheritDoc */ that.close = function() { that.dialog_close(); @@ -761,17 +1021,22 @@ IPA.confirm_dialog = function(spec) { } }; + /** @inheritDoc */ that.open = function(container) { that.confirmed = false; that.dialog_open(container); }; + /** + * Confirm handler + */ that.on_confirm = function() { that.confirmed = true; that.close(); }; + /** Create buttons */ that.create_buttons = function() { that.create_button({ @@ -801,16 +1066,40 @@ IPA.confirm_dialog = function(spec) { return that; }; +/** + * Confirm mixin + * + * Can extend a dialog by confirmation by keyboard functionality. When applied + * dialog can be: + * + * - confirmed by 'ENTER' key + * - declined by 'ESCAPE' key + * + * To apply: + * + * IPA.confirm_mixin().apply(dialog); + * + * @class + */ IPA.confirm_mixin = function() { return { mixin: { + /** + * Elements (tag names) or node types which should be ignored as + * confirmation event sources. + */ ignore_enter_rules: { src_elements: ['a', 'button'], src_types: ['textarea', 'select-one'] }, + /** + * Test if event is confirmation event + * @param {Event} event + * @return {boolean} + */ test_ignore: function(event) { var ir = this.ignore_enter_rules, @@ -822,6 +1111,9 @@ IPA.confirm_mixin = function() { return ignore; }, + /** + * Registration of keyboard event handlers + */ register_listeners: function() { var self = this; this._on_key_up_listener = function(e) { self.on_key_up(e); }; @@ -829,11 +1121,19 @@ IPA.confirm_mixin = function() { dialog_container.bind('keyup', this._on_key_up_listener); }, + /** + * Removal of registered event handlers + */ remove_listeners: function() { var dialog_container = this.container.parent('.ui-dialog'); dialog_container.unbind('keyup', this._on_key_up_listener); }, + /** + * Test if confirmation happened + * If so call dialog's `on_confirm` or `on_cancel` method. + * @param {Event} event + */ on_key_up: function(event) { if (event.keyCode === $.ui.keyCode.ENTER && !this.test_ignore(event) && -- cgit