(function() {
/**
* @typedef {Object} Help4.widget.help.view2.TileHotspot.ControlParams
* @property {string} animationType
* @property {Help4.control2.SizeWidthHeight} delta
* @property {string} hotspotType
* @property {string} icon
* @property {?number} number
* @property {Help4.control2.PositionXY} point
* @property {string} pos
* @property {Help4.control2.AreaXYWH} rect
* @property {string} size
* @property {boolean} spotlight
* @property {number} spotlightBlur
* @property {number} spotlightOffset
* @property {number} spotlightOpacity
* @property {?string} title
* @property {boolean} active
* @property {boolean} visible
* @property {Object} _metadata
* @property {string} _metadata.tileId
* @property {string} _metadata.hotspotId
* @property {string} _metadata.controlStyle
* @property {string} [controlType]
* @property {string} [ariaLabel]
*/
/** hotspot helper for {@link Help4.widget.help.view2.Tile} */
Help4.widget.help.view2.TileHotspot = class {
/**
* @param {Help4.widget.help.view2.Tile} tile
* @returns {boolean}
*/
static updateHotspotControl(tile) {
const {hotspotControlId, stealth, __contentView} = tile;
const removeHotspotControl = () => {
__contentView.remove(hotspotControlId);
tile.hotspotControlId = null;
}
if (stealth) {
removeHotspotControl();
return false;
}
const {view2} = Help4.widget.help;
const {__widget, projectTile, hotspotStatus} = tile;
const hasHotspot = view2.hasHotspot(__widget, projectTile);
const status = hasHotspot && hotspotStatus || {visible: false};
const params = _getHotspotParams(tile, projectTile, status);
if (params) {
// check whether controlStyle are still the same
const control = hotspotControlId && __contentView.get(hotspotControlId);
const cs1 = control?.getMetadata('controlStyle');
const cs2 = projectTile.hotspotStyle;
if (cs1 === cs2) {
// update existing hotspot control
const skip = {_metadata: 1, hotspotType: 1, controlType: 1, contentLanguage: 1};
for (const [key, value] of Object.entries(params)) {
if (!skip[key]) control[key] = value;
}
} else {
// add new hotspot control
tile.hotspotControlId = __contentView.add(params).id;
}
} else if (hotspotControlId) {
removeHotspotControl();
}
return !hasHotspot || status.visible;
}
/** @param {Help4.widget.help.view2.Tile} tile */
static selectHotspot(tile) {
const {_selected, _hovered, hotspotControlId, __contentView} = tile;
const control = __contentView.get(hotspotControlId);
if (control) control.active = _selected || _hovered;
}
/** @param {Help4.widget.help.view2.Tile} tile */
static wmHover(tile) {
const {hotspotControlId, __contentView} = tile;
const control = __contentView.get(hotspotControlId);
control?.addCss('hover');
}
/** @param {Help4.widget.help.view2.Tile} tile */
static wmLeave(tile) {
const {hotspotControlId, __contentView} = tile;
const control = __contentView.get(hotspotControlId);
control?.removeCss('hover');
}
/**
* @param {Help4.widget.help.view2.Tile} tile
* @returns {boolean}
*/
static stopHotspotAnimation(tile) {
const {hotspot} = Help4.control2;
const {Connected} = hotspot;
const {__contentView, hotspotControlId} = tile;
const control = hotspotControlId && __contentView.get(hotspotControlId);
if (control instanceof Connected) {
const {ANIMATION_TYPES: {none}} = hotspot;
const {hotspotType, animationType} = control;
if (hotspotType === 'icon' && animationType !== none) {
control.animationType = none;
return true;
}
}
return false;
}
/**
* @param {Help4.widget.help.view2.Tile} tile
* @returns {Promise<void>}
*/
static async scrollHotspotIntoView(tile) {
const {hotspotStatus, stealth} = tile;
const status = !stealth && hotspotStatus || {visible: false};
const {visible, scrolled, topmost} = status;
if (visible && (scrolled || !topmost)) {
const {Core} = Help4.widget.companionCore;
const {__widget, projectTile} = tile;
const hotspotData = Core.projectTileToHotspotData(projectTile, status);
const {/** @type {Help4.service.recording.PlaybackService} */ playbackService} = __widget.getContext().service;
await playbackService.scrollIntoView(hotspotData);
}
}
}
/**
* @private
* @param {Help4.widget.help.view2.Tile} tile
* @param {Help4.widget.help.ProjectTile} projectTile
* @param {Object} hotspotStatus
* @returns {?Help4.widget.help.view2.TileHotspot.ControlParams}
*/
function _getHotspotParams(tile, projectTile, hotspotStatus) {
const {
data: {HotspotData},
widget: {
companionCore: {Core},
help: {view2}
},
control2: {hotspot: {ANIMATION_TYPES}}
} = Help4;
const {__widget} = tile;
const {configuration} = __widget.getContext();
const hotspot = Core.projectTileToHotspotData(projectTile, hotspotStatus);
const hotspotData = new HotspotData(hotspot);
const params = /** @type {?Help4.widget.help.view2.TileHotspot.ControlParams} */ hotspotData.toControlParams(configuration);
hotspotData.destroy();
if (params) {
const {__view, descriptor, _selected, _hovered} = tile;
const {language} = projectTile;
params._metadata = {
...params._metadata,
type: 'hotspot',
descriptor
};
params.controlType = 'hotspot.Connected';
params.contentLanguage = language;
params.ariaLabel = params.title;
params.title = null; // XRAY-5028 - hotspot tooltip - hide in playback
// disable animation for controls where stopAnimation has been called for
const seenAnimations = /** @type {Help4.widget.help.TileDescriptor[]} */ __view.getSeenAnimations();
if (view2.containsTileDescriptor(seenAnimations, descriptor)) {
params.animationType = ANIMATION_TYPES.none;
}
// activate hotspots; if hovered or selected
params.active = _selected || _hovered;
}
return params;
}
})();