goog.module('gep.provider.CursorProvider');
const {listen,unlisten,Event,EventType,EventTarget} = goog.require('goog.events');
const classlist = goog.require('goog.dom.classlist');
const {setStyle} = goog.require('goog.style');
/**
* This provider (singleton) manages the display of a custom cursor object if a corresponding element with the `class="custom-cursor"` exists in the dom.
* @extends {EventTarget}
*/
class CursorProvider extends EventTarget
{
constructor()
{
super();
/**
* List of elements to be perceived for hovering.
* @type {NodeList}
* @private
*/
this.hoverElements_ = null;
/**
* List of elements that should use the default cursor for themselves again.
* @type {NodeList}
* @private
*/
this.leaveElements_ = null;
/**
* Element in the dom which is used as a grafic replacement of the cursor.
* @type {Element}
* @private
*/
this.cursor_ = document.documentElement.querySelector('.custom-cursor');
/**
* Specifies whether the display of the custom cursor should be prevented.
* @type {boolean}
* @private
*/
this.preventShow_ = false;
if(this.cursor_)
{
listen(window, EventType.MOUSEMOVE, this.move_, false, this);
listen(window, EventType.MOUSEOUT, this.hide, false, this);
}
}
/**
* Trigger manual check to display custom mouse cursor after changing the list of hover or leave elements.
*/
update()
{
if(!this.cursor_)
return;
if(this.hoverElements_)
this.hoverElements_.forEach((element) => {
unlisten(element, EventType.MOUSEOVER, this.over, false, this);
unlisten(element, EventType.MOUSEOUT, this.out, false, this);
});
if(this.leaveElements_)
this.leaveElements_.forEach((element) => {
unlisten(element, EventType.MOUSEOVER, this.handleLeaveOver_, false, this);
unlisten(element, EventType.MOUSEOUT, this.handleLeaveOut_, false, this);
});
this.hoverElements_ = document.body.querySelectorAll('button,a');
this.hoverElements_.forEach((element) => {
listen(element, EventType.MOUSEOVER, this.over, false, this);
listen(element, EventType.MOUSEOUT, this.out, false, this);
});
this.leaveElements_ = document.body.querySelectorAll('.layer-media-vimeo,.layer.installation-frame .layer-content-wrapper');
this.leaveElements_.forEach((element) => {
listen(element, EventType.MOUSEOVER, this.handleLeaveOver_, false, this);
listen(element, EventType.MOUSEOUT, this.handleLeaveOut_, false, this);
});
}
/**
* Handle mouse move event for updating the position of the custom cursor
* @param {Event} event
* @private
*/
move_(event)
{
if(!this.preventShow_) this.show();
setStyle(this.cursor_, {'left': event.getBrowserEvent().clientX+'px', 'top': event.getBrowserEvent().clientY+'px'})
}
/**
* Handle mouse over an element which is defined in the leave element list and should display the default cursor
* @param {Event} event
* @private
*/
handleLeaveOver_(event)
{
this.preventShow_ = true;
this.hide();
}
/**
* Handle mouse out an element which is defined in the leave element list and should display the default cursor
* @private
*/
handleLeaveOut_()
{
this.preventShow_ = false;
}
/**
* Handle mouse over event of an element which is defined in the hover elements list
*/
over()
{
classlist.add(document.documentElement, 'is-mouse-over');
}
/**
* Handle mouse out event of an element which is defined in the hover elements list
*/
out()
{
classlist.remove(document.documentElement, 'is-mouse-over');
}
/**
* Make the custom cursor visible
*/
show()
{
if(!this.preventShow_)
classlist.add(document.documentElement, 'has-custom-cursor');
}
/**
* Hide the custom cursor
*/
hide()
{
classlist.remove(document.documentElement, 'has-custom-cursor');
}
}
goog.addSingletonGetter(CursorProvider);
exports = CursorProvider;