(function() {
/**
* @typedef {Help4.control2.Control.Params} Help4.control2.recording.SelectionRect.Params
*/
/**
* Draws the selection rect around elements during hotspot assignment.
* @augments Help4.control2.Control
*/
Help4.control2.recording.SelectionRect = class extends Help4.control2.Control {
/**
* @override
* @param {Help4.control2.recording.SelectionRect.Params} [params]
*/
constructor(params) {
super(params, {
statics: {
_mbox: {init: null},
_quality: {},
_message: {},
_dnd: {init: null, destroy: true},
_rect: {init: null},
_borderWidth: {init: 0},
_borderHeight: {init: 0},
_onContainerEvent: {}
},
config: {
css: 'control-capturerect'
}
});
}
/**
* @param {Object} info
* @param {Object} selector
* @returns {Help4.control2.recording.SelectionRect}
*/
draw(info, selector) {
const {x, y, w, h} = this._rect = info.element.rect;
Help4.extendObject(this.getDom().style, {
left: x + 'px',
top: y + 'px',
width: w + 'px',
height: h + 'px'
});
// use the worst quality
let {quality} = info.selector;
while (info.iframe || info.shadow) {
info = info.iframe || info.shadow;
if (info.selector.quality > quality) quality = info.selector.quality;
}
_setQuality.call(this, quality);
_setMessage.call(this, quality, selector);
return this;
}
/**
* @override
* @param {Help4.control2.recording.SelectionRect.Params} params - same params as provided to the constructor
*/
_onAfterInit(params) {
const {container} = this;
if (container) {
/** @param {{name: string}} event */
this._onContainerEvent = ({name}) => {
name === 'visible' && _alignMessageBox.call(this);
}
container.addListener('dataChange', this._onContainerEvent);
}
}
/** @override */
_onBeforeDestroy() {
const {container, _onContainerEvent} = this;
_onContainerEvent && container?.removeListener?.('dataChange', _onContainerEvent);
}
/**
* @override
* @param {HTMLElement} dom - control DOM
*/
_onDomCreated(dom) {
const _mbox = this._mbox = this._createElement('div', {css: 'mbox'});
if (Help4.Feature.RecordingDebug) {
this._dnd = new Help4.jscore.DragDrop({object: _mbox});
}
if (this.rtl) this.addCss('rtl');
const {borderLeftWidth: blw, borderRightWidth: brw, borderBottomWidth: bbw} = getComputedStyle(dom);
this._borderWidth = parseInt(blw) + parseInt(brw);
this._borderHeight = parseInt(bbw);
}
}
/**
* @memberof Help4.control2.recording.SelectionRect#
* @param {Help4.selector.SELECTOR_QUALITY} quality
* @private
*/
function _setQuality(quality) {
if (this._quality !== quality) {
const q = Help4.selector.SELECTOR_QUALITY;
let c = '';
switch (this._quality = quality) {
case q.best: c = 'safe'; break;
case q.good: c = 'good'; break;
case q.lang: c = 'lang'; break;
default: c = 'other'; break;
}
this
.removeCss('safe good lang other')
.addCss(c);
}
}
/**
* @memberof Help4.control2.recording.SelectionRect#
* @param {Help4.selector.SELECTOR_QUALITY} quality
* @param {Object} selector
* @private
*/
function _setMessage(quality, selector) {
let message;
if (Help4.Feature.RecordingDebug) {
message = selector.rule + ': ' + selector.value;
let s = selector;
while (s && ({iframe, shadow} = s)) {
if (s = (iframe || shadow)) message += `\n<${shadow ? 'shadow':'iframe'}> ${s.rule}: ${s.value}`;
}
} else {
const q = Help4.selector.SELECTOR_QUALITY;
let c = '';
switch (quality) {
case q.best: c = 'safe'; break;
case q.good: c = 'good'; break;
case q.lang: c = 'lang'; break;
default: c = 'other'; break;
}
message = Help4.Localization.getText('capture.quality.' + c);
}
const {_mbox} = this;
if (this._message !== message) {
// set message to box
Help4.Element.setText(_mbox, this._message = message);
if (Help4.Feature.RecordingDebug) {
const newCss = [];
const css = _mbox.className.split(' ');
for (const c of css) {
if (c.indexOf('-selector-') < 0) newCss.push(c);
}
_mbox.className = newCss.join(' ');
Help4.Element.addClass(_mbox, 'selector-' + selector.rule);
}
}
_alignMessageBox.call(this);
}
/**
* @memberof Help4.control2.recording.SelectionRect#
* @private
*/
function _alignMessageBox() {
if (this.isDestroyed()) return; // XRAY-4753
// set x, y
const {_mbox} = this;
if (_mbox.offsetWidth) {
const {_rect: {w, h}} = this;
_mbox.style.top = h + this._borderHeight + 'px';
_mbox.style.left = ((w + this._borderWidth - _mbox.offsetWidth) >> 1) + 'px';
} else {
// XRAY-4720, sometimes the box needs time to render
setTimeout(() => _alignMessageBox.call(this), Help4.Queue.getTime());
}
}
})();