(function() {
/**
* @namespace button
* @memberof Help4.control2
*/
Help4.control2.button = {};
/**
* @enum {string}
*/
Help4.control2.button.APPEARANCES = {
widget: 'widget',
bubble: 'bubble',
link: 'link',
rect: 'rect',
icon: 'icon',
panel: 'panel',
rate: 'rate',
input: 'input',
tile: 'tile',
exposed: 'exposed',
checkbox: 'checkbox',
radio: 'radio',
tab: 'tab',
collapsible: 'collapsible',
toggle: 'toggle',
figure: 'figure'
}
/**
* @enum {string}
*/
Help4.control2.button.TEXT_POSITIONS = {
top: 'top',
bottom: 'bottom',
start: 'start',
end: 'end'
}
/**
* @typedef {Help4.control2.Control.Params} Help4.control2.button.Button.Params
* @property {?string} [text = null] - possible button text
* @property {?string} [icon = null] - possible button icon
* @property {?string} [image = null] - possible image on button
* @property {?string} [svg = null] - possible svg on button
* @property {Help4.control2.button.APPEARANCES} [appearance = 'link'] - button appearance
* @property {Help4.control2.button.TEXT_POSITIONS} [textPosition = 'end'] - position of text
* @property {boolean} [toggle = false] - wether the button can be toggled
* @property {?string} ariaPressed - aria-pressed attribute
*/
/**
* A control to handle a button.
* @augments Help4.control2.Control
* @property {?string} text - possible button text
* @property {?string} icon - possible button icon
* @property {?string} image - possible image on button
* @property {?string} svg - possible svg on button
* @property {Help4.control2.button.APPEARANCES} appearance - button appearance
* @property {Help4.control2.button.TEXT_POSITIONS} textPosition - position of text
* @property {boolean} toggle - button can be toggled
* @property {boolean} ariaPressed - DOM aria-pressed
*/
Help4.control2.button.Button = class extends Help4.control2.Control {
/**
* @override
* @param {Help4.control2.button.Button.Params} [params]
* @param {Help4.jscore.ControlBase.Params} [derived]
*/
constructor(params, derived) {
const {APPEARANCES, TEXT_POSITIONS} = Help4.control2.button;
params ||= {};
if (params.svg) params.appearance = params.role = params.tag = APPEARANCES.figure;
const appearance = params.appearance || derived?.params?.appearance?.init || APPEARANCES.link;
const {ControlBase} = Help4.jscore;
const T = ControlBase.TYPES;
const TT = ControlBase.TEXT_TYPES;
super(params, {
params: {
tag: {init: 'button'},
role: {init: 'button'},
text: {type: T.string_null},
icon: {type: T.string_null},
image: {type: T.string_null},
svg: {type: T.string_null},
appearance: {type: T.string, init: appearance, readonly: true},
textPosition: {type: T.string, init: TEXT_POSITIONS.end, readonly: true},
toggle: {type: T.boolean, init: false, readonly: true},
ariaPressed: {type: T.boolean, init: false, private: true},
autoEvent: {init: true}
},
config: {
css: 'control-button ' + appearance
},
texts: {
text: TT.innerText
},
derived
});
}
/**
* @override
* @param {Object} event - the received event
*/
onEvent(event) {
if (this.disabled) return;
if (event.type === 'keydown') {
// XRAY-1096: will otherwise open new tabs for buttons
if (Help4.KeyMap[event.keyCode] === 'space') {
return Help4.Event.cancel(event);
}
}
super.onEvent(event);
}
/**
* @override
* @param {Help4.jscore.ControlBase.PropertyChangeEvent} event - the change event
*/
_applyPropertyToDom({name, value, oldValue}) {
switch (name) {
case 'active':
if (this.toggle) this._applyPropertyToDom({name: 'ariaPressed', value: value, oldValue: oldValue});
super._applyPropertyToDom({name, value, oldValue});
break;
case 'text':
_setText.call(this, value);
break;
case 'icon':
_setIcon.call(this, value);
break;
case 'image':
_setImage.call(this, value, oldValue);
break;
case 'svg':
_setSVG.call(this, value, oldValue);
break;
case 'ariaPressed':
const o = {};
o[name] = value;
Help4.Element.setAttribute(this.getDom(), o);
break;
default:
super._applyPropertyToDom({name, value, oldValue});
break;
}
}
}
/**
* @memberof Help4.control2.button.Button#
* @returns {string}
* @private
*/
function _getTextPosition() {
const {TEXT_POSITIONS: TP} = Help4.control2.button;
const {textPosition: tp} = this;
return tp === TP.top || tp === TP.start ? TP.start : TP.end;
}
/**
* @memberof Help4.control2.button.Button#
* @param {string} text
* @private
*/
function _setText(text) {
const dom = this.getDom('-inner');
if (!text) return void dom?.parentNode.removeChild(dom);
if (dom) {
Help4.Element.setText(dom, text);
} else {
const {TEXT_POSITIONS: TP} = Help4.control2.button;
const pos = _getTextPosition.call(this);
const domParams = {id: '-inner', css: 'inner ' + this.textPosition, text: text};
if (pos === TP.start) domParams.moveTo = 0;
const span = this._createElement('span', domParams);
this._setTextAttribute(span, 'text');
}
}
/**
* @memberof Help4.control2.button.Button#
* @param {string} icon
* @private
*/
function _setIcon(icon) {
const dom = this.getDom('-ico');
if (!icon) return void dom?.parentNode.removeChild(dom);
icon = Help4.control2.correctIcon(icon);
icon = Help4.control2.ICONS[icon];
if (dom) {
Help4.Element.setText(dom, icon);
} else {
const {TEXT_POSITIONS: TP} = Help4.control2.button;
const textDom = this.getDom('-inner');
const domParams = {id: '-ico', css: 'icon', ariaHidden: true, role: 'presentation', text: icon};
textDom && _getTextPosition.call(this) === TP.start
? (domParams.insertAfter = textDom)
: (domParams.moveTo = 0);
this._createElement('span', domParams);
}
}
/**
* @memberof Help4.control2.button.Button#
* @param {string} image
* @param {string} oldImage
* @private
*/
function _setImage(image, oldImage) {
const dom = this.getDom('-image');
if (!image) return void dom?.parentNode.removeChild(dom);
if (dom) {
Help4.Element.removeClass(dom, oldImage);
Help4.Element.addClass(dom, image);
} else {
const {TEXT_POSITIONS: TP} = Help4.control2.button;
const iconDom = this.getDom('-ico');
const textDom = this.getDom('-inner');
const domParams = {id: '-image', css: 'image ' + image, ariaHidden: true, role: 'presentation'};
if (iconDom) {
domParams.insertAfter = iconDom;
} else if (textDom && _getTextPosition.call(this) === TP.start) {
domParams.insertAfter = textDom;
}
this._createElement('span', domParams);
}
}
/**
* @memberof Help4.control2.button.Button#
* @param {string} svg
* @param {string} oldSvg
* @private
*/
function _setSVG(svg, oldSvg) {
let dom = this.getDom('-svg');
if (!svg) return void dom?.parentNode.removeChild(dom);
const controller = Help4.getController();
const svgUrl = controller.getResourceUrl() + Help4.FILES_PATH + svg + '.svg';
if (dom) {
Help4.Element.removeClass(dom, oldSvg);
Help4.Element.addClass(dom, svg);
dom.innerHTML = null;
Help4.downloadSVG(dom, svgUrl);
} else {
const {TEXT_POSITIONS: TP} = Help4.control2.button;
const imageDom = this.getDom('-ico');
const iconDom = this.getDom('-ico');
const textDom = this.getDom('-inner');
const domParams = {id: '-svg', css: 'svg ' + svg};
if (imageDom) {
domParams.insertAfter = imageDom;
} else if (iconDom) {
domParams.insertAfter = iconDom;
} else if (textDom && _getTextPosition.call(this) === TP.start) {
domParams.insertAfter = textDom;
}
dom = this._createElement('div', domParams);
Help4.downloadSVG(dom, svgUrl);
}
}
})();