import { CONTROLS, MODES, EVENTS } from '../Constants';
import { DataImage } from '../DataImage';
import * as THREE from 'three';
/**
* @classdesc Widget for controls
* @constructor
* @param {HTMLElement} container - A domElement where default control widget will be attached to
*/
function Widget ( container ) {
if ( !container ) {
console.warn( 'PANOLENS.Widget: No container specified' );
}
THREE.EventDispatcher.call( this );
this.DEFAULT_TRANSITION = 'all 0.27s ease';
this.TOUCH_ENABLED = !!(( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch);
this.PREVENT_EVENT_HANDLER = function ( event ) {
event.preventDefault();
event.stopPropagation();
};
this.container = container;
this.barElement = null;
this.fullscreenElement = null;
this.videoElement = null;
this.settingElement = null;
this.mainMenu = null;
this.activeMainItem = null;
this.activeSubMenu = null;
this.mask = null;
}
Widget.prototype = Object.assign( Object.create( THREE.EventDispatcher.prototype ), {
constructor: Widget,
/**
* Add control bar
* @memberOf Widget
* @instance
*/
addControlBar: function () {
if ( !this.container ) {
console.warn( 'Widget container not set' );
return;
}
const scope = this;
const gradientStyle = 'linear-gradient(bottom, rgba(0,0,0,0.2), rgba(0,0,0,0))';
const bar = document.createElement( 'div' );
bar.style.width = '100%';
bar.style.height = '44px';
bar.style.float = 'left';
bar.style.transform = bar.style.webkitTransform = bar.style.msTransform = 'translateY(-100%)';
bar.style.background = '-webkit-' + gradientStyle;
bar.style.background = '-moz-' + gradientStyle;
bar.style.background = '-o-' + gradientStyle;
bar.style.background = '-ms-' + gradientStyle;
bar.style.background = gradientStyle;
bar.style.transition = this.DEFAULT_TRANSITION;
bar.style.pointerEvents = 'none';
bar.isHidden = false;
bar.toggle = function () {
bar.isHidden = !bar.isHidden;
const styleTranslate = bar.isHidden ? 'translateY(0)' : 'translateY(-100%)';
const styleOpacity = bar.isHidden ? 0 : 1;
bar.style.transform = bar.style.webkitTransform = bar.style.msTransform = styleTranslate;
bar.style.opacity = styleOpacity;
};
// Menu
const menu = this.createDefaultMenu();
this.mainMenu = this.createMainMenu( menu );
bar.appendChild( this.mainMenu );
// Mask
const mask = this.createMask();
this.mask = mask;
this.container.appendChild( mask );
// Dispose
bar.dispose = function () {
if ( scope.fullscreenElement ) {
bar.removeChild( scope.fullscreenElement );
scope.fullscreenElement.dispose();
scope.fullscreenElement = null;
}
if ( scope.settingElement ) {
bar.removeChild( scope.settingElement );
scope.settingElement.dispose();
scope.settingElement = null;
}
if ( scope.videoElement ) {
bar.removeChild( scope.videoElement );
scope.videoElement.dispose();
scope.videoElement = null;
}
};
this.container.appendChild( bar );
// Mask events
this.mask.addEventListener( 'mousemove', this.PREVENT_EVENT_HANDLER, true );
this.mask.addEventListener( 'mouseup', this.PREVENT_EVENT_HANDLER, true );
this.mask.addEventListener( 'mousedown', this.PREVENT_EVENT_HANDLER, true );
this.mask.addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', function ( event ) {
event.preventDefault();
event.stopPropagation();
scope.mask.hide();
scope.settingElement.deactivate();
}, false );
// Event listener
this.addEventListener( 'control-bar-toggle', bar.toggle );
this.barElement = bar;
},
/**
* Create default menu
* @memberOf Widget
* @instance
*/
createDefaultMenu: function () {
const scope = this;
const handler = function ( method, data ) {
return function () {
scope.dispatchEvent( {
type: EVENTS.VIEWER_HANDLER,
method: method,
data: data
} );
};
};
return [
{
title: 'Control',
subMenu: [
{
title: this.TOUCH_ENABLED ? 'Touch' : 'Mouse',
handler: handler( 'enableControl', CONTROLS.ORBIT )
},
{
title: 'Sensor',
handler: handler( 'enableControl', CONTROLS.DEVICEORIENTATION )
}
]
},
{
title: 'Mode',
subMenu: [
{
title: 'Normal',
handler: handler( 'disableEffect' )
},
{
title: 'Cardboard',
handler: handler( 'enableEffect', MODES.CARDBOARD )
},
{
title: 'Stereoscopic',
handler: handler( 'enableEffect', MODES.STEREO )
}
]
}
];
},
/**
* Add buttons on top of control bar
* @param {string} name - The control button name to be created
* @memberOf Widget
* @instance
*/
addControlButton: function ( name ) {
let element;
switch( name ) {
case 'fullscreen':
element = this.createFullscreenButton();
this.fullscreenElement = element;
break;
case 'setting':
element = this.createSettingButton();
this.settingElement = element;
break;
case 'video':
element = this.createVideoControl();
this.videoElement = element;
break;
default:
return;
}
if ( !element ) {
return;
}
this.barElement.appendChild( element );
},
/**
* Create modal mask
* @memberOf Widget
* @instance
*/
createMask: function () {
const element = document.createElement( 'div' );
element.style.position = 'absolute';
element.style.top = 0;
element.style.left = 0;
element.style.width = '100%';
element.style.height = '100%';
element.style.background = 'transparent';
element.style.display = 'none';
element.show = function () {
this.style.display = 'block';
};
element.hide = function () {
this.style.display = 'none';
};
return element;
},
/**
* Create Setting button to toggle menu
* @memberOf Widget
* @instance
*/
createSettingButton: function () {
let scope = this, item;
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
scope.mainMenu.toggle();
if ( this.activated ) {
this.deactivate();
} else {
this.activate();
}
}
item = this.createCustomItem( {
style: {
backgroundImage: 'url("' + DataImage.Setting + '")',
webkitTransition: this.DEFAULT_TRANSITION,
transition: this.DEFAULT_TRANSITION
},
onTap: onTap
} );
item.activate = function () {
this.style.transform = 'rotate3d(0,0,1,90deg)';
this.activated = true;
scope.mask.show();
};
item.deactivate = function () {
this.style.transform = 'rotate3d(0,0,0,0)';
this.activated = false;
scope.mask.hide();
if ( scope.mainMenu && scope.mainMenu.visible ) {
scope.mainMenu.hide();
}
if ( scope.activeSubMenu && scope.activeSubMenu.visible ) {
scope.activeSubMenu.hide();
}
if ( scope.mainMenu && scope.mainMenu._width ) {
scope.mainMenu.changeSize( scope.mainMenu._width );
scope.mainMenu.unslideAll();
}
};
item.activated = false;
return item;
},
/**
* Create Fullscreen button
* @return {HTMLSpanElement} - The dom element icon for fullscreen
* @memberOf Widget
* @instance
* @fires Widget#panolens-viewer-handler
*/
createFullscreenButton: function () {
let scope = this, item, isFullscreen = false, tapSkipped = true, stylesheetId;
const { container } = this;
stylesheetId = 'panolens-style-addon';
// Don't create button if no support
if ( !document.fullscreenEnabled &&
!document.webkitFullscreenEnabled &&
!document.mozFullScreenEnabled &&
!document.msFullscreenEnabled ) {
return;
}
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
tapSkipped = false;
if ( !isFullscreen ) {
if ( container.requestFullscreen ) { container.requestFullscreen(); }
if ( container.msRequestFullscreen ) { container.msRequestFullscreen(); }
if ( container.mozRequestFullScreen ) { container.mozRequestFullScreen(); }
if ( container.webkitRequestFullscreen ) { container.webkitRequestFullscreen( Element.ALLOW_KEYBOARD_INPUT ); }
isFullscreen = true;
} else {
if ( document.exitFullscreen ) { document.exitFullscreen(); }
if ( document.msExitFullscreen ) { document.msExitFullscreen(); }
if ( document.mozCancelFullScreen ) { document.mozCancelFullScreen(); }
if ( document.webkitExitFullscreen ) { document.webkitExitFullscreen( ); }
isFullscreen = false;
}
this.style.backgroundImage = ( isFullscreen )
? 'url("' + DataImage.FullscreenLeave + '")'
: 'url("' + DataImage.FullscreenEnter + '")';
}
function onFullScreenChange () {
if ( tapSkipped ) {
isFullscreen = !isFullscreen;
item.style.backgroundImage = ( isFullscreen )
? 'url("' + DataImage.FullscreenLeave + '")'
: 'url("' + DataImage.FullscreenEnter + '")';
}
/**
* Viewer handler event
* @type {object}
* @event Widget#panolens-viewer-handler
* @property {string} method - 'onWindowResize' function call on Viewer
*/
scope.dispatchEvent( { type: EVENTS.VIEWER_HANDLER, method: 'onWindowResize' } );
tapSkipped = true;
}
document.addEventListener( 'fullscreenchange', onFullScreenChange, false );
document.addEventListener( 'webkitfullscreenchange', onFullScreenChange, false );
document.addEventListener( 'mozfullscreenchange', onFullScreenChange, false );
document.addEventListener( 'MSFullscreenChange', onFullScreenChange, false );
item = this.createCustomItem( {
style: {
backgroundImage: 'url("' + DataImage.FullscreenEnter + '")'
},
onTap: onTap
} );
// Add fullscreen stlye if not exists
if ( !document.querySelector( stylesheetId ) ) {
const sheet = document.createElement( 'style' );
sheet.id = stylesheetId;
sheet.innerHTML = ':-webkit-full-screen { width: 100% !important; height: 100% !important }';
document.head.appendChild( sheet );
}
return item;
},
/**
* Create video control container
* @memberOf Widget
* @instance
* @return {HTMLSpanElement} - The dom element icon for video control
*/
createVideoControl: function () {
const item = document.createElement( 'span' );
item.style.display = 'none';
item.show = function () {
item.style.display = '';
};
item.hide = function () {
item.style.display = 'none';
item.controlButton.paused = true;
item.controlButton.update();
};
item.controlButton = this.createVideoControlButton();
item.seekBar = this.createVideoControlSeekbar();
item.appendChild( item.controlButton );
item.appendChild( item.seekBar );
item.dispose = function () {
item.removeChild( item.controlButton );
item.removeChild( item.seekBar );
item.controlButton.dispose();
item.controlButton = null;
item.seekBar.dispose();
item.seekBar = null;
};
this.addEventListener( 'video-control-show', item.show );
this.addEventListener( 'video-control-hide', item.hide );
return item;
},
/**
* Create video control button
* @memberOf Widget
* @instance
* @return {HTMLSpanElement} - The dom element icon for video control
* @fires Widget#panolens-viewer-handler
*/
createVideoControlButton: function () {
const scope = this;
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
/**
* Viewer handler event
* @type {object}
* @event Widget#panolens-viewer-handler
* @property {string} method - 'toggleVideoPlay' function call on Viewer
*/
scope.dispatchEvent( { type: EVENTS.VIEWER_HANDLER, method: 'toggleVideoPlay', data: !this.paused } );
this.paused = !this.paused;
item.update();
};
const item = this.createCustomItem( {
style: {
float: 'left',
backgroundImage: 'url("' + DataImage.VideoPlay + '")'
},
onTap: onTap
} );
item.paused = true;
item.update = function ( paused ) {
this.paused = paused !== undefined ? paused : this.paused;
this.style.backgroundImage = 'url("' + ( this.paused
? DataImage.VideoPlay
: DataImage.VideoPause ) + '")';
};
return item;
},
/**
* Create video seekbar
* @memberOf Widget
* @instance
* @return {HTMLSpanElement} - The dom element icon for video seekbar
* @fires Widget#panolens-viewer-handler
*/
createVideoControlSeekbar: function () {
let scope = this, item, progressElement, progressElementControl,
isDragging = false, mouseX, percentageNow, percentageNext;
progressElement = document.createElement( 'div' );
progressElement.style.width = '0%';
progressElement.style.height = '100%';
progressElement.style.backgroundColor = '#fff';
progressElementControl = document.createElement( 'div' );
progressElementControl.style.float = 'right';
progressElementControl.style.width = '14px';
progressElementControl.style.height = '14px';
progressElementControl.style.transform = 'translate(7px, -5px)';
progressElementControl.style.borderRadius = '50%';
progressElementControl.style.backgroundColor = '#ddd';
progressElementControl.addEventListener( 'mousedown', onMouseDown, { passive: true } );
progressElementControl.addEventListener( 'touchstart', onMouseDown, { passive: true } );
function onMouseDown ( event ) {
event.stopPropagation();
isDragging = true;
mouseX = event.clientX || ( event.changedTouches && event.changedTouches[0].clientX );
percentageNow = parseInt( progressElement.style.width ) / 100;
addControlListeners();
}
function onVideoControlDrag ( event ) {
if( isDragging ){
const clientX = event.clientX || ( event.changedTouches && event.changedTouches[0].clientX );
percentageNext = ( clientX - mouseX ) / item.clientWidth;
percentageNext = percentageNow + percentageNext;
percentageNext = percentageNext > 1 ? 1 : ( ( percentageNext < 0 ) ? 0 : percentageNext );
item.setProgress ( percentageNext );
/**
* Viewer handler event
* @type {object}
* @event Widget#panolens-viewer-handler
* @property {string} method - 'setVideoCurrentTime' function call on Viewer
* @property {number} data - Percentage of current video. Range from 0.0 to 1.0
*/
scope.dispatchEvent( { type: EVENTS.VIEWER_HANDLER, method: 'setVideoCurrentTime', data: percentageNext } );
}
}
function onVideoControlStop ( event ) {
event.stopPropagation();
isDragging = false;
removeControlListeners();
}
function addControlListeners () {
scope.container.addEventListener( 'mousemove', onVideoControlDrag, { passive: true } );
scope.container.addEventListener( 'mouseup', onVideoControlStop, { passive: true } );
scope.container.addEventListener( 'touchmove', onVideoControlDrag, { passive: true } );
scope.container.addEventListener( 'touchend', onVideoControlStop, { passive: true } );
}
function removeControlListeners () {
scope.container.removeEventListener( 'mousemove', onVideoControlDrag, false );
scope.container.removeEventListener( 'mouseup', onVideoControlStop, false );
scope.container.removeEventListener( 'touchmove', onVideoControlDrag, false );
scope.container.removeEventListener( 'touchend', onVideoControlStop, false );
}
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
if ( event.target === progressElementControl ) { return; }
const percentage = ( event.changedTouches && event.changedTouches.length > 0 )
? ( event.changedTouches[0].pageX - event.target.getBoundingClientRect().left ) / this.clientWidth
: event.offsetX / this.clientWidth;
/**
* Viewer handler event
* @type {object}
* @property {string} method - 'setVideoCurrentTime' function call on Viewer
* @property {number} data - Percentage of current video. Range from 0.0 to 1.0
*/
scope.dispatchEvent( { type: EVENTS.VIEWER_HANDLER, method: 'setVideoCurrentTime', data: percentage } );
item.setProgress( event.offsetX / this.clientWidth );
};
function onDispose () {
removeControlListeners();
progressElement = null;
progressElementControl = null;
}
progressElement.appendChild( progressElementControl );
item = this.createCustomItem( {
style: {
float: 'left',
width: '30%',
height: '4px',
marginTop: '20px',
backgroundColor: 'rgba(188,188,188,0.8)'
},
onTap: onTap,
onDispose: onDispose
} );
item.appendChild( progressElement );
item.setProgress = function( percentage ) {
progressElement.style.width = percentage * 100 + '%';
};
this.addEventListener( 'video-update', function ( event ) {
item.setProgress( event.percentage );
} );
item.progressElement = progressElement;
item.progressElementControl = progressElementControl;
return item;
},
/**
* Create menu item
* @param {string} title - Title to display
* @memberOf Widget
* @instance
* @return {HTMLElement} - An anchor tag element
*/
createMenuItem: function ( title ) {
const scope = this;
const item = document.createElement( 'a' );
item.textContent = title;
item.style.display = 'block';
item.style.padding = '10px';
item.style.textDecoration = 'none';
item.style.cursor = 'pointer';
item.style.pointerEvents = 'auto';
item.style.transition = this.DEFAULT_TRANSITION;
item.slide = function ( right ) {
this.style.transform = 'translateX(' + ( right ? '' : '-' ) + '100%)';
};
item.unslide = function () {
this.style.transform = 'translateX(0)';
};
item.setIcon = function ( url ) {
if ( this.icon ) {
this.icon.style.backgroundImage = 'url(' + url + ')';
}
};
item.setSelectionTitle = function ( title ) {
if ( this.selection ) {
this.selection.textContent = title;
}
};
item.addSelection = function ( name ) {
const selection = document.createElement( 'span' );
selection.style.fontSize = '13px';
selection.style.fontWeight = '300';
selection.style.float = 'right';
this.selection = selection;
this.setSelectionTitle( name );
this.appendChild( selection );
return this;
};
item.addIcon = function ( url = DataImage.ChevronRight, left = false, flip = false ) {
const element = document.createElement( 'span' );
element.style.float = left ? 'left' : 'right';
element.style.width = '17px';
element.style.height = '17px';
element.style[ 'margin' + ( left ? 'Right' : 'Left' ) ] = '12px';
element.style.backgroundSize = 'cover';
if ( flip ) {
element.style.transform = 'rotateZ(180deg)';
}
this.icon = element;
this.setIcon( url );
this.appendChild( element );
return this;
};
item.addSubMenu = function ( title, items ) {
this.subMenu = scope.createSubMenu( title, items );
return this;
};
item.addEventListener( 'mouseenter', function () {
this.style.backgroundColor = '#e0e0e0';
}, false );
item.addEventListener( 'mouseleave', function () {
this.style.backgroundColor = '#fafafa';
}, false );
return item;
},
/**
* Create menu item header
* @param {string} title - Title to display
* @memberOf Widget
* @instance
* @return {HTMLElement} - An anchor tag element
*/
createMenuItemHeader: function ( title ) {
const header = this.createMenuItem( title );
header.style.borderBottom = '1px solid #333';
header.style.paddingBottom = '15px';
return header;
},
/**
* Create main menu
* @param {array} menus - Menu array list
* @memberOf Widget
* @instance
* @return {HTMLElement} - A span element
*/
createMainMenu: function ( menus ) {
let scope = this, menu = this.createMenu();
menu._width = 200;
menu.changeSize( menu._width );
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
let mainMenu = scope.mainMenu, subMenu = this.subMenu;
function onNextTick () {
mainMenu.changeSize( subMenu.clientWidth );
subMenu.show();
subMenu.unslideAll();
}
mainMenu.hide();
mainMenu.slideAll();
mainMenu.parentElement.appendChild( subMenu );
scope.activeMainItem = this;
scope.activeSubMenu = subMenu;
window.requestAnimationFrame( onNextTick );
};
for ( let i = 0; i < menus.length; i++ ) {
const item = menu.addItem( menus[ i ].title );
item.style.paddingLeft = '20px';
item.addIcon()
.addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', onTap, false );
if ( menus[ i ].subMenu && menus[ i ].subMenu.length > 0 ) {
const title = menus[ i ].subMenu[ 0 ].title;
item.addSelection( title )
.addSubMenu( menus[ i ].title, menus[ i ].subMenu );
}
}
return menu;
},
/**
* Create sub menu
* @param {string} title - Sub menu title
* @param {array} items - Item array list
* @memberOf Widget
* @instance
* @return {HTMLElement} - A span element
*/
createSubMenu: function ( title, items ) {
let scope = this, menu, subMenu = this.createMenu();
subMenu.items = items;
subMenu.activeItem = null;
function onTap ( event ) {
event.preventDefault();
event.stopPropagation();
menu = scope.mainMenu;
menu.changeSize( menu._width );
menu.unslideAll();
menu.show();
subMenu.slideAll( true );
subMenu.hide();
if ( this.type !== 'header' ) {
subMenu.setActiveItem( this );
scope.activeMainItem.setSelectionTitle( this.textContent );
if ( this.handler ) { this.handler(); }
}
}
subMenu.addHeader( title ).addIcon( undefined, true, true ).addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', onTap, false );
for ( let i = 0; i < items.length; i++ ) {
const item = subMenu.addItem( items[ i ].title );
item.style.fontWeight = 300;
item.handler = items[ i ].handler;
item.addIcon( ' ', true );
item.addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', onTap, false );
if ( !subMenu.activeItem ) {
subMenu.setActiveItem( item );
}
}
subMenu.slideAll( true );
return subMenu;
},
/**
* Create general menu
* @memberOf Widget
* @instance
* @return {HTMLElement} - A span element
*/
createMenu: function () {
const scope = this;
const menu = document.createElement( 'span' );
const style = menu.style;
style.padding = '5px 0';
style.position = 'fixed';
style.bottom = '100%';
style.right = '14px';
style.backgroundColor = '#fafafa';
style.fontFamily = 'Helvetica Neue';
style.fontSize = '14px';
style.visibility = 'hidden';
style.opacity = 0;
style.boxShadow = '0 0 12pt rgba(0,0,0,0.25)';
style.borderRadius = '2px';
style.overflow = 'hidden';
style.willChange = 'width, height, opacity';
style.pointerEvents = 'auto';
style.transition = this.DEFAULT_TRANSITION;
menu.visible = false;
menu.changeSize = function ( width, height ) {
if ( width ) {
this.style.width = width + 'px';
}
if ( height ) {
this.style.height = height + 'px';
}
};
menu.show = function () {
this.style.opacity = 1;
this.style.visibility = 'visible';
this.visible = true;
};
menu.hide = function () {
this.style.opacity = 0;
this.style.visibility = 'hidden';
this.visible = false;
};
menu.toggle = function () {
if ( this.visible ) {
this.hide();
} else {
this.show();
}
};
menu.slideAll = function ( right ) {
for ( let i = 0; i < menu.children.length; i++ ){
if ( menu.children[ i ].slide ) {
menu.children[ i ].slide( right );
}
}
};
menu.unslideAll = function () {
for ( let i = 0; i < menu.children.length; i++ ){
if ( menu.children[ i ].unslide ) {
menu.children[ i ].unslide();
}
}
};
menu.addHeader = function ( title ) {
const header = scope.createMenuItemHeader( title );
header.type = 'header';
this.appendChild( header );
return header;
};
menu.addItem = function ( title ) {
const item = scope.createMenuItem( title );
item.type = 'item';
this.appendChild( item );
return item;
};
menu.setActiveItem = function ( item ) {
if ( this.activeItem ) {
this.activeItem.setIcon( ' ' );
}
item.setIcon( DataImage.Check );
this.activeItem = item;
};
menu.addEventListener( 'mousemove', this.PREVENT_EVENT_HANDLER, true );
menu.addEventListener( 'mouseup', this.PREVENT_EVENT_HANDLER, true );
menu.addEventListener( 'mousedown', this.PREVENT_EVENT_HANDLER, true );
return menu;
},
/**
* Create custom item element
* @memberOf Widget
* @instance
* @return {HTMLSpanElement} - The dom element icon
*/
createCustomItem: function ( options = {} ) {
const scope = this;
const item = options.element || document.createElement( 'span' );
const { onDispose } = options;
item.style.cursor = 'pointer';
item.style.float = 'right';
item.style.width = '44px';
item.style.height = '100%';
item.style.backgroundSize = '60%';
item.style.backgroundRepeat = 'no-repeat';
item.style.backgroundPosition = 'center';
item.style.webkitUserSelect =
item.style.MozUserSelect =
item.style.userSelect = 'none';
item.style.position = 'relative';
item.style.pointerEvents = 'auto';
// White glow on icon
item.addEventListener( scope.TOUCH_ENABLED ? 'touchstart' : 'mouseenter', function() {
item.style.filter =
item.style.webkitFilter = 'drop-shadow(0 0 5px rgba(255,255,255,1))';
}, { passive: true });
item.addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'mouseleave', function() {
item.style.filter =
item.style.webkitFilter = '';
}, { passive: true });
this.mergeStyleOptions( item, options.style );
if ( options.onTap ) {
item.addEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', options.onTap, false );
}
item.dispose = function () {
item.removeEventListener( scope.TOUCH_ENABLED ? 'touchend' : 'click', options.onTap, false );
if ( onDispose ) { options.onDispose(); }
};
return item;
},
/**
* Merge item css style
* @param {HTMLElement} element - The element to be merged with style
* @param {object} options - The style options
* @memberOf Widget
* @instance
* @return {HTMLElement} - The same element with merged styles
*/
mergeStyleOptions: function ( element, options = {} ) {
for ( let property in options ){
if ( options.hasOwnProperty( property ) ) {
element.style[ property ] = options[ property ];
}
}
return element;
},
/**
* Dispose widgets by detaching dom elements from container
* @memberOf Widget
* @instance
*/
dispose: function () {
if ( this.barElement ) {
this.container.removeChild( this.barElement );
this.barElement.dispose();
this.barElement = null;
}
}
} );
export { Widget };