/**
* @license
* Copyright The Closure Library Authors.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Component for an input field with bidi direction automatic
* detection. The input element directionality is automatically set according
* to the contents (value) of the element.
*
* @see ../demos/bidiinput.html
*/
goog.provide('goog.ui.BidiInput');
goog.require('goog.dom');
goog.require('goog.dom.InputType');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.InputHandler');
goog.require('goog.i18n.bidi');
goog.require('goog.ui.Component');
/**
* Default implementation of BidiInput.
*
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* @constructor
* @extends {goog.ui.Component}
*/
goog.ui.BidiInput = function(opt_domHelper) {
'use strict';
goog.ui.Component.call(this, opt_domHelper);
};
goog.inherits(goog.ui.BidiInput, goog.ui.Component);
/**
* The input handler that provides the input event.
* @type {goog.events.InputHandler?}
* @private
*/
goog.ui.BidiInput.prototype.inputHandler_ = null;
/**
* Decorates the given HTML element as a BidiInput. The HTML element can be an
* input element with type='text', a textarea element, or any contenteditable.
* Overrides {@link goog.ui.Component#decorateInternal}. Considered protected.
* @param {Element} element Element to decorate.
* @protected
* @override
*/
goog.ui.BidiInput.prototype.decorateInternal = function(element) {
'use strict';
goog.ui.BidiInput.superClass_.decorateInternal.call(this, element);
this.init_();
};
/**
* @return {?HTMLInputElement}
* @override
*/
goog.ui.BidiInput.prototype.getElement = function() {
return /** @type {?HTMLInputElement} */ (
goog.ui.BidiInput.superClass_.getElement.call(this));
};
/**
* Creates the element for the text input.
* @protected
* @override
*/
goog.ui.BidiInput.prototype.createDom = function() {
'use strict';
this.setElementInternal(this.getDomHelper().createDom(
goog.dom.TagName.INPUT, {'type': goog.dom.InputType.TEXT}));
this.init_();
};
/**
* Initializes the events and initial text direction.
* Called from either decorate or createDom, after the input field has
* been created.
* @private
*/
goog.ui.BidiInput.prototype.init_ = function() {
'use strict';
// Set initial direction by current text
this.setDirection_();
// Listen to value change events
this.inputHandler_ = new goog.events.InputHandler(this.getElement());
goog.events.listen(
this.inputHandler_, goog.events.InputHandler.EventType.INPUT,
this.setDirection_, false, this);
};
/**
* Set the direction of the input element based on the current value. If the
* value does not have any strongly directional characters, remove the dir
* attribute so that the direction is inherited instead.
* This method is called when the user changes the input element value, or
* when a program changes the value using
* {@link goog.ui.BidiInput#setValue}
* @private
*/
goog.ui.BidiInput.prototype.setDirection_ = function() {
'use strict';
var element = this.getElement();
if (element) {
var text = this.getValue();
goog.i18n.bidi.setElementDirByTextDirectionality(element, text);
}
};
/**
* Returns the direction of the input element.
* @return {?string} Return 'rtl' for right-to-left text,
* 'ltr' for left-to-right text, or null if the value itself is not
* enough to determine directionality (e.g. an empty value), and the
* direction is inherited from a parent element (typically the body
* element).
* @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
*/
goog.ui.BidiInput.prototype.getDirection = function() {
'use strict';
var dir = this.getElement().dir;
if (dir == '') {
dir = null;
}
return dir;
};
/**
* Sets the value of the underlying input field, and sets the direction
* according to the given value.
* @param {string} value The Value to set in the underlying input field.
* @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
*/
goog.ui.BidiInput.prototype.setValue = function(value) {
'use strict';
var element = this.getElement();
if (element.value != null) {
element.value = value;
} else {
goog.dom.setTextContent(element, value);
}
this.setDirection_();
};
/**
* Returns the value of the underlying input field.
* @return {string} Value of the underlying input field.
* @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
*/
goog.ui.BidiInput.prototype.getValue = function() {
'use strict';
var element = this.getElement();
return element.value != null ? element.value :
goog.dom.getRawTextContent(element);
};
/** @override */
goog.ui.BidiInput.prototype.disposeInternal = function() {
'use strict';
if (this.inputHandler_) {
goog.events.removeAll(this.inputHandler_);
this.inputHandler_.dispose();
this.inputHandler_ = null;
}
goog.ui.BidiInput.base(this, 'disposeInternal');
};