'use strict';
import $ from 'jquery';
import ColorItem from './ColorItem';
/**
* Handles everything related to the colorpicker input
* @ignore
*/
class InputHandler {
/**
* @param {Colorpicker} colorpicker
*/
constructor(colorpicker) {
/**
* @type {Colorpicker}
*/
this.colorpicker = colorpicker;
/**
* @type {jQuery|false}
*/
this.input = this.colorpicker.element.is('input') ? this.colorpicker.element : (this.colorpicker.options.input ?
this.colorpicker.element.find(this.colorpicker.options.input) : false);
if (this.input && (this.input.length === 0)) {
this.input = false;
}
this._initValue();
}
bind() {
if (!this.hasInput()) {
return;
}
this.input.on({
'keyup.colorpicker': $.proxy(this.onkeyup, this)
});
this.input.on({
'change.colorpicker': $.proxy(this.onchange, this)
});
}
unbind() {
if (!this.hasInput()) {
return;
}
this.input.off('.colorpicker');
}
_initValue() {
if (!this.hasInput()) {
return;
}
let val = '';
[
// candidates:
this.input.val(),
this.input.data('color'),
this.input.attr('data-color')
].map((item) => {
if (item && (val === '')) {
val = item;
}
});
if (val instanceof ColorItem) {
val = this.getFormattedColor(val.string(this.colorpicker.format));
} else if (!(typeof val === 'string' || val instanceof String)) {
val = '';
}
this.input.prop('value', val);
}
/**
* Returns the color string from the input value.
* If there is no input the return value is false.
*
* @returns {String|boolean}
*/
getValue() {
if (!this.hasInput()) {
return false;
}
return this.input.val();
}
/**
* If the input element is present, it updates the value with the current color object color string.
* If the value is changed, this method fires a "change" event on the input element.
*
* @param {String} val
*
* @fires Colorpicker#change
*/
setValue(val) {
if (!this.hasInput()) {
return;
}
let inputVal = this.input.prop('value');
val = val ? val : '';
if (val === (inputVal ? inputVal : '')) {
// No need to set value or trigger any event if nothing changed
return;
}
this.input.prop('value', val);
/**
* (Input) Triggered on the input element when a new color is selected.
*
* @event Colorpicker#change
*/
this.input.trigger({
type: 'change',
colorpicker: this.colorpicker,
color: this.colorpicker.color,
value: val
});
}
/**
* Returns the formatted color string, with the formatting options applied
* (e.g. useHashPrefix)
*
* @param {String|null} val
*
* @returns {String}
*/
getFormattedColor(val = null) {
val = val ? val : this.colorpicker.colorHandler.getColorString();
if (!val) {
return '';
}
val = this.colorpicker.colorHandler.resolveColorDelegate(val, false);
if (this.colorpicker.options.useHashPrefix === false) {
val = val.replace(/^#/g, '');
}
return val;
}
/**
* Returns true if the widget has an associated input element, false otherwise
* @returns {boolean}
*/
hasInput() {
return (this.input !== false);
}
/**
* Returns true if the input exists and is disabled
* @returns {boolean}
*/
isEnabled() {
return this.hasInput() && !this.isDisabled();
}
/**
* Returns true if the input exists and is disabled
* @returns {boolean}
*/
isDisabled() {
return this.hasInput() && (this.input.prop('disabled') === true);
}
/**
* Disables the input if any
*
* @fires Colorpicker#colorpickerDisable
* @returns {boolean}
*/
disable() {
if (this.hasInput()) {
this.input.prop('disabled', true);
}
}
/**
* Enables the input if any
*
* @fires Colorpicker#colorpickerEnable
* @returns {boolean}
*/
enable() {
if (this.hasInput()) {
this.input.prop('disabled', false);
}
}
/**
* Calls setValue with the current internal color value
*
* @fires Colorpicker#change
*/
update() {
if (!this.hasInput()) {
return;
}
if (
(this.colorpicker.options.autoInputFallback === false) &&
this.colorpicker.colorHandler.isInvalidColor()
) {
// prevent update if color is invalid, autoInputFallback is disabled and the last event is keyup.
return;
}
this.setValue(this.getFormattedColor());
}
/**
* Function triggered when the input has changed, so the colorpicker gets updated.
*
* @private
* @param {Event} e
* @returns {boolean}
*/
onchange(e) {
this.colorpicker.lastEvent.alias = 'input.change';
this.colorpicker.lastEvent.e = e;
let val = this.getValue();
if (val !== e.value) {
this.colorpicker.setValue(val);
}
}
/**
* Function triggered after a keyboard key has been released.
*
* @private
* @param {Event} e
* @returns {boolean}
*/
onkeyup(e) {
this.colorpicker.lastEvent.alias = 'input.keyup';
this.colorpicker.lastEvent.e = e;
let val = this.getValue();
if (val !== e.value) {
this.colorpicker.setValue(val);
}
}
}
export default InputHandler;