(function() {
/**
* @typedef {Object} Help4.widget.help.view2.View.Params
* @property {Help4.widget.help.Widget} widget
* @property {boolean} stealth
*/
/**
* @typedef {Object} Help4.widget.help.view2.View.Cache
* @property {string} [screenId]
* @property {Help4.widget.help.CatalogueKeys} [catalogueKey]
* @property {string[]} [helpIds]
* @property {Help4.widget.help.ProjectTile[]} [tiles]
* @property {Help4.widget.help.ProjectTile[]} [conditionTiles]
* @property {boolean} [isDataUpdate]
* @property {Object} [persist] - information that needs to persist and be (de)serialized
* @property {Object} [persist.animation] - already seen animations; see {@link Help4.widget.help.TileDescriptor}
* @property {Object} [persist.callout] - already shown callouts; see {@link Help4.widget.help.TileDescriptor}
* @property {Object} [persist.announcement_always] - already shown announcements; see {@link Help4.widget.help.TileDescriptor}
* @property {Object} [persist.announcement_once] - already shown announcements; see {@link Help4.widget.help.TileDescriptor}
* @property {string} [select]
* @property {boolean} [stealth]
*/
/**
* @typedef {'activate'|'deactivate'|'playbackActive'|'controllerOpen'|'controllerClose'|'widgetDeactivate'|'navigate'|'redraw'} Help4.widget.help.view2.View.WidgetUpdateTypes
*/
/**
* @augments Help4.jscore.ControlBase
* @property {Help4.widget.help.Widget} __widget
* @property {boolean} __whatsnew
* @property {boolean} blockUpdate
* @property {boolean} stealth
* @property {Help4.control2.container.Container} _contentView
* @property {Help4.control2.container.Container} _tileView
* @property {Help4.widget.help.view2.View.Cache} _cache
* @property {Help4.jscore.MutualExclusion} _mutual
* @property {boolean} _updating
* @property {Help4.widget.help.view2.TileContainer} _tileContainer
* @property {Help4.control2.Control} _mouseOverControl
* @property {?Help4.widget.help.view2.LaserBeam} _laserBeam
* @property {Function} _domRefreshExecutor
* @property {boolean} _initialized
*/
Help4.widget.help.view2.View = class extends Help4.jscore.ControlBase {
/**
* @override
* @param {Help4.widget.help.view2.View.Params} params
*/
constructor(params) {
const domRefreshExecutor = () => this.isDestroyed() || this._updating || this.update();
const {
jscore: {ControlBase: {TYPES: T}},
control2: {container: {Container: ControlContainer}},
widget: {
companionCore: {Core},
help: {view2: {TileContainer}},
whatsnew: {Widget: WhatsNewWidget}
}
} = Help4;
const {widget} = params;
const contentViewParams = Core.addStandardViewParameters(widget, {
css: 'widget-help-view content-view content-view2',
ariaLive: 'assertive',
ariaAtomic: 'true',
ariaRelevant: 'additions'
}, 'full');
const tileViewParams = Core.addStandardViewParameters(widget, {
css: 'widget-help-view tile-view tile-view2'
}, 'contentDiv');
tileViewParams.dom ||= document.createDocumentFragment();
const contentView = new ControlContainer(contentViewParams)
.addListener(['click', 'mouseover', 'mouseout'], ({type, target: [container, control]}) => _onControlEvent.call(this, type, control));
const tileView = new ControlContainer(tileViewParams)
.addListener(['click', 'mouseover', 'mouseout', 'space', 'enter'], ({type, target: [container, control]}) => {
if (type === 'space' || type === 'enter') type = 'click';
_onControlEvent.call(this, type, control);
});
super(params, {
params: {
widget: {type: T.instance, readonly: true, mandatory: true, private: true},
whatsnew: {type: T.boolean, readonly: true, private: true}, // will be set below to avoid override by params
blockUpdate: {type: T.boolean},
stealth: {type: T.boolean}
},
statics: {
_contentView: {init: contentView},
_tileView: {init: tileView},
_cache: {init: {}, destroy: false},
_mutual: {init: new Help4.jscore.MutualExclusion()},
_updating: {init: false, destroy: false},
_tileContainer: {init: null},
_mouseOverControl: {init: null, destroy: false},
_laserBeam: {},
_domRefreshExecutor: {init: domRefreshExecutor, destroy: false},
_initialized: {init: false},
},
config: {
onPropertyChange: ({name, value}) => name === 'stealth' && (this._tileContainer.stealth = value)
}
});
const whatsnew = widget instanceof WhatsNewWidget;
this.dataFunctions.set({whatsnew}, {allowReadonlyOverride: true}); // allow readonly override
const {stealth} = this;
this._tileContainer = new TileContainer({view: this, widget, contentView, tileView, stealth})
.addListener('closeCallout', ({descriptor}) => _stopCallout.call(this, descriptor))
.addListener('closeAnnouncement', ({descriptor, checkbox}) => _stopAnnouncement.call(this, descriptor, checkbox))
.addListener('showCallout', ({descriptor}) => {
const {view2} = Help4.widget.help;
const data = view2.convertTileDescriptor(descriptor);
this._fireEvent({type: 'select', data});
});
}
/** @type {number} */
static BUBBLE_CLOSE_TIME = 500;
/** @override */
destroy() {
const {Core} = Help4.widget.companionCore;
const {__widget, _domRefreshExecutor} = this;
const context = __widget.getContext();
context && Core.disconnectDomRefresh(_domRefreshExecutor, context);
super.destroy();
}
/**
* @param {?Help4.widget.help.view2.SerializedStatus} status
* @param {Help4.widget.help.view2.Tile.Descriptor} [select]
* @returns {Promise<void>}
*/
async init(status, select) {
const {Core} = Help4.widget.companionCore;
const {__widget, _domRefreshExecutor} = this;
// system is still booting and might not be ready especially for condition element evaluation;
// wait a bit to let the boot finish
await Core.waitControllerPlaybackServiceReady(__widget, 100);
if (this.isDestroyed()) return;
// observe dom changes
const context = __widget.getContext();
Core.observeDomRefresh(_domRefreshExecutor, context, this);
// update view
this._initialized = true;
await this.update({status, select, isRefresh: false});
}
/**
* @returns {Help4.widget.help.view2.SerializedStatus}
*/
serialize() {
const {view2} = Help4.widget.help;
return view2.serialize(this);
}
/**
* @param {Object} [params = {}]
* @param {?Help4.widget.help.view2.SerializedStatus} [params.status]
* @param {Help4.widget.help.view2.Tile.Descriptor} [params.select]
* @param {boolean} [params.stealth]
* @param {boolean} [params.isRefresh = true]
* @returns {Promise<void>}
*/
async update({status, select, stealth, isRefresh = true} = {}) {
const {
help: {view2},
companionCore: {data: {Help}},
} = Help4.widget;
view2.deserialize(this, status);
_updateTileView.call(this);
if (this.blockUpdate || !this._initialized) return;
// check whether we are still showing the same projects with same catalogue key on the same screen
// if yes, we can skip the complete recalculation and increase performance
const {
screenId,
catalogueKey,
helpIds,
isDataUpdate
} = /** @type {Help4.widget.help.view2.AllowUpdateResult} */ view2.allowUpdateFromCache(this);
const {
/** @type {Help4.widget.help.Widget} */ __widget,
/** @type {Help4.widget.help.view2.View.Cache} */ _cache,
/** @type {Help4.jscore.MutualExclusion} */ _mutual,
/** @type {Help4.widget.help.view2.TileContainer} */ _tileContainer,
/** @type {boolean} */ __whatsnew: whatsnew
} = this;
// update cache
_cache.screenId = screenId;
_cache.catalogueKey = catalogueKey;
_cache.helpIds = [...helpIds];
if (typeof select === 'string') _cache.select = select;
if (typeof stealth === 'boolean') _cache.stealth = stealth;
isDataUpdate && (_cache.isDataUpdate = true);
// start of ASYNC area
const mutualToken = _mutual.start();
_mutual.access(mutualToken); // immediately access; to avoid code execution below
// block intermediate updates through DomRefreshEngine, etc.
this._updating = true;
// create tile list
const tiles = await Help.getAvailableTiles({whatsnew, screenId});
if (this.isDestroyed() || !_mutual.access(mutualToken)) return;
_cache.tiles = tiles;
// check cache sanity
if (status && view2.fixPersistentCache(this, tiles, screenId)) {
this._fireEvent({type: 'fixStatus'});
}
// filter UR tiles; in case a UACP/SEN tile is hidden by condition a UR tile with same hotspot will also be hidden
const urFilteredTiles = Help.filterUrTiles(tiles);
// reduce to those that pass conditions
const conditionTiles = await Help.filterTilesByCondition(urFilteredTiles, {whatsnew});
if (this.isDestroyed() || !_mutual.access(mutualToken)) return;
_cache.conditionTiles = conditionTiles;
// update hotspot status
const tilesWithHotspots = conditionTiles.filter(projectTile => view2.hasHotspot(__widget, projectTile));
const hotspotStatus = await view2.HotspotScan.scan(__widget, tilesWithHotspots);
if (this.isDestroyed() || !_mutual.access(mutualToken)) return;
// end of ASYNC area
select = _cache.select;
stealth = _cache.stealth ?? this.stealth;
delete _cache.select;
delete _cache.stealth;
// add to tile container
_tileContainer.set({projectTiles: conditionTiles, hotspotStatus, stealth});
if (select) {
_tileContainer.selected = select;
const data = view2.convertTileDescriptor(select);
this._fireEvent({type: 'select', data});
}
// set unseen announcements and callouts
const {configuration: {WM}} = __widget.getContext();
_tileContainer.announcements = WM > 1 ? [] : _getAnnouncements.call(this);
_tileContainer.callouts = _getCallouts.call(this);
// reset status; but not for certain special updates
if (_cache.isDataUpdate) {
// XRAY-6395, XRAY-6396
// several processes might hit the update function
// one of them could be after a navigate with isDataUpdate true
// but it could have been kicked out by a later process
// we store the need to update data once in cache
// to execute here
delete _cache.isDataUpdate;
this.onWidgetUpdate({type: 'navigate', select});
}
this.stealth = stealth;
// unblock intermediate updates
this._updating = false;
}
/** @returns {Help4.widget.help.TileDescriptor[]} */
getSeenAnimations() {
const {__widget, _cache} = this;
const {configuration: {core: {screenId}}} = __widget.getContext();
return _cache.persist?.animation?.[screenId] || [];
}
/** @returns {{tiles: ?Object, content: ?Object}} */
getTexts() {
const {_tileView, _contentView} = this;
return {
tiles: _tileView?.getTexts(),
content: _contentView?.getTexts()
};
}
/** @param {{tiles: ?Object, content: ?Object}} texts */
setTexts({tiles, content}) {
const {_tileView, _contentView} = this;
tiles && _tileView?.setTexts(tiles);
content && _contentView?.setTexts(content);
}
/** will close any open lightbox */
closeLightbox() {
const {_tileContainer} = this;
const {selected} = _tileContainer;
if (!selected) return;
const {type, linkLightbox} = _tileContainer.get(selected);
if (type === 'link' && !!linkLightbox) _tileContainer.selected = null;
}
/** @param {Help4.widget.help.TileDescriptor} data */
select(data) {
const {view2} = Help4.widget.help;
this._tileContainer.selected = view2.convertTileDescriptor(data);
this._fireEvent({type: 'select', data});
}
/** focus handling */
focus() {
const {_tileView} = this;
_tileView.count() > 0
? _tileView.get(0).focus()
: _tileView.focus();
}
/**
* focus handling - up/down arrow keys
* @param {string} direction
*/
focusListItem(direction) {
const {_tileView} = this;
let count = _tileView.count();
if (count > 0) {
const visibleControls = [];
_tileView.forEach(control => control.visible && visibleControls.push(control));
const focussedElement = Help4.widget.getActiveElement();
let index = visibleControls.findIndex(control => control.getDom() === focussedElement);
if (index >= 0) visibleControls[direction === 'down' ? ++index : --index]?.focus();
}
}
/** @param {Help4.widget.help.TileDescriptor} data */
showQuickTour(data) {
const {view2} = Help4.widget.help;
this._tileContainer.quickTour = view2.convertTileDescriptor(data);
this._fireEvent({type: 'select', data});
}
/**
* @param {Object} event
* @param {Help4.widget.help.view2.View.WidgetUpdateTypes} event.type
* @param {Help4.widget.help.view2.Tile.Descriptor} [event.select]
*/
onWidgetUpdate({type, select}) {
const {_tileContainer} = this;
const selectAnnouncementOrCallout = select => {
const activeWidget = Help4.widget.getActiveInstance();
if (!activeWidget || activeWidget.getName() !== 'tour') { // do not interfere w/ tour playback
_tileContainer.showAnnouncement();
select || _tileContainer.showCallout(null); // do not use current callout but force a reset
}
}
switch (type) {
case 'navigate':
// navigate means a complete data switch; is called from update()
_tileContainer.selected = select || null;
_tileContainer.hovered = null;
_tileContainer.announcement = null; // allow a new announcement to be shown
_tileContainer.callout = null; // reset callout data
selectAnnouncementOrCallout(select);
break;
case 'widgetDeactivate': { // another widget deactivates
const {selected} = _tileContainer;
selectAnnouncementOrCallout(selected);
break;
}
case 'activate': // widget activates
case 'controllerOpen': // help is opened
// in case nothing is selected: show next callout
const {selected} = _tileContainer;
selected || _tileContainer.showCallout();
break;
case 'deactivate': // widget deactivates
case 'controllerClose': // help is closed
// clean all content and reset selection
// but keep callouts open / open any
_tileContainer.hovered = null;
_tileContainer.showCallout();
if (!_tileContainer.callout) _tileContainer.selected = null;
break;
case 'playbackActive': // playbackActive is called after init when help is closed
case 'redraw': // widget redraw, e.g. API data change, PUB - HEAD switch, ...
break;
}
}
/** @returns {Help4.control2.container.Container} */
getContentView() {
return this._contentView;
}
/** @returns {Help4.widget.help.ProjectTile[]} */
getTiles() {
return this._cache.tiles;
}
/** @param {Help4.widget.help.view2.Tile.Descriptor} descriptor */
tileSelect(descriptor) {
const {view2} = Help4.widget.help;
_stopHotspotAnimation.call(this, descriptor);
const {_cache: {tiles}} = this;
const data = view2.convertTileDescriptor(descriptor);
const {type} = tiles.find(({id}) => id === data.tileId) || {};
if (type === 'tour') {
data.type = 'tour';
this._fireEvent({type: 'select', data});
return;
}
// select a new tile or deselect an already selected one
// - selected: TileDescriptor
// - deselected: null
// - no change: undefined
const result = _select.call(this, descriptor);
if (result !== undefined) {
_stopCallout.call(this, descriptor);
const data = result ? view2.convertTileDescriptor(result) : null;
this._fireEvent({type: 'select', data});
}
}
/**
* @param {?Help4.widget.help.view2.Tile.Descriptor} [descriptor = null]
*/
wmHotspotHover(descriptor = null) {
this._tileContainer.wmHovered = descriptor;
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {'click'|'mouseover'|'mouseout'} eventType
* @param {Help4.control2.Control} control
*/
function _onControlEvent(eventType, control) {
if (!control || control.isDestroyed() || this.isDestroyed()) return;
const {view2} = Help4.widget.help;
const descriptor = view2.extractTileDescriptor(control);
const {Tile: TileControl, hotspot: {Connected: HotspotControl}} = Help4.control2;
const {BubbleControl} = Help4.widget.help.view2;
const isTileControl = control instanceof TileControl;
const isHotspotControl = control instanceof HotspotControl;
const isBubbleControl = control instanceof BubbleControl;
const controlType = isTileControl ? 'tile' : isHotspotControl ? 'hotspot' : isBubbleControl ? 'bubble' : null;
const type = {
tile: {click: 'tileSelect', mouseover: 'tileOver', mouseout: 'tileOut'},
hotspot: {click: 'hotspotClick', mouseover: 'hotspotOver', mouseout: 'hotspotOut'},
bubble: {click: 'bubbleClick', mouseout: 'bubbleOut'}
}[controlType]?.[eventType];
if (!type) return;
switch (eventType) {
case 'click':
_onControlEvent2.call(this, type, descriptor, control);
break;
case 'mouseover':
// do not send multiple mouseover events for the same control
if (this._mouseOverControl !== control) {
this._mouseOverControl = control;
_onControlEvent2.call(this, type, descriptor, control);
}
break;
case 'mouseout':
// ignore mouseout events where the mouse is still over
// wait some time to allow DOM to adapt
setTimeout(() => {
if (control.isMouseOver()) return;
this._mouseOverControl = null;
_onControlEvent2.call(this, type, descriptor, control);
}, 50); // 10ms did not work
break;
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {string} type
* @param {Help4.widget.help.view2.Tile.Descriptor} descriptor
*/
function _onControlEvent2(type, descriptor) {
const {view2} = Help4.widget.help;
const {_tileContainer: {selected}} = this;
switch (type) {
case 'hotspotClick':
_stopCallout.call(this, descriptor);
// fall-through is intentional
case 'tileSelect':
this.tileSelect(descriptor);
break;
case 'bubbleClick':
_stopCallout.call(this, descriptor);
break;
case 'tileOver':
view2.LaserBeam.show(this, descriptor);
break;
case 'tileOut':
// ATTENTION:
// tileOut comes with a delay to ensure that mouse is truly out
// therefore tileOver and tileOut events come out-of-order
view2.LaserBeam.hide(this, descriptor);
break;
case 'hotspotOver': {
// select a new tile or deselect an already selected one
// - selected: TileDescriptor
// - deselected: null
// - no change: undefined
_stopHotspotAnimation.call(this, descriptor);
const result = _hotspotHover.call(this, descriptor);
if (result !== undefined && !selected) {
// in case nothing is selected: hotspot hover counts as selection
const data = result ? view2.convertTileDescriptor(result) : null;
this._fireEvent({type: 'select', data});
}
break;
}
case 'hotspotOut':
case 'bubbleOut':
// ATTENTION:
// hotspotOut comes with a delay to ensure that mouse is truly out
// therefore hotspotOver and hotspotOut events come out-of-order
_leave.call(this, descriptor)
.then(success => {
if (!success) return;
const data = view2.convertTileDescriptor(descriptor);
this._fireEvent({type: 'select', data: null, oldData: data})
});
break;
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor|null} descriptor
* @returns {Help4.widget.help.view2.Tile.Descriptor|null|undefined}
*/
function _select(descriptor) {
// return values
// - selected: TileDescriptor
// - deselected: null
// - no change: undefined
const {_tileContainer} = this;
const {/** @type {Help4.widget.help.view2.Tile.Descriptor|null} */ selected} = _tileContainer;
const isAlreadySelected = selected && selected === descriptor || false;
// deselect or click to an already selected item
if (!descriptor || isAlreadySelected) {
if (selected) {
// deselect
_tileContainer.selected = null;
_tileContainer.hovered = null; // deselection also removes hover state
return null;
}
return undefined; // no change
}
// new selection
_tileContainer.selected = descriptor;
return descriptor;
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor|null} descriptor
* @returns {Help4.widget.help.view2.Tile.Descriptor|null|undefined}
*/
function _hotspotHover(descriptor) {
// return values
// - hovered: TileDescriptor
// - un-hovered: null
// - no change: undefined
const {_tileContainer} = this;
const {
/** @type {Help4.widget.help.view2.Tile.Descriptor|null} */ selected,
/** @type {Help4.widget.help.view2.Tile.Descriptor|null} */ hovered
} = _tileContainer;
if (selected) {
// something is selected; do not interfere with it
if (selected === descriptor) {
// set hover already selected hotspot
_tileContainer.hovered = descriptor;
return descriptor;
}
return undefined; // no change
}
const isAlreadyHovered = hovered && hovered === descriptor || false;
if (isAlreadyHovered) return undefined; // no change
_tileContainer.hovered = descriptor;
return descriptor;
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor|null} descriptor
* @returns {Promise<boolean>}
*/
async function _leave(descriptor) {
const {_tileContainer} = this;
const {
/** @type {Help4.widget.help.view2.Tile.Descriptor|null} */ selected,
/** @type {Help4.widget.help.view2.Tile.Descriptor|null} */ hovered
} = _tileContainer;
const isHovered = hovered && hovered === descriptor;
if (!isHovered) return false;
if (selected) {
// something is selected; do not interfere with it
// just remove the hover mark
_tileContainer.hovered = null;
return false;
}
// in case a hotspot out results in a closed bubble:
// hotspot out counts as deselect
// do not use "_tileContainer.hovered = null;" as we need delayed close functionality!
return await _tileContainer.leave();
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor} descriptor
*/
async function _stopHotspotAnimation(descriptor) {
if (this._tileContainer.stopHotspotAnimation(descriptor)) {
const {view2} = Help4.widget.help;
if (await view2.setPersistenceCacheValue(this, 'animation', descriptor)) {
this._fireEvent({type: 'stopAnimation'});
}
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor} descriptor
*/
async function _stopCallout(descriptor) {
const {view2} = Help4.widget.help;
const {_tileContainer} = this;
const isCallout = Help4.includes(_tileContainer.callouts, descriptor);
if (isCallout && await view2.setPersistenceCacheValue(this, 'callout', descriptor)) {
// callout no longer open
_tileContainer.callout = null;
// update callout list; now one more callout has been seen
_tileContainer.callouts = _getCallouts.call(this);
// update storage
this._fireEvent({type: 'stopCallout'});
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
* @param {Help4.widget.help.view2.Tile.Descriptor} descriptor
* @param {boolean|null} checkbox
*/
async function _stopAnnouncement(descriptor, checkbox) {
const {view2} = Help4.widget.help;
const {_tileContainer, _cache: {conditionTiles}} = this;
if (_tileContainer.announcement !== descriptor) return;
const {tileId} = view2.convertTileDescriptor(descriptor);
const {splashOption} = checkbox === true
? {splashOption: 'once'} // checkbox true: do not show again
: /** @type {Help4.widget.help.ProjectTile} */ conditionTiles.find(({id}) => id === tileId);
const persistenceId = `announcement_${splashOption}`;
if (await view2.setPersistenceCacheValue(this, persistenceId, descriptor)) {
// announcement no longer open; set empty string to avoid showing any further announcements
_tileContainer.announcement = false;
// update callout list; now one more callout has been seen
_tileContainer.announcements = _getAnnouncements.call(this);
// update storage
this._fireEvent({type: 'stopAnnouncement'});
}
}
/**
* @memberof Help4.widget.help.view2.View#
* @private
*/
function _updateTileView() {
const {__widget, _tileView} = this;
if (__widget.isActive()) {
const {panel} = __widget.getContext();
if (panel) {
const contentInstance = /** @type {?Help4.control2.bubble.content.Panel} */ panel.getContentInstance();
_tileView.setDom(contentInstance?.useContentDiv());
return;
}
}
const ownerDom = _tileView.getOwnerDom();
if (ownerDom.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
_tileView.setDom(document.createDocumentFragment());
}
}
/**
* get unseen callouts
* @memberof Help4.widget.help.view2.View#
* @private
* @returns {Help4.widget.help.view2.Tile.Descriptor[]}
*/
function _getCallouts() {
const {view2} = Help4.widget.help;
const {_cache, __widget} = this;
const {persist: {callout} = {}, conditionTiles} = _cache;
const {configuration: {core: {screenId}}} = __widget.getContext();
return conditionTiles
.map(tile => {
if (!!tile.callout) {
// filter already seen callouts
const descriptor = view2.extractTileDescriptor(tile);
return view2.containsTileDescriptor(callout?.[screenId] || [], descriptor)
? null
: descriptor;
}
return null;
})
.filter(descriptor => !!descriptor);
}
/**
* get unseen announcements
* @memberof Help4.widget.help.view2.View#
* @private
* @returns {Help4.widget.help.view2.Tile.Descriptor[]}
*/
function _getAnnouncements() {
const {view2} = Help4.widget.help;
const {_cache, __widget} = this;
const {persist: {announcement_always, announcement_once} = {}, conditionTiles} = _cache;
const {configuration: {core: {screenId}}} = __widget.getContext();
const tile = conditionTiles.find(tile => {
const {type, linkLightbox, linkTo, splash} = tile;
return type === 'link' && !!linkLightbox && !!linkTo && !!splash;
});
if (tile) {
// always check both lists; as an "always" announcement is stored within "once"
// in case the user checks the "do not show again" checkbox
const descriptor = view2.extractTileDescriptor(tile);
if (!view2.containsTileDescriptor(announcement_always?.[screenId] || [], descriptor) &&
!view2.containsTileDescriptor(announcement_once?.[screenId] || [], descriptor))
{
return [descriptor];
}
}
return [];
}
})();