Source: controls/Textbox.js

/***
 * @guicreatable
 * @requirefiles {controls/Control.js,controls/Editor.js}
 */

/**
 * Creates an instance of a new Textbox control.<br />
 * <br />
 * Example:<br />
 * <img src="img/Textbox.png" /><br />
 * <br />
 * @class Textbox
 * @classdesc The Textbox class provides a GUI representation of a Textbox.
 * @augments Control
 * @mixes Editor
 * @param settings
 * @param {JQuery} settings.Parent Element within which to inject the textbox.
 * @param {Control} [settings.ForFocus=null] Control which should receive focus in place of this one.
 * @param {Control} [settings.ParentControl=null] The containing control.
 * @param {number} [settings.TabIndex=0] The tab index of the control determines which order controls may shift focus via the tab key.
 * @param {number[]} [settings.BlockedKeys=[]] Key codes which should be blocked from input.
 * @param {string} [settings.Class=""] CSS class(es) to apply to the injected textbox, space separated.
 * @param {Object} [settings.DataBinding=null] The data binding to bind the textbox value to.
 * @param {Control} [settings.KeyBlocker=settings.ParentControl] Control which should receive input events from blocked keys.
 * @param {Control} [settings.ParentControl=null] The control which contains the textbox, if applicable.
 * @param {boolean} [settings.ReadOnly=false] Sets whether or not the control is read-only.
 * @param {Object.<string, string>} [settings.Style={}] CSS style to apply to the injected textbox.
 * @param {Validator} [settings.Validator=Validator] Validator to use in conjunction with the textbox control.
 * @param {string} [settings.Value=""] Value to set in the textbox upon creation.
 * @constructor
 */
function Textbox(settings) {
    /**
     * Element within which the textbox has been injected.
     * @name Textbox#Parent
     * @type {JQuery}
     */
    this.Parent = settings.Parent;
    /**
     * The data binding to which the textbox has been bound.
     * @name Textbox#DataBinding
     * @type {Object}
     */
    this.DataBinding = null;
    if (settings.hasOwnProperty('DataBinding')) { this.DataBinding = settings.DataBinding; }
    this.Parent.append('<div class="editor' + (settings.hasOwnProperty('Class') && (settings['Class'].length > 0) ? ' ' + settings['Class'] : '') + '"></div>');
    /**
     * Root container of textbox control.
     * @name Textbox#Container
     * @type {JQuery}
     */
    this.Container = $('div', this.Parent).last();
    /**
     * Control which should receive input events from blocked keys.
     * @name Textbox#KeyBlocker
     * @type {Control}
     */
    this.KeyBlocker = (settings.hasOwnProperty('KeyBlocker') ? settings.KeyBlocker : settings.ParentControl);
    var self = this;
    /**
     * Underlying editor control for the textbox.
     * @name Textbox#Editor
     * @type {Editor}
     */
    this.Editor = new Editor(this.Container, {
        BlockedKeys: (settings.hasOwnProperty('BlockedKeys') ? settings.BlockedKeys : new Array()),
        Validator: (settings.hasOwnProperty('Validator') ? settings.Validator : Validator),
        ReadOnly: (settings.hasOwnProperty('ReadOnly') ? settings.ReadOnly : false),
        Events: {
            Changed: function (document) {

            },
            Resize: function (document) {

            },
            SelectionChanged: function (document) {
                if (EditorGlobal.ActiveEditor == document) {
                    RibbonGlobal.hidepopups();
                    var render = false;
                    if (document.Selection.Styles.length == 1) {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Styles').Layout.ByName('Style').SetValue(document.Selection.Styles[0], true) || render;
                    } else {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Styles').Layout.ByName('Style').SetValue(document.Selection.Styles, true) || render;
                    }
                    if (document.Selection.Fonts.length == 1) {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Font Name').SetValue(document.Selection.Fonts[0], true) || render;
                    } else {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Font Name').SetTitle('Font Name', true) || render;
                    }
                    if (document.Selection.Sizes.length == 1) {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Font Size').SetValue(document.Selection.Sizes[0], true) || render;
                    } else {
                        render = __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Font Size').SetTitle('Size', true) || render;
                    }
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Bold').SetCheckState(document.Selection.Bold);
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Italic').SetCheckState(document.Selection.Italic);
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Underline').SetCheckState(document.Selection.Underline);
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Strikethrough').SetCheckState(document.Selection.Strikethrough);
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Subscript').SetCheckState(document.Selection.Subscript);
                    __Ribbon.Tabs.ByName('Document').Panes.ByName('Font').Layout.ByName('Superscript').SetCheckState(document.Selection.Superscript);
                    if (render == true) { __Ribbon.Tabs.ByName('Document').Render(); }
                }
            }
        },
        data: this
    }, false);
    var self = this;
    this.Editor.onChange = function (value) {
        if (self.onChange != null) { self.onChange(value); }
    };
    this.Editor.onKeyBlock = function (event) {
        if (event.data.data.onKeyBlock != null) {
            if (event.data.data.KeyBlocker != null) {
                event.data.data.onKeyBlock.apply(event.data.data.KeyBlocker, [event]);
            }
        }
    };
    this.Editor.onResize = function () {
        if (this.Settings.data.onResize != null) {
            var tw = this.Settings.data.Container.css('width');
            var th = this.Settings.data.Container.css('height');
            var td = this.Settings.data.Container.css('display');
            this.Settings.data.Container.css('width', '');
            this.Settings.data.Container.css('height', '');
            this.Settings.data.Container.css('display', 'inline');
            var width = this.Settings.data.Container.width();
            var height = this.Settings.data.Container.height();
            this.Settings.data.Container.css('width', tw);
            this.Settings.data.Container.css('height', th);
            this.Settings.data.Container.css('display', td);
            this.Settings.data.onResize(this, width, height);
        }
    };
    /**
     * Callback responsible for handling of blocked keydown events.
     * @event Textbox#onKeyBlock
     * @param {IJQueryEventObject} event The keydown event object.
     */
    this.onKeyBlock = null;
    /**
     * Callback responsible for handling of value change events.
     * @event Textbox#onChange
     * @param {string} value The validated value of the textbox.
     */
    this.onChange = null;
    /**
     * Callback responsible for handling of value-based resize events.
     * @event Textbox#onResize
     * @param {Textbox} object The textbox triggering the event.
     * @param {number} width The width of the textbox.
     * @param {number} height The height of the textbox.
     */
    this.onResize = null;
    this.onSelection = null;
    this.CanGetFocus = true;
    this.CanTabFocus = true;
    Control.prototype.Initialize.call(this, [arguments, settings.ParentControl, [this.Container]]);
    if (settings.hasOwnProperty('Style')) {
        for (var style in settings.Style) {
            if (settings.Style.hasOwnProperty(style)) {
                this.Container.css(style, settings.Style[style]);
            }
        }
        this.Style = settings.Style;
    } else {
        this.Style = {};
    }
    /**
     * Key codes which should be blocked from input.
     * @name Textbox#BlockedKeys
     * @type number[]
     * @default []
     */
    Object.defineProperty(this, 'BlockedKeys', {
        get: function () { return (this.Editor.BlockedKeys); },
        set: function (value) { this.Editor.BlockedKeys = value; }
    });
    /**
     * Whether or not the control is read-only.
     * @name Textbox#ReadOnly
     * @type boolean
     * @default false
     */
    Object.defineProperty(this, 'ReadOnly', {
        get: function () { return (this.Editor.ReadOnly); },
        set: function (value) { this.Editor.ReadOnly = value; }
    });
    /**
     * Get or set Textbox value.
     * @name Textbox#Value
     * @type String
     * @default ""
     */
    Object.defineProperty(this, 'Value', {
        get: Textbox_Value_get,
        set: Textbox_Value_set
    });
    if (settings.hasOwnProperty('Value')) { this.Value = settings.Value; }
}

/**
 * Causes the textbox to receive input focus.
 * @function
 * @name Textbox#Activate
 */
function Textbox_Activate() {
    this.Container.focus();
}

/**
 * Causes the textbox to lose input focus.
 * @function
 * @name Textbox#Deactivate
 */
function Textbox_Deactivate() {
    this.Container.blur();
}

/**
 * Disposes of the textbox instance and frees up allocated resources.
 * @function
 * @name Textbox#Dispose
 */
function Textbox_Dispose() {
    Control.prototype.Dispose.call(this);
}

/**
 * Handles the keydown event for the textbox.
 * @function
 * @name Textbox#Keydown
 */
function Textbox_Keydown(event) {
    if (this.BlockedKeys.indexOf(event.which) >= 0) {
        if (window.ControlGlobal.Controls[window.ControlGlobal.Controls.length - 1] == this) {
            if (this.onKeyBlock != null) {
                if (this.KeyBlocker != null) {
                    this.onKeyBlock.apply(this.KeyBlocker, [event]);
                }
            }
            return (false);
        }
    }
    event.stopPropagation();
}

/**
 * Handles the keypress event for the textbox.
 * @function
 * @name Textbox#Keypress
 */
function Textbox_Keypress(event) {
    event.stopPropagation();
}

/**
 * Handles the keyup event for the textbox.
 * @function
 * @name Textbox#Keyup
 */
function Textbox_Keyup(event) {
    event.stopPropagation();
}

/**
 * Handles the mousedown event for the textbox.
 * @function
 * @name Textbox#Mousedown
 */
function Textbox_Mousedown(event) {
    event.stopPropagation();
}

/**
 * Handles the mouseup event for the textbox.
 * @function
 * @name Textbox#Mouseup
 */
function Textbox_Mouseup(event) {
    event.stopPropagation();
}

/**
 * Textbox value getter.
 * @function
 * @name Textbox#Value_get
 */
function Textbox_Value_get() {
    return (this.Editor.LastValidValue);
}

/**
 * Textbox value setter.
 * @function
 * @name Textbox#Value_set
 */
function Textbox_Value_set(value) {
    this.Editor.LastValidValue = this.Editor.Validator.Force(value);
    this.Container.html(this.Editor.LastValidValue);
    if (this.Editor.onResize != null) { this.Editor.onResize(); }
}
// noinspection JSClosureCompilerSyntax
Textbox.prototype = new Control();
Textbox.prototype.constructor = Textbox;
Textbox.prototype.Activate = Textbox_Activate;
Textbox.prototype.Deactivate = Textbox_Deactivate;
Textbox.prototype.Dispose = Textbox_Dispose;
Textbox.prototype.Keydown = Textbox_Keydown;
Textbox.prototype.Keypress = Textbox_Keypress;
Textbox.prototype.Keyup = Textbox_Keyup;
Textbox.prototype.Mousedown = Textbox_Mousedown;
Textbox.prototype.Mouseup = Textbox_Mouseup;
Textbox.prototype.Value_get = Textbox_Value_get;
Textbox.prototype.Value_set = Textbox_Value_set;