2017-07-24 15:50:40 +02:00
/*! choices.js v2.8.10 | (c) 2017 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
2016-10-18 15:15:00 +02:00
( function webpackUniversalModuleDefinition ( root , factory ) {
if ( typeof exports === 'object' && typeof module === 'object' )
module . exports = factory ( ) ;
else if ( typeof define === 'function' && define . amd )
2016-10-28 22:59:43 +02:00
define ( [ ] , factory ) ;
2016-10-18 15:15:00 +02:00
else if ( typeof exports === 'object' )
exports [ "Choices" ] = factory ( ) ;
else
root [ "Choices" ] = factory ( ) ;
} ) ( this , function ( ) {
return /******/ ( function ( modules ) { // webpackBootstrap
2016-08-23 08:24:45 +02:00
/******/ // The module cache
/******/ var installedModules = { } ;
/******/ // The require function
/******/ function _ _webpack _require _ _ ( moduleId ) {
/******/ // Check if module is in cache
/******/ if ( installedModules [ moduleId ] )
/******/ return installedModules [ moduleId ] . exports ;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules [ moduleId ] = {
/******/ exports : { } ,
/******/ id : moduleId ,
/******/ loaded : false
/******/ } ;
/******/ // Execute the module function
/******/ modules [ moduleId ] . call ( module . exports , module , module . exports , _ _webpack _require _ _ ) ;
/******/ // Flag the module as loaded
/******/ module . loaded = true ;
/******/ // Return the exports of the module
/******/ return module . exports ;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ _ _webpack _require _ _ . m = modules ;
/******/ // expose the module cache
/******/ _ _webpack _require _ _ . c = installedModules ;
/******/ // __webpack_public_path__
/******/ _ _webpack _require _ _ . p = "/assets/scripts/dist/" ;
/******/ // Load entry module and return exports
/******/ return _ _webpack _require _ _ ( 0 ) ;
/******/ } )
/************************************************************************/
/******/ ( [
/* 0 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
module . exports = _ _webpack _require _ _ ( 1 ) ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2016-08-23 08:24:45 +02:00
/* 1 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
var _fuse = _ _webpack _require _ _ ( 2 ) ;
var _fuse2 = _interopRequireDefault ( _fuse ) ;
2017-06-27 13:42:01 +02:00
var _classnames = _ _webpack _require _ _ ( 3 ) ;
var _classnames2 = _interopRequireDefault ( _classnames ) ;
var _index = _ _webpack _require _ _ ( 4 ) ;
2016-08-23 08:24:45 +02:00
var _index2 = _interopRequireDefault ( _index ) ;
2017-06-27 13:42:01 +02:00
var _index3 = _ _webpack _require _ _ ( 30 ) ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _utils = _ _webpack _require _ _ ( 31 ) ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
_ _webpack _require _ _ ( 32 ) ;
2016-08-23 08:24:45 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
2016-09-04 16:23:19 +02:00
function _defineProperty ( obj , key , value ) { if ( key in obj ) { Object . defineProperty ( obj , key , { value : value , enumerable : true , configurable : true , writable : true } ) ; } else { obj [ key ] = value ; } return obj ; }
2016-08-23 08:24:45 +02:00
function _toConsumableArray ( arr ) { if ( Array . isArray ( arr ) ) { for ( var i = 0 , arr2 = Array ( arr . length ) ; i < arr . length ; i ++ ) { arr2 [ i ] = arr [ i ] ; } return arr2 ; } else { return Array . from ( arr ) ; } }
function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
2017-07-19 21:48:25 +02:00
/ * *
* Choices
2016-08-23 08:24:45 +02:00
* /
var Choices = function ( ) {
2016-09-05 23:31:20 +02:00
function Choices ( ) {
2016-10-26 16:43:15 +02:00
var element = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : '[data-choice]' ;
var userConfig = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : { } ;
2016-09-05 23:31:20 +02:00
_classCallCheck ( this , Choices ) ;
// If there are multiple elements, create a new instance
// for each element besides the first one (as that already has an instance)
if ( ( 0 , _utils . isType ) ( 'String' , element ) ) {
var elements = document . querySelectorAll ( element ) ;
if ( elements . length > 1 ) {
for ( var i = 1 ; i < elements . length ; i ++ ) {
var el = elements [ i ] ;
new Choices ( el , userConfig ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var defaultConfig = {
2017-05-18 18:57:35 +02:00
silent : false ,
2016-09-05 23:31:20 +02:00
items : [ ] ,
choices : [ ] ,
maxItemCount : - 1 ,
addItems : true ,
removeItems : true ,
removeItemButton : false ,
editItems : false ,
duplicateItems : true ,
delimiter : ',' ,
paste : true ,
2017-05-18 18:57:35 +02:00
searchEnabled : true ,
2017-04-06 15:42:11 +02:00
searchChoices : true ,
2016-09-29 15:16:28 +02:00
searchFloor : 1 ,
2017-06-27 17:39:08 +02:00
searchResultLimit : 4 ,
2017-04-07 09:51:41 +02:00
searchFields : [ 'label' , 'value' ] ,
2017-02-21 21:47:12 +01:00
position : 'auto' ,
2017-01-26 10:16:21 +01:00
resetScrollPosition : true ,
2016-09-05 23:31:20 +02:00
regexFilter : null ,
shouldSort : true ,
2017-07-11 07:36:10 +02:00
shouldSortItems : false ,
2016-09-05 23:31:20 +02:00
sortFilter : _utils . sortByAlpha ,
placeholder : true ,
placeholderValue : null ,
prependValue : null ,
appendValue : null ,
2017-07-11 07:36:10 +02:00
renderSelectedChoices : 'auto' ,
2016-09-05 23:31:20 +02:00
loadingText : 'Loading...' ,
2016-10-26 16:43:15 +02:00
noResultsText : 'No results found' ,
2016-09-05 23:31:20 +02:00
noChoicesText : 'No choices to choose from' ,
2016-09-26 11:36:04 +02:00
itemSelectText : 'Press to select' ,
2016-11-07 11:27:04 +01:00
addItemText : function addItemText ( value ) {
return 'Press Enter to add <b>"' + value + '"</b>' ;
} ,
maxItemText : function maxItemText ( maxItemCount ) {
return 'Only ' + maxItemCount + ' values can be added.' ;
} ,
uniqueItemText : 'Only unique values can be added.' ,
2016-09-05 23:31:20 +02:00
classNames : {
containerOuter : 'choices' ,
containerInner : 'choices__inner' ,
input : 'choices__input' ,
inputCloned : 'choices__input--cloned' ,
list : 'choices__list' ,
listItems : 'choices__list--multiple' ,
listSingle : 'choices__list--single' ,
listDropdown : 'choices__list--dropdown' ,
item : 'choices__item' ,
itemSelectable : 'choices__item--selectable' ,
itemDisabled : 'choices__item--disabled' ,
itemChoice : 'choices__item--choice' ,
placeholder : 'choices__placeholder' ,
group : 'choices__group' ,
groupHeading : 'choices__heading' ,
button : 'choices__button' ,
activeState : 'is-active' ,
focusState : 'is-focused' ,
openState : 'is-open' ,
disabledState : 'is-disabled' ,
highlightedState : 'is-highlighted' ,
hiddenState : 'is-hidden' ,
flippedState : 'is-flipped' ,
loadingState : 'is-loading'
} ,
2017-01-01 17:02:51 +01:00
fuseOptions : {
include : 'score'
} ,
2016-09-29 15:16:28 +02:00
callbackOnInit : null ,
2017-01-01 17:01:35 +01:00
callbackOnCreateTemplates : null
2016-09-05 23:31:20 +02:00
} ;
2016-09-04 23:23:20 +02:00
2017-06-02 22:34:07 +02:00
this . idNames = {
itemChoice : 'item-choice'
} ;
2016-09-05 23:31:20 +02:00
// Merge options with user options
this . config = ( 0 , _utils . extend ) ( defaultConfig , userConfig ) ;
2016-08-23 08:24:45 +02:00
2017-07-12 12:21:35 +02:00
if ( this . config . renderSelectedChoices !== 'auto' && this . config . renderSelectedChoices !== 'always' ) {
2017-07-11 07:36:10 +02:00
if ( ! this . config . silent ) {
2017-07-12 12:21:35 +02:00
console . warn ( 'renderSelectedChoices: Possible values are \'auto\' and \'always\'. Falling back to \'auto\'.' ) ;
2017-07-11 07:36:10 +02:00
}
this . config . renderSelectedChoices = 'auto' ;
}
2016-09-05 23:31:20 +02:00
// Create data store
this . store = new _index2 . default ( this . render ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// State tracking
this . initialised = false ;
this . currentState = { } ;
this . prevState = { } ;
this . currentValue = '' ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
2016-10-22 22:05:29 +02:00
this . element = element ;
2016-09-05 23:31:20 +02:00
this . passedElement = ( 0 , _utils . isType ) ( 'String' , element ) ? document . querySelector ( element ) : element ;
2016-10-26 16:43:15 +02:00
this . isTextElement = this . passedElement . type === 'text' ;
2017-07-13 17:00:51 +02:00
this . isSelectOneElement = this . passedElement . type === 'select-one' ;
this . isSelectMultipleElement = this . passedElement . type === 'select-multiple' ;
this . isSelectElement = this . isSelectOneElement || this . isSelectMultipleElement ;
this . isValidElementType = this . isTextElement || this . isSelectElement ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( ! this . passedElement ) {
2017-05-18 18:57:35 +02:00
if ( ! this . config . silent ) {
console . error ( 'Passed element not found' ) ;
}
2016-09-05 23:31:20 +02:00
return ;
}
2017-07-13 17:00:51 +02:00
if ( this . config . shouldSortItems === true && this . isSelectOneElement ) {
2017-07-11 07:36:10 +02:00
if ( ! this . config . silent ) {
console . warn ( 'shouldSortElements: Type of passed element is \'select-one\', falling back to false.' ) ;
}
}
2016-09-05 23:31:20 +02:00
this . highlightPosition = 0 ;
2017-05-18 18:57:35 +02:00
this . canSearch = this . config . searchEnabled ;
2016-09-05 23:31:20 +02:00
2017-07-11 07:36:10 +02:00
// Assign preset choices from passed object
2016-09-05 23:31:20 +02:00
this . presetChoices = this . config . choices ;
// Assign preset items from passed object first
this . presetItems = this . config . items ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Then add any values passed from attribute
if ( this . passedElement . value ) {
this . presetItems = this . presetItems . concat ( this . passedElement . value . split ( this . config . delimiter ) ) ;
}
2017-06-03 13:38:33 +02:00
// Set unique base Id
2017-06-02 22:34:07 +02:00
this . baseId = ( 0 , _utils . generateId ) ( this . passedElement , 'choices-' ) ;
2016-09-05 23:31:20 +02:00
// Bind methods
this . render = this . render . bind ( this ) ;
// Bind event handlers
this . _onFocus = this . _onFocus . bind ( this ) ;
this . _onBlur = this . _onBlur . bind ( this ) ;
this . _onKeyUp = this . _onKeyUp . bind ( this ) ;
this . _onKeyDown = this . _onKeyDown . bind ( this ) ;
this . _onClick = this . _onClick . bind ( this ) ;
this . _onTouchMove = this . _onTouchMove . bind ( this ) ;
this . _onTouchEnd = this . _onTouchEnd . bind ( this ) ;
this . _onMouseDown = this . _onMouseDown . bind ( this ) ;
this . _onMouseOver = this . _onMouseOver . bind ( this ) ;
this . _onPaste = this . _onPaste . bind ( this ) ;
this . _onInput = this . _onInput . bind ( this ) ;
// Monitor touch taps/scrolls
this . wasTap = true ;
// Cutting the mustard
2016-10-26 16:43:15 +02:00
var cuttingTheMustard = 'classList' in document . documentElement ;
2017-05-18 18:57:35 +02:00
if ( ! cuttingTheMustard && ! this . config . silent ) {
console . error ( 'Choices: Your browser doesn\'t support Choices' ) ;
}
2016-09-05 23:31:20 +02:00
2017-07-13 17:00:51 +02:00
var canInit = ( 0 , _utils . isElement ) ( this . passedElement ) && this . isValidElementType ;
2016-09-05 23:31:20 +02:00
if ( canInit ) {
2017-07-24 15:50:40 +02:00
// If element has already been initialised with Choices
2017-05-18 18:57:35 +02:00
if ( this . passedElement . getAttribute ( 'data-choice' ) === 'active' ) {
return ;
}
2016-09-05 23:31:20 +02:00
// Let's go
this . init ( ) ;
2017-05-18 18:57:35 +02:00
} else if ( ! this . config . silent ) {
2016-09-05 23:31:20 +02:00
console . error ( 'Incompatible input passed' ) ;
}
}
2016-09-04 16:23:19 +02:00
2017-07-19 21:48:25 +02:00
/ * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
= Public functions =
2016-09-29 15:16:28 +02:00
=== === === === === === === === === === === === === = * /
2017-07-19 21:48:25 +02:00
/ * *
* Initialise Choices
* @ return
* @ public
2016-09-05 23:31:20 +02:00
* /
_createClass ( Choices , [ {
key : 'init' ,
value : function init ( ) {
2017-05-18 18:57:35 +02:00
if ( this . initialised === true ) {
return ;
}
2016-09-05 23:31:20 +02:00
2016-10-19 08:35:42 +02:00
var callback = this . config . callbackOnInit ;
2016-09-05 23:31:20 +02:00
// Set initialise flag
this . initialised = true ;
// Create required elements
this . _createTemplates ( ) ;
// Generate input markup
this . _createInput ( ) ;
// Subscribe store to render method
this . store . subscribe ( this . render ) ;
// Render any items
this . render ( ) ;
// Trigger event listeners
this . _addEventListeners ( ) ;
// Run callback if it is a function
if ( callback ) {
if ( ( 0 , _utils . isType ) ( 'Function' , callback ) ) {
2016-11-07 11:37:47 +01:00
callback . call ( this ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
}
2017-07-19 21:48:25 +02:00
/ * *
* Destroy Choices and nullify values
* @ return
* @ public
2016-08-23 08:24:45 +02:00
* /
2016-09-05 23:31:20 +02:00
} , {
key : 'destroy' ,
value : function destroy ( ) {
2017-05-18 18:57:35 +02:00
if ( this . initialised === false ) {
return ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Remove all event listeners
this . _removeEventListeners ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Reinstate passed element
this . passedElement . classList . remove ( this . config . classNames . input , this . config . classNames . hiddenState ) ;
2016-10-22 22:05:29 +02:00
this . passedElement . removeAttribute ( 'tabindex' ) ;
2017-07-17 12:35:50 +02:00
// Recover original styles if any
var origStyle = this . passedElement . getAttribute ( 'data-choice-orig-style' ) ;
if ( Boolean ( origStyle ) ) {
this . passedElement . removeAttribute ( 'data-choice-orig-style' ) ;
this . passedElement . setAttribute ( 'style' , origStyle ) ;
2017-07-14 23:53:43 +02:00
} else {
this . passedElement . removeAttribute ( 'style' ) ;
}
2016-09-05 23:31:20 +02:00
this . passedElement . removeAttribute ( 'aria-hidden' ) ;
2017-07-13 17:00:51 +02:00
this . passedElement . removeAttribute ( 'data-choice' ) ;
2016-08-23 08:24:45 +02:00
2016-10-22 22:05:29 +02:00
// Re-assign values - this is weird, I know
this . passedElement . value = this . passedElement . value ;
2016-08-23 08:24:45 +02:00
2016-10-22 22:05:29 +02:00
// Move passed element back to original position
this . containerOuter . parentNode . insertBefore ( this . passedElement , this . containerOuter ) ;
// Remove added elements
this . containerOuter . parentNode . removeChild ( this . containerOuter ) ;
// Clear data store
this . clearStore ( ) ;
// Nullify instance-specific data
this . config . templates = null ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Uninitialise
this . initialised = false ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Render group choices into a DOM fragment and append to choice list
* @ param { Array } groups Groups to add to list
* @ param { Array } choices Choices to add to groups
* @ param { DocumentFragment } fragment Fragment to add groups and options to ( optional )
* @ return { DocumentFragment } Populated options fragment
* @ private
2016-09-29 15:16:28 +02:00
* /
} , {
key : 'renderGroups' ,
value : function renderGroups ( groups , choices , fragment ) {
2017-07-13 17:00:51 +02:00
var _this = this ;
2016-09-29 15:16:28 +02:00
var groupFragment = fragment || document . createDocumentFragment ( ) ;
var filter = this . config . sortFilter ;
// If sorting is enabled, filter groups
if ( this . config . shouldSort ) {
groups . sort ( filter ) ;
}
groups . forEach ( function ( group ) {
// Grab options that are children of this group
var groupChoices = choices . filter ( function ( choice ) {
2017-07-13 17:00:51 +02:00
if ( _this . isSelectOneElement ) {
2016-09-29 15:16:28 +02:00
return choice . groupId === group . id ;
}
return choice . groupId === group . id && ! choice . selected ;
} ) ;
if ( groupChoices . length >= 1 ) {
2017-07-13 17:00:51 +02:00
var dropdownGroup = _this . _getTemplate ( 'choiceGroup' , group ) ;
2016-09-29 15:16:28 +02:00
groupFragment . appendChild ( dropdownGroup ) ;
2017-07-13 17:00:51 +02:00
_this . renderChoices ( groupChoices , groupFragment ) ;
2016-09-29 15:16:28 +02:00
}
} ) ;
return groupFragment ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Render choices into a DOM fragment and append to choice list
* @ param { Array } choices Choices to add to list
* @ param { DocumentFragment } fragment Fragment to add choices to ( optional )
* @ return { DocumentFragment } Populated choices fragment
* @ private
2016-09-29 15:16:28 +02:00
* /
} , {
key : 'renderChoices' ,
value : function renderChoices ( choices , fragment ) {
2017-07-13 17:00:51 +02:00
var _this2 = this ;
2016-09-29 15:16:28 +02:00
// Create a fragment to store our list items (so we don't have to update the DOM for each item)
var choicesFragment = fragment || document . createDocumentFragment ( ) ;
var filter = this . isSearching ? _utils . sortByScore : this . config . sortFilter ;
2017-07-11 07:36:10 +02:00
var renderSelectedChoices = this . config . renderSelectedChoices ;
2017-06-27 17:39:08 +02:00
var appendChoice = function appendChoice ( choice ) {
2017-07-13 17:00:51 +02:00
var shouldRender = renderSelectedChoices === 'auto' ? _this2 . isSelectOneElement || ! choice . selected : true ;
2017-06-27 17:39:08 +02:00
if ( shouldRender ) {
2017-07-13 17:00:51 +02:00
var dropdownItem = _this2 . _getTemplate ( 'choice' , choice ) ;
2017-06-27 17:39:08 +02:00
choicesFragment . appendChild ( dropdownItem ) ;
}
} ;
2016-09-29 15:16:28 +02:00
// If sorting is enabled or the user is searching, filter choices
if ( this . config . shouldSort || this . isSearching ) {
choices . sort ( filter ) ;
}
2017-06-27 17:39:08 +02:00
if ( this . isSearching ) {
for ( var i = 0 ; i < this . config . searchResultLimit ; i ++ ) {
var choice = choices [ i ] ;
if ( choice ) {
appendChoice ( choice ) ;
}
2016-09-29 15:16:28 +02:00
}
2017-06-27 17:39:08 +02:00
} else {
choices . forEach ( function ( choice ) {
return appendChoice ( choice ) ;
} ) ;
}
2016-09-29 15:16:28 +02:00
return choicesFragment ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Render items into a DOM fragment and append to items list
* @ param { Array } items Items to add to list
* @ param { DocumentFragment } [ fragment ] Fragment to add items to ( optional )
* @ return
* @ private
2016-09-29 15:16:28 +02:00
* /
} , {
key : 'renderItems' ,
2017-07-13 17:00:51 +02:00
value : function renderItems ( items ) {
var _this3 = this ;
var fragment = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : null ;
2016-09-29 15:16:28 +02:00
// Create fragment to add elements to
var itemListFragment = fragment || document . createDocumentFragment ( ) ;
2017-07-11 07:36:10 +02:00
// If sorting is enabled, filter items
2017-07-13 17:00:51 +02:00
if ( this . config . shouldSortItems && ! this . isSelectOneElement ) {
2017-07-11 07:36:10 +02:00
items . sort ( this . config . sortFilter ) ;
}
2016-10-26 16:43:15 +02:00
if ( this . isTextElement ) {
2017-06-27 17:30:08 +02:00
// Simplify store data to just values
var itemsFiltered = this . store . getItemsReducedToValues ( items ) ;
2017-07-19 21:48:25 +02:00
var itemsFilteredString = itemsFiltered . join ( this . config . delimiter ) ;
// Update the value of the hidden input
this . passedElement . setAttribute ( 'value' , itemsFilteredString ) ;
this . passedElement . value = itemsFilteredString ;
2016-09-29 15:16:28 +02:00
} else {
2017-02-17 10:26:08 +01:00
var selectedOptionsFragment = document . createDocumentFragment ( ) ;
// Add each list item to list
items . forEach ( function ( item ) {
// Create a standard select option
2017-07-13 17:00:51 +02:00
var option = _this3 . _getTemplate ( 'option' , item ) ;
2017-02-17 10:26:08 +01:00
// Append it to fragment
selectedOptionsFragment . appendChild ( option ) ;
} ) ;
2016-09-29 15:16:28 +02:00
2017-02-17 10:26:08 +01:00
// Update selected choices
this . passedElement . innerHTML = '' ;
this . passedElement . appendChild ( selectedOptionsFragment ) ;
2016-09-29 15:16:28 +02:00
}
// Add each list item to list
items . forEach ( function ( item ) {
// Create new list element
2017-07-13 17:00:51 +02:00
var listItem = _this3 . _getTemplate ( 'item' , item ) ;
2016-09-29 15:16:28 +02:00
// Append it to list
itemListFragment . appendChild ( listItem ) ;
} ) ;
return itemListFragment ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Render DOM with values
* @ return
* @ private
2016-09-29 15:16:28 +02:00
* /
} , {
key : 'render' ,
value : function render ( ) {
this . currentState = this . store . getState ( ) ;
// Only render if our state has actually changed
if ( this . currentState !== this . prevState ) {
// Choices
if ( this . currentState . choices !== this . prevState . choices || this . currentState . groups !== this . prevState . groups ) {
2017-07-13 17:00:51 +02:00
if ( this . isSelectElement ) {
2016-09-29 15:16:28 +02:00
// Get active groups/choices
var activeGroups = this . store . getGroupsFilteredByActive ( ) ;
var activeChoices = this . store . getChoicesFilteredByActive ( ) ;
var choiceListFragment = document . createDocumentFragment ( ) ;
// Clear choices
this . choiceList . innerHTML = '' ;
2017-01-26 10:16:21 +01:00
2016-09-29 15:16:28 +02:00
// Scroll back to top of choices list
2017-01-26 10:16:21 +01:00
if ( this . config . resetScrollPosition ) {
this . choiceList . scrollTop = 0 ;
}
2016-09-29 15:16:28 +02:00
// If we have grouped options
if ( activeGroups . length >= 1 && this . isSearching !== true ) {
choiceListFragment = this . renderGroups ( activeGroups , activeChoices , choiceListFragment ) ;
} else if ( activeChoices . length >= 1 ) {
choiceListFragment = this . renderChoices ( activeChoices , choiceListFragment ) ;
}
2017-05-11 16:12:14 +02:00
var activeItems = this . store . getItemsFilteredByActive ( ) ;
var canAddItem = this . _canAddItem ( activeItems , this . input . value ) ;
// If we have choices to show
2016-09-29 15:16:28 +02:00
if ( choiceListFragment . childNodes && choiceListFragment . childNodes . length > 0 ) {
2017-05-11 16:12:14 +02:00
// ...and we can select them
if ( canAddItem . response ) {
// ...append them and highlight the first choice
this . choiceList . appendChild ( choiceListFragment ) ;
this . _highlightChoice ( ) ;
} else {
// ...otherwise show a notice
this . choiceList . appendChild ( this . _getTemplate ( 'notice' , canAddItem . notice ) ) ;
}
2016-09-29 15:16:28 +02:00
} else {
// Otherwise show a notice
2017-02-09 14:50:14 +01:00
var dropdownItem = void 0 ;
var notice = void 0 ;
if ( this . isSearching ) {
notice = ( 0 , _utils . isType ) ( 'Function' , this . config . noResultsText ) ? this . config . noResultsText ( ) : this . config . noResultsText ;
2017-05-11 16:12:14 +02:00
2017-02-09 14:50:14 +01:00
dropdownItem = this . _getTemplate ( 'notice' , notice ) ;
} else {
notice = ( 0 , _utils . isType ) ( 'Function' , this . config . noChoicesText ) ? this . config . noChoicesText ( ) : this . config . noChoicesText ;
2017-05-11 16:12:14 +02:00
2017-02-09 14:50:14 +01:00
dropdownItem = this . _getTemplate ( 'notice' , notice ) ;
}
2016-09-29 15:16:28 +02:00
this . choiceList . appendChild ( dropdownItem ) ;
}
}
}
// Items
if ( this . currentState . items !== this . prevState . items ) {
2017-05-11 16:12:14 +02:00
var _activeItems = this . store . getItemsFilteredByActive ( ) ;
if ( _activeItems ) {
2016-09-29 15:16:28 +02:00
// Create a fragment to store our list items
// (so we don't have to update the DOM for each item)
2017-05-11 16:12:14 +02:00
var itemListFragment = this . renderItems ( _activeItems ) ;
2016-09-29 15:16:28 +02:00
// Clear list
this . itemList . innerHTML = '' ;
// If we have items to add
if ( itemListFragment . childNodes ) {
// Update list
this . itemList . appendChild ( itemListFragment ) ;
}
}
}
this . prevState = this . currentState ;
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Select item ( a selected item can be deleted )
* @ param { Element } item Element to select
* @ param { Boolean } [ runEvent = true ] Whether to trigger 'highlightItem' event
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
} , {
key : 'highlightItem' ,
value : function highlightItem ( item ) {
2017-01-01 17:01:35 +01:00
var runEvent = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : true ;
2017-05-18 18:57:35 +02:00
if ( ! item ) {
2017-07-13 17:00:51 +02:00
return this ;
2017-05-18 18:57:35 +02:00
}
2016-09-05 23:31:20 +02:00
var id = item . id ;
2016-10-19 08:35:42 +02:00
var groupId = item . groupId ;
2017-01-01 17:01:35 +01:00
var group = groupId >= 0 ? this . store . getGroupById ( groupId ) : null ;
2016-09-05 23:31:20 +02:00
this . store . dispatch ( ( 0 , _index3 . highlightItem ) ( id , true ) ) ;
2017-01-01 17:01:35 +01:00
if ( runEvent ) {
if ( group && group . value ) {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'highlightItem' , {
id : id ,
value : item . value ,
2017-03-01 20:10:46 +01:00
label : item . label ,
2017-01-01 17:01:35 +01:00
groupValue : group . value
} ) ;
2016-09-05 23:31:20 +02:00
} else {
2017-01-01 17:01:35 +01:00
( 0 , _utils . triggerEvent ) ( this . passedElement , 'highlightItem' , {
id : id ,
2017-03-01 20:10:46 +01:00
value : item . value ,
label : item . label
2017-01-01 17:01:35 +01:00
} ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Deselect item
* @ param { Element } item Element to de - select
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
} , {
key : 'unhighlightItem' ,
value : function unhighlightItem ( item ) {
2017-05-18 18:57:35 +02:00
if ( ! item ) {
2017-07-13 17:00:51 +02:00
return this ;
2017-05-18 18:57:35 +02:00
}
2016-09-05 23:31:20 +02:00
var id = item . id ;
2016-10-19 08:35:42 +02:00
var groupId = item . groupId ;
2017-01-01 17:01:35 +01:00
var group = groupId >= 0 ? this . store . getGroupById ( groupId ) : null ;
2016-10-19 08:35:42 +02:00
2016-09-05 23:31:20 +02:00
this . store . dispatch ( ( 0 , _index3 . highlightItem ) ( id , false ) ) ;
2017-01-01 17:01:35 +01:00
if ( group && group . value ) {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'unhighlightItem' , {
id : id ,
value : item . value ,
2017-03-01 20:10:46 +01:00
label : item . label ,
2017-01-01 17:01:35 +01:00
groupValue : group . value
} ) ;
} else {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'unhighlightItem' , {
id : id ,
2017-03-01 20:10:46 +01:00
value : item . value ,
label : item . label
2017-01-01 17:01:35 +01:00
} ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Highlight items within store
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-31 20:18:46 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'highlightAll' ,
value : function highlightAll ( ) {
2017-07-13 17:00:51 +02:00
var _this4 = this ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var items = this . store . getItems ( ) ;
items . forEach ( function ( item ) {
2017-07-13 17:00:51 +02:00
_this4 . highlightItem ( item ) ;
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Deselect items within store
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'unhighlightAll' ,
value : function unhighlightAll ( ) {
2017-07-13 17:00:51 +02:00
var _this5 = this ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var items = this . store . getItems ( ) ;
items . forEach ( function ( item ) {
2017-07-13 17:00:51 +02:00
_this5 . unhighlightItem ( item ) ;
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Remove an item from the store by its value
* @ param { String } value Value to search for
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'removeItemsByValue' ,
value : function removeItemsByValue ( value ) {
2017-07-13 17:00:51 +02:00
var _this6 = this ;
2016-09-05 23:31:20 +02:00
if ( ! value || ! ( 0 , _utils . isType ) ( 'String' , value ) ) {
2017-07-13 17:00:51 +02:00
return this ;
2016-09-05 23:31:20 +02:00
}
var items = this . store . getItemsFilteredByActive ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
items . forEach ( function ( item ) {
if ( item . value === value ) {
2017-07-13 17:00:51 +02:00
_this6 . _removeItem ( item ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Remove all items from store array
* @ note Removed items are soft deleted
* @ param { Number } excludedId Optionally exclude item by ID
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'removeActiveItems' ,
value : function removeActiveItems ( excludedId ) {
2017-07-13 17:00:51 +02:00
var _this7 = this ;
2016-09-05 23:31:20 +02:00
var items = this . store . getItemsFilteredByActive ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
items . forEach ( function ( item ) {
if ( item . active && excludedId !== item . id ) {
2017-07-13 17:00:51 +02:00
_this7 . _removeItem ( item ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Remove all selected items from store
* @ note Removed items are soft deleted
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'removeHighlightedItems' ,
value : function removeHighlightedItems ( ) {
2017-07-13 17:00:51 +02:00
var _this8 = this ;
2016-09-05 23:31:20 +02:00
2017-01-01 17:01:35 +01:00
var runEvent = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : false ;
2016-09-20 13:57:44 +02:00
2016-09-05 23:31:20 +02:00
var items = this . store . getItemsFilteredByActive ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
items . forEach ( function ( item ) {
if ( item . highlighted && item . active ) {
2017-07-13 17:00:51 +02:00
_this8 . _removeItem ( item ) ;
2016-09-20 13:57:44 +02:00
// If this action was performed by the user
2017-01-01 17:01:35 +01:00
// trigger the event
if ( runEvent ) {
2017-07-13 17:00:51 +02:00
_this8 . _triggerChange ( item . value ) ;
2016-09-20 13:57:44 +02:00
}
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Show dropdown to user by adding active state class
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'showDropdown' ,
value : function showDropdown ( ) {
2016-10-26 16:43:15 +02:00
var focusInput = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : false ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var body = document . body ;
var html = document . documentElement ;
var winHeight = Math . max ( body . scrollHeight , body . offsetHeight , html . clientHeight , html . scrollHeight , html . offsetHeight ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . containerOuter . classList . add ( this . config . classNames . openState ) ;
this . containerOuter . setAttribute ( 'aria-expanded' , 'true' ) ;
this . dropdown . classList . add ( this . config . classNames . activeState ) ;
2017-03-28 15:42:35 +02:00
this . dropdown . setAttribute ( 'aria-expanded' , 'true' ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var dimensions = this . dropdown . getBoundingClientRect ( ) ;
2017-05-11 16:12:14 +02:00
var dropdownPos = Math . ceil ( dimensions . top + window . scrollY + this . dropdown . offsetHeight ) ;
2017-02-21 21:47:12 +01:00
2016-09-05 23:31:20 +02:00
// If flip is enabled and the dropdown bottom position is greater than the window height flip the dropdown.
2017-02-21 21:47:12 +01:00
var shouldFlip = false ;
if ( this . config . position === 'auto' ) {
shouldFlip = dropdownPos >= winHeight ;
} else if ( this . config . position === 'top' ) {
shouldFlip = true ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( shouldFlip ) {
this . containerOuter . classList . add ( this . config . classNames . flippedState ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Optionally focus the input if we have a search input
if ( focusInput && this . canSearch && document . activeElement !== this . input ) {
this . input . focus ( ) ;
}
2016-08-23 08:24:45 +02:00
2017-03-12 14:17:46 +01:00
( 0 , _utils . triggerEvent ) ( this . passedElement , 'showDropdown' , { } ) ;
2017-03-02 17:13:53 +01:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Hide dropdown from user
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'hideDropdown' ,
value : function hideDropdown ( ) {
2016-10-26 16:43:15 +02:00
var blurInput = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : false ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// A dropdown flips if it does not have space within the page
var isFlipped = this . containerOuter . classList . contains ( this . config . classNames . flippedState ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . containerOuter . classList . remove ( this . config . classNames . openState ) ;
this . containerOuter . setAttribute ( 'aria-expanded' , 'false' ) ;
this . dropdown . classList . remove ( this . config . classNames . activeState ) ;
2017-03-28 15:42:35 +02:00
this . dropdown . setAttribute ( 'aria-expanded' , 'false' ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( isFlipped ) {
this . containerOuter . classList . remove ( this . config . classNames . flippedState ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Optionally blur the input if we have a search input
if ( blurInput && this . canSearch && document . activeElement === this . input ) {
this . input . blur ( ) ;
}
2016-08-23 08:24:45 +02:00
2017-03-12 14:17:46 +01:00
( 0 , _utils . triggerEvent ) ( this . passedElement , 'hideDropdown' , { } ) ;
2017-03-02 17:13:53 +01:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Determine whether to hide or show dropdown based on its current state
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'toggleDropdown' ,
value : function toggleDropdown ( ) {
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
if ( hasActiveDropdown ) {
this . hideDropdown ( ) ;
} else {
this . showDropdown ( true ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get value ( s ) of input ( i . e . inputted items ( text ) or selected choices ( select ) )
* @ param { Boolean } valueOnly Get only values of selected items , otherwise return selected items
* @ return { Array / String } selected value ( select - one ) or array of selected items ( inputs & select - multiple )
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getValue' ,
value : function getValue ( ) {
2017-07-13 17:00:51 +02:00
var _this9 = this ;
2016-08-23 08:24:45 +02:00
2016-10-26 16:43:15 +02:00
var valueOnly = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : false ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var items = this . store . getItemsFilteredByActive ( ) ;
var selectedItems = [ ] ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
items . forEach ( function ( item ) {
2017-07-13 17:00:51 +02:00
if ( _this9 . isTextElement ) {
2016-09-05 23:31:20 +02:00
selectedItems . push ( valueOnly ? item . value : item ) ;
} else if ( item . active ) {
selectedItems . push ( valueOnly ? item . value : item ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
return selectedItems [ 0 ] ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return selectedItems ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Set value of input . If the input is a select box , a choice will be created and selected otherwise
* an item will created directly .
* @ param { Array } args Array of value objects or value strings
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'setValue' ,
value : function setValue ( args ) {
2017-07-13 17:00:51 +02:00
var _this10 = this ;
2016-09-05 23:31:20 +02:00
if ( this . initialised === true ) {
2017-02-17 10:26:08 +01:00
// Convert args to an iterable array
var values = [ ] . concat ( _toConsumableArray ( args ) ) ,
handleValue = function handleValue ( item ) {
var itemType = ( 0 , _utils . getType ) ( item ) ;
if ( itemType === 'Object' ) {
2017-05-18 18:57:35 +02:00
if ( ! item . value ) {
return ;
}
2017-02-17 10:26:08 +01:00
// If we are dealing with a select input, we need to create an option first
// that is then selected. For text inputs we can just add items normally.
2017-07-13 17:00:51 +02:00
if ( ! _this10 . isTextElement ) {
2017-07-19 19:48:46 +02:00
_this10 . _addChoice ( item . value , item . label , true , false , - 1 , item . customProperties , null ) ;
2017-02-17 10:26:08 +01:00
} else {
2017-07-19 19:48:46 +02:00
_this10 . _addItem ( item . value , item . label , item . id , undefined , item . customProperties , null ) ;
2016-08-23 08:24:45 +02:00
}
2017-02-17 10:26:08 +01:00
} else if ( itemType === 'String' ) {
2017-07-13 17:00:51 +02:00
if ( ! _this10 . isTextElement ) {
2017-07-19 19:48:46 +02:00
_this10 . _addChoice ( item , item , true , false , - 1 , null ) ;
2017-02-17 10:26:08 +01:00
} else {
2017-07-13 17:00:51 +02:00
_this10 . _addItem ( item ) ;
2017-02-17 10:26:08 +01:00
}
}
} ;
if ( values . length > 1 ) {
values . forEach ( function ( value ) {
handleValue ( value ) ;
2016-10-26 16:43:15 +02:00
} ) ;
2017-02-17 10:26:08 +01:00
} else {
handleValue ( values [ 0 ] ) ;
}
2016-09-05 23:31:20 +02:00
}
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Select value of select box via the value of an existing choice
* @ param { Array / String } value An array of strings of a single string
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'setValueByChoice' ,
value : function setValueByChoice ( value ) {
2017-07-13 17:00:51 +02:00
var _this11 = this ;
2016-09-05 23:31:20 +02:00
2017-07-13 17:00:51 +02:00
if ( ! this . isTextElement ) {
2017-02-17 10:26:08 +01:00
var choices = this . store . getChoices ( ) ;
// If only one value has been passed, convert to array
var choiceValue = ( 0 , _utils . isType ) ( 'Array' , value ) ? value : [ value ] ;
// Loop through each value and
choiceValue . forEach ( function ( val ) {
var foundChoice = choices . find ( function ( choice ) {
// Check 'value' property exists and the choice isn't already selected
return choice . value === val ;
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
if ( foundChoice ) {
if ( ! foundChoice . selected ) {
2017-07-19 19:48:46 +02:00
_this11 . _addItem ( foundChoice . value , foundChoice . label , foundChoice . id , foundChoice . groupId , foundChoice . customProperties , foundChoice . keyCode ) ;
2017-07-13 17:00:51 +02:00
} else if ( ! _this11 . config . silent ) {
2017-02-17 10:26:08 +01:00
console . warn ( 'Attempting to select choice already selected' ) ;
2016-08-23 08:24:45 +02:00
}
2017-07-13 17:00:51 +02:00
} else if ( ! _this11 . config . silent ) {
2017-02-17 10:26:08 +01:00
console . warn ( 'Attempting to select choice that does not exist' ) ;
}
} ) ;
2016-09-05 23:31:20 +02:00
}
return this ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Direct populate choices
* @ param { Array } choices - Choices to insert
* @ param { String } value - Name of 'value' property
* @ param { String } label - Name of 'label' property
* @ param { Boolean } replaceChoices Whether existing choices should be removed
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'setChoices' ,
value : function setChoices ( choices , value , label ) {
2017-07-13 17:00:51 +02:00
var _this12 = this ;
2016-09-05 23:31:20 +02:00
2016-10-26 16:43:15 +02:00
var replaceChoices = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : false ;
2016-10-19 08:35:42 +02:00
2016-09-05 23:31:20 +02:00
if ( this . initialised === true ) {
2016-10-26 16:43:15 +02:00
if ( this . isSelectElement ) {
2017-05-18 18:57:35 +02:00
if ( ! ( 0 , _utils . isType ) ( 'Array' , choices ) || ! value ) {
2017-07-13 17:00:51 +02:00
return this ;
2017-05-18 18:57:35 +02:00
}
2016-10-19 08:35:42 +02:00
// Clear choices if needed
if ( replaceChoices ) {
this . _clearChoices ( ) ;
}
// Add choices if passed
2016-09-05 23:31:20 +02:00
if ( choices && choices . length ) {
this . containerOuter . classList . remove ( this . config . classNames . loadingState ) ;
2017-07-13 17:00:51 +02:00
choices . forEach ( function ( result ) {
2016-09-05 23:31:20 +02:00
if ( result . choices ) {
2017-07-13 17:00:51 +02:00
_this12 . _addGroup ( result , result . id || null , value , label ) ;
2016-09-05 23:31:20 +02:00
} else {
2017-07-19 19:48:46 +02:00
_this12 . _addChoice ( result [ value ] , result [ label ] , result . selected , result . disabled , undefined , result [ 'customProperties' ] , null ) ;
2016-09-05 23:31:20 +02:00
}
} ) ;
}
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Clear items , choices and groups
* @ note Hard delete
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'clearStore' ,
value : function clearStore ( ) {
this . store . dispatch ( ( 0 , _index3 . clearAll ) ( ) ) ;
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Set value of input to blank
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'clearInput' ,
value : function clearInput ( ) {
2017-07-13 17:00:51 +02:00
if ( this . input . value ) {
this . input . value = '' ;
}
if ( ! this . isSelectOneElement ) {
2016-10-22 22:05:29 +02:00
this . _setInputWidth ( ) ;
2016-09-05 23:31:20 +02:00
}
2017-07-13 17:00:51 +02:00
if ( ! this . isTextElement && this . config . searchEnabled ) {
2016-09-05 23:31:20 +02:00
this . isSearching = false ;
this . store . dispatch ( ( 0 , _index3 . activateChoices ) ( true ) ) ;
}
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Enable interaction with Choices
* @ return { Object } Class instance
2016-09-29 15:16:28 +02:00
* /
} , {
key : 'enable' ,
value : function enable ( ) {
this . passedElement . disabled = false ;
var isDisabled = this . containerOuter . classList . contains ( this . config . classNames . disabledState ) ;
if ( this . initialised && isDisabled ) {
this . _addEventListeners ( ) ;
this . passedElement . removeAttribute ( 'disabled' ) ;
this . input . removeAttribute ( 'disabled' ) ;
this . containerOuter . classList . remove ( this . config . classNames . disabledState ) ;
this . containerOuter . removeAttribute ( 'aria-disabled' ) ;
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2017-04-06 15:42:11 +02:00
this . containerOuter . setAttribute ( 'tabindex' , '0' ) ;
}
2016-09-29 15:16:28 +02:00
}
return this ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Disable interaction with Choices
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'disable' ,
value : function disable ( ) {
this . passedElement . disabled = true ;
var isEnabled = ! this . containerOuter . classList . contains ( this . config . classNames . disabledState ) ;
if ( this . initialised && isEnabled ) {
this . _removeEventListeners ( ) ;
this . passedElement . setAttribute ( 'disabled' , '' ) ;
this . input . setAttribute ( 'disabled' , '' ) ;
this . containerOuter . classList . add ( this . config . classNames . disabledState ) ;
this . containerOuter . setAttribute ( 'aria-disabled' , 'true' ) ;
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2017-04-06 15:42:11 +02:00
this . containerOuter . setAttribute ( 'tabindex' , '-1' ) ;
}
2016-09-05 23:31:20 +02:00
}
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Populate options via ajax callback
* @ param { Function } fn Function that actually makes an AJAX request
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'ajax' ,
value : function ajax ( fn ) {
2017-07-13 17:00:51 +02:00
var _this13 = this ;
2017-06-27 17:30:08 +02:00
2016-09-05 23:31:20 +02:00
if ( this . initialised === true ) {
2016-10-26 16:43:15 +02:00
if ( this . isSelectElement ) {
2016-09-27 10:11:22 +02:00
// Show loading text
2017-06-27 17:30:08 +02:00
requestAnimationFrame ( function ( ) {
2017-07-13 17:00:51 +02:00
_this13 . _handleLoadingState ( true ) ;
2017-06-27 17:30:08 +02:00
} ) ;
2016-09-29 15:16:28 +02:00
// Run callback
fn ( this . _ajaxCallback ( ) ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
return this ;
}
2016-08-23 08:24:45 +02:00
2016-09-29 15:16:28 +02:00
/*===== End of Public functions ======*/
2017-07-19 21:48:25 +02:00
/ * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
= Private functions =
2016-09-29 15:16:28 +02:00
=== === === === === === === === === === === === === === === * /
2017-07-19 21:48:25 +02:00
/ * *
* Call change callback
* @ param { String } value - last added / deleted / selected value
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_triggerChange' ,
value : function _triggerChange ( value ) {
2017-05-18 18:57:35 +02:00
if ( ! value ) {
return ;
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
( 0 , _utils . triggerEvent ) ( this . passedElement , 'change' , {
value : value
} ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Process enter / click of an item button
* @ param { Array } activeItems The currently active items
* @ param { Element } element Button being interacted with
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_handleButtonAction' ,
value : function _handleButtonAction ( activeItems , element ) {
2017-05-18 18:57:35 +02:00
if ( ! activeItems || ! element ) {
return ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If we are clicking on a button
if ( this . config . removeItems && this . config . removeItemButton ) {
2017-02-17 10:26:08 +01:00
var itemId = element . parentNode . getAttribute ( 'data-id' ) ;
var itemToRemove = activeItems . find ( function ( item ) {
return item . id === parseInt ( itemId , 10 ) ;
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
// Remove item associated with button
this . _removeItem ( itemToRemove ) ;
this . _triggerChange ( itemToRemove . value ) ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2017-02-17 10:26:08 +01:00
var placeholder = this . config . placeholder ? this . config . placeholderValue || this . passedElement . getAttribute ( 'placeholder' ) : false ;
if ( placeholder ) {
var placeholderItem = this . _getTemplate ( 'placeholder' , placeholder ) ;
this . itemList . appendChild ( placeholderItem ) ;
2016-09-05 23:31:20 +02:00
}
2017-02-17 10:26:08 +01:00
}
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Process click of an item
* @ param { Array } activeItems The currently active items
* @ param { Element } element Item being interacted with
* @ param { Boolean } hasShiftKey Whether the user has the shift key active
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_handleItemAction' ,
value : function _handleItemAction ( activeItems , element ) {
2017-07-13 17:00:51 +02:00
var _this14 = this ;
2016-09-05 23:31:20 +02:00
2016-10-26 16:43:15 +02:00
var hasShiftKey = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : false ;
2016-09-05 23:31:20 +02:00
2017-05-18 18:57:35 +02:00
if ( ! activeItems || ! element ) {
return ;
}
2016-09-05 23:31:20 +02:00
// If we are clicking on an item
2017-07-13 17:00:51 +02:00
if ( this . config . removeItems && ! this . isSelectOneElement ) {
2017-02-17 10:26:08 +01:00
var passedId = element . getAttribute ( 'data-id' ) ;
// We only want to select one item with a click
// so we deselect any items that aren't the target
// unless shift is being pressed
activeItems . forEach ( function ( item ) {
if ( item . id === parseInt ( passedId , 10 ) && ! item . highlighted ) {
2017-07-13 17:00:51 +02:00
_this14 . highlightItem ( item ) ;
2017-02-17 10:26:08 +01:00
} else if ( ! hasShiftKey ) {
if ( item . highlighted ) {
2017-07-13 17:00:51 +02:00
_this14 . unhighlightItem ( item ) ;
2016-08-23 08:24:45 +02:00
}
2017-02-17 10:26:08 +01:00
}
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
// Focus input as without focus, a user cannot do anything with a
// highlighted item
2017-05-29 12:12:48 +02:00
if ( document . activeElement !== this . input ) {
this . input . focus ( ) ;
}
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Process click of a choice
* @ param { Array } activeItems The currently active items
* @ param { Element } element Choice being interacted with
* @ return
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_handleChoiceAction' ,
value : function _handleChoiceAction ( activeItems , element ) {
2017-05-18 18:57:35 +02:00
if ( ! activeItems || ! element ) {
return ;
}
2016-09-05 23:31:20 +02:00
// If we are clicking on an option
var id = element . getAttribute ( 'data-id' ) ;
var choice = this . store . getChoiceById ( id ) ;
2017-07-20 13:06:32 +02:00
var passedKeyCode = activeItems [ 0 ] && activeItems [ 0 ] . keyCode ? activeItems [ 0 ] . keyCode : null ;
2016-09-05 23:31:20 +02:00
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
2017-07-19 19:48:46 +02:00
// Update choice keyCode
choice . keyCode = passedKeyCode ;
2017-03-28 15:42:35 +02:00
( 0 , _utils . triggerEvent ) ( this . passedElement , 'choice' , {
choice : choice
} ) ;
2016-09-05 23:31:20 +02:00
if ( choice && ! choice . selected && ! choice . disabled ) {
var canAddItem = this . _canAddItem ( activeItems , choice . value ) ;
if ( canAddItem . response ) {
2017-07-19 19:48:46 +02:00
this . _addItem ( choice . value , choice . label , choice . id , choice . groupId , choice . customProperties , choice . keyCode ) ;
2016-09-05 23:31:20 +02:00
this . _triggerChange ( choice . value ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
this . clearInput ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// We wont to close the dropdown if we are dealing with a single select box
2017-07-13 17:00:51 +02:00
if ( hasActiveDropdown && this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
this . hideDropdown ( ) ;
this . containerOuter . focus ( ) ;
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Process back space event
* @ param { Array } activeItems items
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
} , {
key : '_handleBackspace' ,
value : function _handleBackspace ( activeItems ) {
if ( this . config . removeItems && activeItems ) {
var lastItem = activeItems [ activeItems . length - 1 ] ;
var hasHighlightedItems = activeItems . some ( function ( item ) {
2017-06-27 17:30:08 +02:00
return item . highlighted ;
2016-09-05 23:31:20 +02:00
} ) ;
// If editing the last item is allowed and there are not other selected items,
// we can edit the item value. Otherwise if we can remove items, remove all selected items
if ( this . config . editItems && ! hasHighlightedItems && lastItem ) {
this . input . value = lastItem . value ;
2016-10-22 22:05:29 +02:00
this . _setInputWidth ( ) ;
2016-09-05 23:31:20 +02:00
this . _removeItem ( lastItem ) ;
this . _triggerChange ( lastItem . value ) ;
} else {
if ( ! hasHighlightedItems ) {
2017-01-01 17:01:35 +01:00
this . highlightItem ( lastItem , false ) ;
2016-09-05 23:31:20 +02:00
}
2016-09-20 13:57:44 +02:00
this . removeHighlightedItems ( true ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Validates whether an item can be added by a user
* @ param { Array } activeItems The currently active items
* @ param { String } value Value of item to add
* @ return { Object } Response : Whether user can add item
* Notice : Notice show in dropdown
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_canAddItem' ,
value : function _canAddItem ( activeItems , value ) {
var canAddItem = true ;
2016-11-07 11:27:04 +01:00
var notice = ( 0 , _utils . isType ) ( 'Function' , this . config . addItemText ) ? this . config . addItemText ( value ) : this . config . addItemText ;
2016-09-05 23:31:20 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectMultipleElement || this . isTextElement ) {
2017-05-11 16:12:14 +02:00
if ( this . config . maxItemCount > 0 && this . config . maxItemCount <= activeItems . length ) {
2016-09-05 23:31:20 +02:00
// If there is a max entry limit and we have reached that limit
// don't update
canAddItem = false ;
2016-11-07 11:27:04 +01:00
notice = ( 0 , _utils . isType ) ( 'Function' , this . config . maxItemText ) ? this . config . maxItemText ( this . config . maxItemCount ) : this . config . maxItemText ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isTextElement && this . config . addItems && canAddItem ) {
2016-09-05 23:31:20 +02:00
// If a user has supplied a regular expression filter
if ( this . config . regexFilter ) {
// Determine whether we can update based on whether
// our regular expression passes
canAddItem = this . _regexFilter ( value ) ;
}
2017-05-18 18:57:35 +02:00
}
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
// If no duplicates are allowed, and the value already exists
// in the array
var isUnique = ! activeItems . some ( function ( item ) {
2017-06-27 17:30:08 +02:00
if ( ( 0 , _utils . isType ) ( 'String' , value ) ) {
return item . value === value . trim ( ) ;
}
return item . value === value ;
2017-05-18 18:57:35 +02:00
} ) ;
2017-07-13 17:00:51 +02:00
if ( ! isUnique && ! this . config . duplicateItems && ! this . isSelectOneElement && canAddItem ) {
2017-05-18 18:57:35 +02:00
canAddItem = false ;
notice = ( 0 , _utils . isType ) ( 'Function' , this . config . uniqueItemText ) ? this . config . uniqueItemText ( value ) : this . config . uniqueItemText ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return {
response : canAddItem ,
notice : notice
} ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Apply or remove a loading state to the component .
* @ param { Boolean } isLoading default value set to 'true' .
* @ return
* @ private
2016-09-27 10:11:22 +02:00
* /
} , {
key : '_handleLoadingState' ,
value : function _handleLoadingState ( ) {
2016-10-26 16:43:15 +02:00
var isLoading = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : true ;
2016-09-27 10:11:22 +02:00
2016-09-29 15:16:28 +02:00
var placeholderItem = this . itemList . querySelector ( '.' + this . config . classNames . placeholder ) ;
2016-09-27 10:11:22 +02:00
if ( isLoading ) {
this . containerOuter . classList . add ( this . config . classNames . loadingState ) ;
this . containerOuter . setAttribute ( 'aria-busy' , 'true' ) ;
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-29 15:16:28 +02:00
if ( ! placeholderItem ) {
placeholderItem = this . _getTemplate ( 'placeholder' , this . config . loadingText ) ;
this . itemList . appendChild ( placeholderItem ) ;
} else {
placeholderItem . innerHTML = this . config . loadingText ;
}
2016-09-27 10:11:22 +02:00
} else {
this . input . placeholder = this . config . loadingText ;
}
} else {
// Remove loading states/text
this . containerOuter . classList . remove ( this . config . classNames . loadingState ) ;
2016-09-29 15:16:28 +02:00
var placeholder = this . config . placeholder ? this . config . placeholderValue || this . passedElement . getAttribute ( 'placeholder' ) : false ;
2017-06-27 17:30:08 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-29 15:16:28 +02:00
placeholderItem . innerHTML = placeholder || '' ;
} else {
2016-09-27 10:11:22 +02:00
this . input . placeholder = placeholder || '' ;
}
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Retrieve the callback used to populate component ' s choices in an async way .
* @ returns { Function } The callback as a function .
* @ private
2016-09-27 10:11:22 +02:00
* /
} , {
2016-09-29 15:16:28 +02:00
key : '_ajaxCallback' ,
value : function _ajaxCallback ( ) {
2017-07-13 17:00:51 +02:00
var _this15 = this ;
2016-09-27 10:11:22 +02:00
return function ( results , value , label ) {
2017-05-18 18:57:35 +02:00
if ( ! results || ! value ) {
return ;
}
2017-02-10 10:02:10 +01:00
2016-09-29 15:16:28 +02:00
var parsedResults = ( 0 , _utils . isType ) ( 'Object' , results ) ? [ results ] : results ;
if ( parsedResults && ( 0 , _utils . isType ) ( 'Array' , parsedResults ) && parsedResults . length ) {
2016-09-27 10:11:22 +02:00
// Remove loading states/text
2017-07-13 17:00:51 +02:00
_this15 . _handleLoadingState ( false ) ;
2016-09-27 10:11:22 +02:00
// Add each result as a choice
2017-07-13 17:00:51 +02:00
parsedResults . forEach ( function ( result ) {
2016-10-10 14:17:35 +02:00
if ( result . choices ) {
2017-06-27 17:30:08 +02:00
var groupId = result . id || null ;
2017-07-13 17:00:51 +02:00
_this15 . _addGroup ( result , groupId , value , label ) ;
2016-10-10 14:17:35 +02:00
} else {
2017-07-19 19:48:46 +02:00
_this15 . _addChoice ( result [ value ] , result [ label ] , result . selected , result . disabled , undefined , result [ 'customProperties' ] , null ) ;
2016-10-10 14:17:35 +02:00
}
2016-09-27 10:11:22 +02:00
} ) ;
2017-02-10 10:02:10 +01:00
} else {
// No results, remove loading state
2017-07-13 17:00:51 +02:00
_this15 . _handleLoadingState ( false ) ;
2016-09-27 10:11:22 +02:00
}
2017-02-10 10:02:10 +01:00
2017-07-13 17:00:51 +02:00
_this15 . containerOuter . removeAttribute ( 'aria-busy' ) ;
2016-09-27 10:11:22 +02:00
} ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Filter choices based on search value
* @ param { String } value Value to filter by
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_searchChoices' ,
value : function _searchChoices ( value ) {
2016-09-29 15:16:28 +02:00
var newValue = ( 0 , _utils . isType ) ( 'String' , value ) ? value . trim ( ) : value ;
var currentValue = ( 0 , _utils . isType ) ( 'String' , this . currentValue ) ? this . currentValue . trim ( ) : this . currentValue ;
// If new value matches the desired length and is not the same as the current value with a space
if ( newValue . length >= 1 && newValue !== currentValue + ' ' ) {
var haystack = this . store . getChoicesFilteredBySelectable ( ) ;
var needle = newValue ;
2017-04-07 09:49:15 +02:00
var keys = ( 0 , _utils . isType ) ( 'Array' , this . config . searchFields ) ? this . config . searchFields : [ this . config . searchFields ] ;
2017-01-01 17:02:51 +01:00
var options = Object . assign ( this . config . fuseOptions , { keys : keys } ) ;
var fuse = new _fuse2 . default ( haystack , options ) ;
2016-09-29 15:16:28 +02:00
var results = fuse . search ( needle ) ;
2017-01-01 17:02:51 +01:00
2016-09-29 15:16:28 +02:00
this . currentValue = newValue ;
this . highlightPosition = 0 ;
this . isSearching = true ;
this . store . dispatch ( ( 0 , _index3 . filterChoices ) ( results ) ) ;
}
}
2016-09-05 14:48:51 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Determine the action when a user is searching
* @ param { String } value Value entered by user
* @ return
* @ private
2016-09-29 15:16:28 +02:00
* /
} , {
key : '_handleSearch' ,
value : function _handleSearch ( value ) {
2017-05-18 18:57:35 +02:00
if ( ! value ) {
return ;
}
2016-09-29 15:16:28 +02:00
var choices = this . store . getChoices ( ) ;
var hasUnactiveChoices = choices . some ( function ( option ) {
2017-06-27 17:30:08 +02:00
return ! option . active ;
2016-09-29 15:16:28 +02:00
} ) ;
2016-09-27 10:11:22 +02:00
// Run callback if it is a function
2016-09-29 15:16:28 +02:00
if ( this . input === document . activeElement ) {
// Check that we have a value to search and the input was an alphanumeric character
2017-05-18 18:57:35 +02:00
if ( value && value . length >= this . config . searchFloor ) {
2017-04-06 15:42:11 +02:00
// Check flag to filter search input
if ( this . config . searchChoices ) {
// Filter available choices
this . _searchChoices ( value ) ;
}
2017-01-01 17:01:35 +01:00
// Trigger search event
( 0 , _utils . triggerEvent ) ( this . passedElement , 'search' , {
value : value
} ) ;
2016-09-29 15:16:28 +02:00
} else if ( hasUnactiveChoices ) {
// Otherwise reset choices to active
this . isSearching = false ;
this . store . dispatch ( ( 0 , _index3 . activateChoices ) ( true ) ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Trigger event listeners
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_addEventListeners' ,
value : function _addEventListeners ( ) {
document . addEventListener ( 'keyup' , this . _onKeyUp ) ;
document . addEventListener ( 'keydown' , this . _onKeyDown ) ;
document . addEventListener ( 'click' , this . _onClick ) ;
document . addEventListener ( 'touchmove' , this . _onTouchMove ) ;
document . addEventListener ( 'touchend' , this . _onTouchEnd ) ;
document . addEventListener ( 'mousedown' , this . _onMouseDown ) ;
document . addEventListener ( 'mouseover' , this . _onMouseOver ) ;
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
this . containerOuter . addEventListener ( 'focus' , this . _onFocus ) ;
this . containerOuter . addEventListener ( 'blur' , this . _onBlur ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . input . addEventListener ( 'input' , this . _onInput ) ;
this . input . addEventListener ( 'paste' , this . _onPaste ) ;
this . input . addEventListener ( 'focus' , this . _onFocus ) ;
this . input . addEventListener ( 'blur' , this . _onBlur ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Remove event listeners
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_removeEventListeners' ,
value : function _removeEventListeners ( ) {
document . removeEventListener ( 'keyup' , this . _onKeyUp ) ;
document . removeEventListener ( 'keydown' , this . _onKeyDown ) ;
document . removeEventListener ( 'click' , this . _onClick ) ;
document . removeEventListener ( 'touchmove' , this . _onTouchMove ) ;
document . removeEventListener ( 'touchend' , this . _onTouchEnd ) ;
document . removeEventListener ( 'mousedown' , this . _onMouseDown ) ;
document . removeEventListener ( 'mouseover' , this . _onMouseOver ) ;
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
this . containerOuter . removeEventListener ( 'focus' , this . _onFocus ) ;
this . containerOuter . removeEventListener ( 'blur' , this . _onBlur ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . input . removeEventListener ( 'input' , this . _onInput ) ;
this . input . removeEventListener ( 'paste' , this . _onPaste ) ;
this . input . removeEventListener ( 'focus' , this . _onFocus ) ;
this . input . removeEventListener ( 'blur' , this . _onBlur ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Set the correct input width based on placeholder
* value or input value
* @ return
2016-10-22 22:05:29 +02:00
* /
} , {
key : '_setInputWidth' ,
value : function _setInputWidth ( ) {
2017-05-29 12:12:48 +02:00
if ( this . config . placeholderValue || this . passedElement . getAttribute ( 'placeholder' ) && this . config . placeholder ) {
2016-10-22 22:05:29 +02:00
// If there is a placeholder, we only want to set the width of the input when it is a greater
// length than 75% of the placeholder. This stops the input jumping around.
var placeholder = this . config . placeholder ? this . config . placeholderValue || this . passedElement . getAttribute ( 'placeholder' ) : false ;
if ( this . input . value && this . input . value . length >= placeholder . length / 1.25 ) {
this . input . style . width = ( 0 , _utils . getWidthOfInput ) ( this . input ) ;
}
} else {
// If there is no placeholder, resize input to contents
this . input . style . width = ( 0 , _utils . getWidthOfInput ) ( this . input ) ;
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Key down event
* @ param { Object } e Event
* @ return
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onKeyDown' ,
value : function _onKeyDown ( e ) {
2017-07-13 17:00:51 +02:00
var _this16 = this ,
2016-09-05 23:31:20 +02:00
_keyDownActions ;
2017-05-18 18:57:35 +02:00
if ( e . target !== this . input && ! this . containerOuter . contains ( e . target ) ) {
return ;
}
2016-09-05 23:31:20 +02:00
var target = e . target ;
var activeItems = this . store . getItemsFilteredByActive ( ) ;
var hasFocusedInput = this . input === document . activeElement ;
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
var hasItems = this . itemList && this . itemList . children ;
var keyString = String . fromCharCode ( e . keyCode ) ;
var backKey = 46 ;
var deleteKey = 8 ;
var enterKey = 13 ;
var aKey = 65 ;
var escapeKey = 27 ;
var upKey = 38 ;
var downKey = 40 ;
2017-01-26 10:16:21 +01:00
var pageUpKey = 33 ;
var pageDownKey = 34 ;
2016-09-05 23:31:20 +02:00
var ctrlDownKey = e . ctrlKey || e . metaKey ;
// If a user is typing and the dropdown is not active
2017-07-13 17:00:51 +02:00
if ( ! this . isTextElement && /[a-zA-Z0-9-_ ]/ . test ( keyString ) && ! hasActiveDropdown ) {
2016-09-05 23:31:20 +02:00
this . showDropdown ( true ) ;
}
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
this . canSearch = this . config . searchEnabled ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var onAKey = function onAKey ( ) {
// If CTRL + A or CMD + A have been pressed and there are items to select
if ( ctrlDownKey && hasItems ) {
2017-07-13 17:00:51 +02:00
_this16 . canSearch = false ;
if ( _this16 . config . removeItems && ! _this16 . input . value && _this16 . input === document . activeElement ) {
2016-09-05 23:31:20 +02:00
// Highlight items
2017-07-13 17:00:51 +02:00
_this16 . highlightAll ( ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var onEnterKey = function onEnterKey ( ) {
// If enter key is pressed and the input has a value
2017-07-13 17:00:51 +02:00
if ( _this16 . isTextElement && target . value ) {
var value = _this16 . input . value ;
var canAddItem = _this16 . _canAddItem ( activeItems , value ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// All is good, add
if ( canAddItem . response ) {
if ( hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this16 . hideDropdown ( ) ;
2016-08-23 08:24:45 +02:00
}
2017-07-13 17:00:51 +02:00
_this16 . _addItem ( value ) ;
_this16 . _triggerChange ( value ) ;
_this16 . clearInput ( ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( target . hasAttribute ( 'data-button' ) ) {
2017-07-13 17:00:51 +02:00
_this16 . _handleButtonAction ( activeItems , target ) ;
2016-09-05 23:31:20 +02:00
e . preventDefault ( ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
if ( hasActiveDropdown ) {
2016-11-28 14:12:45 +01:00
e . preventDefault ( ) ;
2017-07-13 17:00:51 +02:00
var highlighted = _this16 . dropdown . querySelector ( '.' + _this16 . config . classNames . highlightedState ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If we have a highlighted choice
if ( highlighted ) {
2017-07-19 19:48:46 +02:00
// add enter keyCode value
2017-07-20 13:06:32 +02:00
if ( activeItems [ 0 ] ) {
activeItems [ 0 ] . keyCode = enterKey ;
}
2017-07-13 17:00:51 +02:00
_this16 . _handleChoiceAction ( activeItems , highlighted ) ;
2016-09-05 23:31:20 +02:00
}
2017-07-13 17:00:51 +02:00
} else if ( _this16 . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
// Open single select dropdown if it's not active
if ( ! hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this16 . showDropdown ( true ) ;
2016-09-05 23:31:20 +02:00
e . preventDefault ( ) ;
}
}
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var onEscapeKey = function onEscapeKey ( ) {
if ( hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this16 . toggleDropdown ( ) ;
_this16 . containerOuter . focus ( ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var onDirectionKey = function onDirectionKey ( ) {
// If up or down key is pressed, traverse through options
2017-07-13 17:00:51 +02:00
if ( hasActiveDropdown || _this16 . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
// Show dropdown if focus
if ( ! hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this16 . showDropdown ( true ) ;
2016-09-05 23:31:20 +02:00
}
2017-07-13 17:00:51 +02:00
_this16 . canSearch = false ;
2016-09-05 23:31:20 +02:00
2017-01-26 10:16:21 +01:00
var directionInt = e . keyCode === downKey || e . keyCode === pageDownKey ? 1 : - 1 ;
var skipKey = e . metaKey || e . keyCode === pageDownKey || e . keyCode === pageUpKey ;
var nextEl = void 0 ;
if ( skipKey ) {
if ( directionInt > 0 ) {
2017-07-13 17:00:51 +02:00
nextEl = Array . from ( _this16 . dropdown . querySelectorAll ( '[data-choice-selectable]' ) ) . pop ( ) ;
2017-01-26 10:16:21 +01:00
} else {
2017-07-13 17:00:51 +02:00
nextEl = _this16 . dropdown . querySelector ( '[data-choice-selectable]' ) ;
2017-01-26 10:16:21 +01:00
}
2016-09-05 23:31:20 +02:00
} else {
2017-07-13 17:00:51 +02:00
var currentEl = _this16 . dropdown . querySelector ( '.' + _this16 . config . classNames . highlightedState ) ;
2017-01-26 10:16:21 +01:00
if ( currentEl ) {
nextEl = ( 0 , _utils . getAdjacentEl ) ( currentEl , '[data-choice-selectable]' , directionInt ) ;
} else {
2017-07-13 17:00:51 +02:00
nextEl = _this16 . dropdown . querySelector ( '[data-choice-selectable]' ) ;
2017-01-26 10:16:21 +01:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( nextEl ) {
// We prevent default to stop the cursor moving
// when pressing the arrow
2017-07-13 17:00:51 +02:00
if ( ! ( 0 , _utils . isScrolledIntoView ) ( nextEl , _this16 . choiceList , directionInt ) ) {
_this16 . _scrollToChoice ( nextEl , directionInt ) ;
2016-08-23 08:24:45 +02:00
}
2017-07-13 17:00:51 +02:00
_this16 . _highlightChoice ( nextEl ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Prevent default to maintain cursor position whilst
// traversing dropdown options
e . preventDefault ( ) ;
}
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var onDeleteKey = function onDeleteKey ( ) {
// If backspace or delete key is pressed and the input has no value
2017-07-13 17:00:51 +02:00
if ( hasFocusedInput && ! e . target . value && ! _this16 . isSelectOneElement ) {
_this16 . _handleBackspace ( activeItems ) ;
2016-09-05 23:31:20 +02:00
e . preventDefault ( ) ;
}
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Map keys to key actions
2017-01-26 10:16:21 +01:00
var keyDownActions = ( _keyDownActions = { } , _defineProperty ( _keyDownActions , aKey , onAKey ) , _defineProperty ( _keyDownActions , enterKey , onEnterKey ) , _defineProperty ( _keyDownActions , escapeKey , onEscapeKey ) , _defineProperty ( _keyDownActions , upKey , onDirectionKey ) , _defineProperty ( _keyDownActions , pageUpKey , onDirectionKey ) , _defineProperty ( _keyDownActions , downKey , onDirectionKey ) , _defineProperty ( _keyDownActions , pageDownKey , onDirectionKey ) , _defineProperty ( _keyDownActions , deleteKey , onDeleteKey ) , _defineProperty ( _keyDownActions , backKey , onDeleteKey ) , _keyDownActions ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If keycode has a function, run it
if ( keyDownActions [ e . keyCode ] ) {
keyDownActions [ e . keyCode ] ( ) ;
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Key up event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-09-04 16:23:19 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onKeyUp' ,
value : function _onKeyUp ( e ) {
2017-05-18 18:57:35 +02:00
if ( e . target !== this . input ) {
return ;
}
2016-08-23 08:24:45 +02:00
2017-05-11 16:12:14 +02:00
var value = this . input . value ;
var activeItems = this . store . getItemsFilteredByActive ( ) ;
var canAddItem = this . _canAddItem ( activeItems , value ) ;
2016-09-05 23:31:20 +02:00
// We are typing into a text input and have a value, we want to show a dropdown
// notice. Otherwise hide the dropdown
2016-10-26 16:43:15 +02:00
if ( this . isTextElement ) {
2016-09-05 23:31:20 +02:00
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
if ( value ) {
if ( canAddItem . notice ) {
var dropdownItem = this . _getTemplate ( 'notice' , canAddItem . notice ) ;
this . dropdown . innerHTML = dropdownItem . outerHTML ;
}
if ( canAddItem . response === true ) {
if ( ! hasActiveDropdown ) {
this . showDropdown ( ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} else if ( ! canAddItem . notice && hasActiveDropdown ) {
this . hideDropdown ( ) ;
}
} else if ( hasActiveDropdown ) {
this . hideDropdown ( ) ;
}
} else {
var backKey = 46 ;
var deleteKey = 8 ;
// If user has removed value...
if ( ( e . keyCode === backKey || e . keyCode === deleteKey ) && ! e . target . value ) {
// ...and it is a multiple select input, activate choices (if searching)
2017-07-13 17:00:51 +02:00
if ( ! this . isTextElement && this . isSearching ) {
2016-09-05 23:31:20 +02:00
this . isSearching = false ;
this . store . dispatch ( ( 0 , _index3 . activateChoices ) ( true ) ) ;
}
2017-05-11 16:12:14 +02:00
} else if ( this . canSearch && canAddItem . response ) {
2016-09-29 15:16:28 +02:00
this . _handleSearch ( this . input . value ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2017-06-02 22:34:07 +02:00
// Re-establish canSearch value from changes in _onKeyDown
2017-06-22 17:31:36 +02:00
this . canSearch = this . config . searchEnabled ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Input event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onInput' ,
value : function _onInput ( ) {
2017-07-13 17:00:51 +02:00
if ( ! this . isSelectOneElement ) {
2016-10-22 22:05:29 +02:00
this . _setInputWidth ( ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Touch move event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onTouchMove' ,
value : function _onTouchMove ( ) {
if ( this . wasTap === true ) {
this . wasTap = false ;
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Touch end event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
} , {
key : '_onTouchEnd' ,
value : function _onTouchEnd ( e ) {
var target = e . target || e . touches [ 0 ] . target ;
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
// If a user tapped within our container...
if ( this . wasTap === true && this . containerOuter . contains ( target ) ) {
// ...and we aren't dealing with a single select box, show dropdown/focus input
2017-07-13 17:00:51 +02:00
if ( ( target === this . containerOuter || target === this . containerInner ) && ! this . isSelectOneElement ) {
2016-10-26 16:43:15 +02:00
if ( this . isTextElement ) {
2016-09-05 23:31:20 +02:00
// If text element, we only want to focus the input (if it isn't already)
if ( document . activeElement !== this . input ) {
this . input . focus ( ) ;
}
} else {
if ( ! hasActiveDropdown ) {
// If a select box, we want to show the dropdown
this . showDropdown ( true ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
// Prevents focus event firing
e . stopPropagation ( ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . wasTap = true ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Mouse down event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
} , {
key : '_onMouseDown' ,
value : function _onMouseDown ( e ) {
var target = e . target ;
if ( this . containerOuter . contains ( target ) && target !== this . input ) {
2017-03-28 15:42:35 +02:00
var foundTarget = void 0 ;
2016-09-05 23:31:20 +02:00
var activeItems = this . store . getItemsFilteredByActive ( ) ;
var hasShiftKey = e . shiftKey ;
2017-03-28 15:42:35 +02:00
if ( foundTarget = ( 0 , _utils . findAncestorByAttrName ) ( target , 'data-button' ) ) {
this . _handleButtonAction ( activeItems , foundTarget ) ;
} else if ( foundTarget = ( 0 , _utils . findAncestorByAttrName ) ( target , 'data-item' ) ) {
2017-03-12 14:17:46 +01:00
this . _handleItemAction ( activeItems , foundTarget , hasShiftKey ) ;
2017-03-28 15:42:35 +02:00
} else if ( foundTarget = ( 0 , _utils . findAncestorByAttrName ) ( target , 'data-choice' ) ) {
2017-03-12 14:17:46 +01:00
this . _handleChoiceAction ( activeItems , foundTarget ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
e . preventDefault ( ) ;
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Click event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
} , {
key : '_onClick' ,
value : function _onClick ( e ) {
var target = e . target ;
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
var activeItems = this . store . getItemsFilteredByActive ( ) ;
// If target is something that concerns us
if ( this . containerOuter . contains ( target ) ) {
// Handle button delete
if ( target . hasAttribute ( 'data-button' ) ) {
this . _handleButtonAction ( activeItems , target ) ;
}
if ( ! hasActiveDropdown ) {
2016-10-26 16:43:15 +02:00
if ( this . isTextElement ) {
2016-09-05 23:31:20 +02:00
if ( document . activeElement !== this . input ) {
this . input . focus ( ) ;
}
} else {
if ( this . canSearch ) {
this . showDropdown ( true ) ;
} else {
this . showDropdown ( ) ;
this . containerOuter . focus ( ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2017-07-13 17:00:51 +02:00
} else if ( this . isSelectOneElement && target !== this . input && ! this . dropdown . contains ( target ) ) {
2016-09-05 23:31:20 +02:00
this . hideDropdown ( true ) ;
}
} else {
var hasHighlightedItems = activeItems . some ( function ( item ) {
2017-06-27 17:30:08 +02:00
return item . highlighted ;
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// De-select any highlighted items
if ( hasHighlightedItems ) {
this . unhighlightAll ( ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
// Remove focus state
this . containerOuter . classList . remove ( this . config . classNames . focusState ) ;
// Close all other dropdowns
if ( hasActiveDropdown ) {
this . hideDropdown ( ) ;
}
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Mouse over ( hover ) event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onMouseOver' ,
value : function _onMouseOver ( e ) {
// If the dropdown is either the target or one of its children is the target
if ( e . target === this . dropdown || this . dropdown . contains ( e . target ) ) {
if ( e . target . hasAttribute ( 'data-choice' ) ) this . _highlightChoice ( e . target ) ;
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Paste event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onPaste' ,
value : function _onPaste ( e ) {
// Disable pasting into the input if option has been set
if ( e . target === this . input && ! this . config . paste ) {
e . preventDefault ( ) ;
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Focus event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onFocus' ,
value : function _onFocus ( e ) {
2017-07-13 17:00:51 +02:00
var _this17 = this ;
2016-09-05 23:31:20 +02:00
var target = e . target ;
// If target is something that concerns us
if ( this . containerOuter . contains ( target ) ) {
2017-02-17 10:26:08 +01:00
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
var focusActions = {
text : function text ( ) {
2017-07-13 17:00:51 +02:00
if ( target === _this17 . input ) {
_this17 . containerOuter . classList . add ( _this17 . config . classNames . focusState ) ;
2017-02-17 10:26:08 +01:00
}
} ,
'select-one' : function selectOne ( ) {
2017-07-13 17:00:51 +02:00
_this17 . containerOuter . classList . add ( _this17 . config . classNames . focusState ) ;
if ( target === _this17 . input ) {
2017-02-17 10:26:08 +01:00
// Show dropdown if it isn't already showing
if ( ! hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this17 . showDropdown ( ) ;
2016-09-05 23:31:20 +02:00
}
2017-02-17 10:26:08 +01:00
}
} ,
'select-multiple' : function selectMultiple ( ) {
2017-07-13 17:00:51 +02:00
if ( target === _this17 . input ) {
// If element is a select box, the focused element is the container and the dropdown
2017-02-17 10:26:08 +01:00
// isn't already open, focus and show dropdown
2017-07-13 17:00:51 +02:00
_this17 . containerOuter . classList . add ( _this17 . config . classNames . focusState ) ;
2017-02-17 10:26:08 +01:00
if ( ! hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this17 . showDropdown ( true ) ;
2016-09-05 23:31:20 +02:00
}
}
2017-02-17 10:26:08 +01:00
}
} ;
2016-09-05 23:31:20 +02:00
2017-02-17 10:26:08 +01:00
focusActions [ this . passedElement . type ] ( ) ;
2016-09-05 23:31:20 +02:00
}
}
2017-07-19 21:48:25 +02:00
/ * *
* Blur event
* @ param { Object } e Event
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_onBlur' ,
value : function _onBlur ( e ) {
2017-07-13 17:00:51 +02:00
var _this18 = this ;
2016-09-05 23:31:20 +02:00
var target = e . target ;
// If target is something that concerns us
if ( this . containerOuter . contains ( target ) ) {
2017-02-17 10:26:08 +01:00
var activeItems = this . store . getItemsFilteredByActive ( ) ;
var hasActiveDropdown = this . dropdown . classList . contains ( this . config . classNames . activeState ) ;
var hasHighlightedItems = activeItems . some ( function ( item ) {
2017-06-27 17:30:08 +02:00
return item . highlighted ;
2017-02-17 10:26:08 +01:00
} ) ;
var blurActions = {
text : function text ( ) {
2017-07-13 17:00:51 +02:00
if ( target === _this18 . input ) {
2017-02-17 10:26:08 +01:00
// Remove the focus state
2017-07-13 17:00:51 +02:00
_this18 . containerOuter . classList . remove ( _this18 . config . classNames . focusState ) ;
2017-02-17 10:26:08 +01:00
// De-select any highlighted items
if ( hasHighlightedItems ) {
2017-07-13 17:00:51 +02:00
_this18 . unhighlightAll ( ) ;
2017-05-29 12:12:48 +02:00
}
// Hide dropdown if it is showing
if ( hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this18 . hideDropdown ( ) ;
2017-02-17 10:26:08 +01:00
}
}
} ,
'select-one' : function selectOne ( ) {
2017-07-13 17:00:51 +02:00
_this18 . containerOuter . classList . remove ( _this18 . config . classNames . focusState ) ;
if ( target === _this18 . containerOuter ) {
2017-02-17 10:26:08 +01:00
// Hide dropdown if it is showing
2017-07-13 17:00:51 +02:00
if ( hasActiveDropdown && ! _this18 . canSearch ) {
_this18 . hideDropdown ( ) ;
2017-02-17 10:26:08 +01:00
}
}
2017-07-13 17:00:51 +02:00
if ( target === _this18 . input && hasActiveDropdown ) {
2017-05-29 12:12:48 +02:00
// Hide dropdown if it is showing
2017-07-13 17:00:51 +02:00
_this18 . hideDropdown ( ) ;
2017-05-29 12:12:48 +02:00
}
2017-02-17 10:26:08 +01:00
} ,
'select-multiple' : function selectMultiple ( ) {
2017-07-13 17:00:51 +02:00
if ( target === _this18 . input ) {
2017-02-17 10:26:08 +01:00
// Remove the focus state
2017-07-13 17:00:51 +02:00
_this18 . containerOuter . classList . remove ( _this18 . config . classNames . focusState ) ;
2017-05-29 12:12:48 +02:00
// Hide dropdown if it is showing
if ( hasActiveDropdown ) {
2017-07-13 17:00:51 +02:00
_this18 . hideDropdown ( ) ;
2017-05-29 12:12:48 +02:00
}
2017-02-17 10:26:08 +01:00
// De-select any highlighted items
if ( hasHighlightedItems ) {
2017-07-13 17:00:51 +02:00
_this18 . unhighlightAll ( ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
}
2017-02-17 10:26:08 +01:00
}
} ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
blurActions [ this . passedElement . type ] ( ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Tests value against a regular expression
* @ param { string } value Value to test
* @ return { Boolean } Whether test passed / failed
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_regexFilter' ,
value : function _regexFilter ( value ) {
2017-05-18 18:57:35 +02:00
if ( ! value ) {
2017-07-13 17:00:51 +02:00
return false ;
2017-05-18 18:57:35 +02:00
}
2016-09-05 23:31:20 +02:00
var regex = this . config . regexFilter ;
var expression = new RegExp ( regex . source , 'i' ) ;
return expression . test ( value ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Scroll to an option element
* @ param { HTMLElement } choice Option to scroll to
* @ param { Number } direction Whether option is above or below
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_scrollToChoice' ,
value : function _scrollToChoice ( choice , direction ) {
2017-07-13 17:00:51 +02:00
var _this19 = this ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
if ( ! choice ) {
return ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var dropdownHeight = this . choiceList . offsetHeight ;
var choiceHeight = choice . offsetHeight ;
// Distance from bottom of element to top of parent
var choicePos = choice . offsetTop + choiceHeight ;
// Scroll position of dropdown
var containerScrollPos = this . choiceList . scrollTop + dropdownHeight ;
// Difference between the choice and scroll position
var endPoint = direction > 0 ? this . choiceList . scrollTop + choicePos - containerScrollPos : choice . offsetTop ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var animateScroll = function animateScroll ( ) {
var strength = 4 ;
2017-07-13 17:00:51 +02:00
var choiceListScrollTop = _this19 . choiceList . scrollTop ;
2016-09-05 23:31:20 +02:00
var continueAnimation = false ;
var easing = void 0 ;
var distance = void 0 ;
if ( direction > 0 ) {
2016-10-26 16:43:15 +02:00
easing = ( endPoint - choiceListScrollTop ) / strength ;
2016-09-05 23:31:20 +02:00
distance = easing > 1 ? easing : 1 ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
_this19 . choiceList . scrollTop = choiceListScrollTop + distance ;
2016-10-26 16:43:15 +02:00
if ( choiceListScrollTop < endPoint ) {
2016-09-05 23:31:20 +02:00
continueAnimation = true ;
}
} else {
2016-10-26 16:43:15 +02:00
easing = ( choiceListScrollTop - endPoint ) / strength ;
2016-09-05 23:31:20 +02:00
distance = easing > 1 ? easing : 1 ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
_this19 . choiceList . scrollTop = choiceListScrollTop - distance ;
2016-10-26 16:43:15 +02:00
if ( choiceListScrollTop > endPoint ) {
2016-09-05 23:31:20 +02:00
continueAnimation = true ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( continueAnimation ) {
requestAnimationFrame ( function ( time ) {
animateScroll ( time , endPoint , direction ) ;
} ) ;
}
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
requestAnimationFrame ( function ( time ) {
animateScroll ( time , endPoint , direction ) ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Highlight choice
* @ param { HTMLElement } [ el ] Element to highlight
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_highlightChoice' ,
2017-07-13 17:00:51 +02:00
value : function _highlightChoice ( ) {
var _this20 = this ;
var el = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : null ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Highlight first element in dropdown
var choices = Array . from ( this . dropdown . querySelectorAll ( '[data-choice-selectable]' ) ) ;
2017-06-03 13:38:33 +02:00
var passedEl = el ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( choices && choices . length ) {
var highlightedChoices = Array . from ( this . dropdown . querySelectorAll ( '.' + this . config . classNames . highlightedState ) ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Remove any highlighted choices
highlightedChoices . forEach ( function ( choice ) {
2017-07-13 17:00:51 +02:00
choice . classList . remove ( _this20 . config . classNames . highlightedState ) ;
2016-09-05 23:31:20 +02:00
choice . setAttribute ( 'aria-selected' , 'false' ) ;
} ) ;
2016-08-23 08:24:45 +02:00
2017-06-03 13:38:33 +02:00
if ( passedEl ) {
this . highlightPosition = choices . indexOf ( passedEl ) ;
2016-09-05 23:31:20 +02:00
} else {
// Highlight choice based on last known highlight location
if ( choices . length > this . highlightPosition ) {
// If we have an option to highlight
2017-06-03 13:38:33 +02:00
passedEl = choices [ this . highlightPosition ] ;
2016-09-05 23:31:20 +02:00
} else {
// Otherwise highlight the option before
2017-06-03 13:38:33 +02:00
passedEl = choices [ choices . length - 1 ] ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-06-03 13:38:33 +02:00
if ( ! passedEl ) {
passedEl = choices [ 0 ] ;
}
2016-08-23 08:24:45 +02:00
}
2017-06-02 22:34:07 +02:00
// Highlight given option, and set accessiblity attributes
2017-06-03 13:38:33 +02:00
passedEl . classList . add ( this . config . classNames . highlightedState ) ;
passedEl . setAttribute ( 'aria-selected' , 'true' ) ;
this . containerOuter . setAttribute ( 'aria-activedescendant' , passedEl . id ) ;
this . input . setAttribute ( 'aria-activedescendant' , passedEl . id ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Add item to store with correct value
* @ param { String } value Value to add to store
* @ param { String } [ label ] Label to add to store
* @ param { Number } [ choiceId = - 1 ] ID of the associated choice that was selected
* @ param { Number } [ groupId = - 1 ] ID of group choice is within . Negative number indicates no group
* @ param { Object } [ customProperties ] Object containing user defined properties
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_addItem' ,
2017-07-13 17:00:51 +02:00
value : function _addItem ( value ) {
var label = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : null ;
2016-10-26 16:43:15 +02:00
var choiceId = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : - 1 ;
var groupId = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : - 1 ;
2017-06-29 09:42:16 +02:00
var customProperties = arguments . length > 4 && arguments [ 4 ] !== undefined ? arguments [ 4 ] : null ;
2017-07-19 19:48:46 +02:00
var keyCode = arguments . length > 5 && arguments [ 5 ] !== undefined ? arguments [ 5 ] : null ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var passedValue = ( 0 , _utils . isType ) ( 'String' , value ) ? value . trim ( ) : value ;
2017-07-19 19:48:46 +02:00
var passedKeyCode = keyCode ;
2016-09-05 23:31:20 +02:00
var items = this . store . getItems ( ) ;
var passedLabel = label || passedValue ;
var passedOptionId = parseInt ( choiceId , 10 ) || - 1 ;
2017-01-01 17:01:35 +01:00
// Get group if group ID passed
var group = groupId >= 0 ? this . store . getGroupById ( groupId ) : null ;
// Generate unique id
var id = items ? items . length + 1 : 1 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If a prepended value has been passed, prepend it
if ( this . config . prependValue ) {
passedValue = this . config . prependValue + passedValue . toString ( ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If an appended value has been passed, append it
if ( this . config . appendValue ) {
passedValue += this . config . appendValue . toString ( ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 19:48:46 +02:00
this . store . dispatch ( ( 0 , _index3 . addItem ) ( passedValue , passedLabel , id , passedOptionId , groupId , customProperties , passedKeyCode ) ) ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
this . removeActiveItems ( id ) ;
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// Trigger change event
if ( group && group . value ) {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'addItem' , {
id : id ,
value : passedValue ,
2017-03-01 13:43:31 +01:00
label : passedLabel ,
2017-07-19 19:48:46 +02:00
groupValue : group . value ,
keyCode : passedKeyCode
2017-01-01 17:01:35 +01:00
} ) ;
} else {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'addItem' , {
id : id ,
2017-03-01 13:43:31 +01:00
value : passedValue ,
2017-07-19 19:48:46 +02:00
label : passedLabel ,
keyCode : passedKeyCode
2017-01-01 17:01:35 +01:00
} ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Remove item from store
* @ param { Object } item Item to remove
* @ return { Object } Class instance
* @ public
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_removeItem' ,
value : function _removeItem ( item ) {
if ( ! item || ! ( 0 , _utils . isType ) ( 'Object' , item ) ) {
2017-07-13 17:00:51 +02:00
return this ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var id = item . id ;
var value = item . value ;
2017-03-01 13:43:31 +01:00
var label = item . label ;
2016-09-05 23:31:20 +02:00
var choiceId = item . choiceId ;
2016-10-19 08:35:42 +02:00
var groupId = item . groupId ;
2017-01-01 17:01:35 +01:00
var group = groupId >= 0 ? this . store . getGroupById ( groupId ) : null ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . store . dispatch ( ( 0 , _index3 . removeItem ) ( id , choiceId ) ) ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
if ( group && group . value ) {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'removeItem' , {
id : id ,
value : value ,
2017-03-01 13:43:31 +01:00
label : label ,
2017-01-01 17:01:35 +01:00
groupValue : group . value
} ) ;
} else {
( 0 , _utils . triggerEvent ) ( this . passedElement , 'removeItem' , {
id : id ,
2017-03-01 13:43:31 +01:00
value : value ,
label : label
2017-01-01 17:01:35 +01:00
} ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return this ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Add choice to dropdown
* @ param { String } value Value of choice
* @ param { String } [ label ] Label of choice
* @ param { Boolean } [ isSelected = false ] Whether choice is selected
* @ param { Boolean } [ isDisabled = false ] Whether choice is disabled
* @ param { Number } [ groupId = - 1 ] ID of group choice is within . Negative number indicates no group
* @ param { Object } [ customProperties ] Object containing user defined properties
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_addChoice' ,
2017-07-13 17:00:51 +02:00
value : function _addChoice ( value ) {
var label = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : null ;
2017-06-27 17:30:08 +02:00
var isSelected = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : false ;
var isDisabled = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : false ;
2016-10-26 16:43:15 +02:00
var groupId = arguments . length > 4 && arguments [ 4 ] !== undefined ? arguments [ 4 ] : - 1 ;
2017-06-29 09:42:16 +02:00
var customProperties = arguments . length > 5 && arguments [ 5 ] !== undefined ? arguments [ 5 ] : null ;
2017-07-19 19:48:46 +02:00
var keyCode = arguments . length > 6 && arguments [ 6 ] !== undefined ? arguments [ 6 ] : null ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
if ( typeof value === 'undefined' || value === null ) {
return ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Generate unique id
var choices = this . store . getChoices ( ) ;
var choiceLabel = label || value ;
var choiceId = choices ? choices . length + 1 : 1 ;
2017-06-03 13:38:33 +02:00
var choiceElementId = this . baseId + '-' + this . idNames . itemChoice + '-' + choiceId ;
2016-08-23 08:24:45 +02:00
2017-07-19 19:48:46 +02:00
this . store . dispatch ( ( 0 , _index3 . addChoice ) ( value , choiceLabel , choiceId , groupId , isDisabled , choiceElementId , customProperties , keyCode ) ) ;
2016-08-23 08:24:45 +02:00
2016-09-21 14:32:21 +02:00
if ( isSelected ) {
2017-07-19 19:48:46 +02:00
this . _addItem ( value , choiceLabel , choiceId , undefined , customProperties , keyCode ) ;
2016-09-05 23:31:20 +02:00
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Clear all choices added to the store .
* @ return
* @ private
2016-09-26 18:11:32 +02:00
* /
} , {
key : '_clearChoices' ,
value : function _clearChoices ( ) {
this . store . dispatch ( ( 0 , _index3 . clearChoices ) ( ) ) ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Add group to dropdown
* @ param { Object } group Group to add
* @ param { Number } id Group ID
* @ param { String } [ valueKey ] name of the value property on the object
* @ param { String } [ labelKey ] name of the label property on the object
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_addGroup' ,
value : function _addGroup ( group , id ) {
2017-07-13 17:00:51 +02:00
var _this21 = this ;
2016-08-23 08:24:45 +02:00
2016-10-26 16:43:15 +02:00
var valueKey = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : 'value' ;
var labelKey = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : 'label' ;
2016-10-10 14:17:35 +02:00
2016-09-05 23:31:20 +02:00
var groupChoices = ( 0 , _utils . isType ) ( 'Object' , group ) ? group . choices : Array . from ( group . getElementsByTagName ( 'OPTION' ) ) ;
2017-02-05 10:46:37 +01:00
var groupId = id ? id : Math . floor ( new Date ( ) . valueOf ( ) * Math . random ( ) ) ;
2016-09-05 23:31:20 +02:00
var isDisabled = group . disabled ? group . disabled : false ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( groupChoices ) {
this . store . dispatch ( ( 0 , _index3 . addGroup ) ( group . label , groupId , true , isDisabled ) ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
groupChoices . forEach ( function ( option ) {
2017-06-27 17:30:08 +02:00
var isOptDisabled = option . disabled || option . parentNode && option . parentNode . disabled ;
var label = ( 0 , _utils . isType ) ( 'Object' , option ) ? option [ labelKey ] : option . innerHTML ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
_this21 . _addChoice ( option [ valueKey ] , label , option . selected , isOptDisabled , groupId , option . customProperties ) ;
2016-09-05 23:31:20 +02:00
} ) ;
} else {
this . store . dispatch ( ( 0 , _index3 . addGroup ) ( group . label , group . id , false , group . disabled ) ) ;
}
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get template from name
* @ param { String } template Name of template to get
* @ param { ... } args Data to pass to template
* @ return { HTMLElement } Template
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_getTemplate' ,
value : function _getTemplate ( template ) {
2017-05-18 18:57:35 +02:00
if ( ! template ) {
2017-07-13 17:00:51 +02:00
return null ;
2017-05-18 18:57:35 +02:00
}
2016-09-05 23:31:20 +02:00
var templates = this . config . templates ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
for ( var _len = arguments . length , args = Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) {
args [ _key - 1 ] = arguments [ _key ] ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return templates [ template ] . apply ( templates , args ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Create HTML element based on type and arguments
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_createTemplates' ,
value : function _createTemplates ( ) {
2017-07-13 17:00:51 +02:00
var _this22 = this ;
2016-09-05 23:31:20 +02:00
2017-06-27 13:42:01 +02:00
var globalClasses = this . config . classNames ;
2016-09-05 23:31:20 +02:00
var templates = {
containerOuter : function containerOuter ( direction ) {
2017-07-13 17:00:51 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + globalClasses . containerOuter + '"\n ' + ( _this22 . isSelectElement ? _this22 . config . searchEnabled ? 'role="combobox" aria-autocomplete="list"' : 'role="listbox"' : '' ) + '\n data-type="' + _this22 . passedElement . type + '"\n ' + ( _this22 . isSelectOneElement ? 'tabindex="0"' : '' ) + '\n aria-haspopup="true"\n aria-expanded="false"\n dir="' + direction + '"\n >\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
containerInner : function containerInner ( ) {
2017-06-27 13:42:01 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div class="' + globalClasses . containerInner + '"></div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
itemList : function itemList ( ) {
2017-06-27 13:42:01 +02:00
var _classNames ;
2017-07-13 17:00:51 +02:00
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . list , ( _classNames = { } , _defineProperty ( _classNames , globalClasses . listSingle , _this22 . isSelectOneElement ) , _defineProperty ( _classNames , globalClasses . listItems , ! _this22 . isSelectOneElement ) , _classNames ) ) ;
2017-06-27 13:42:01 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div class="' + localClasses + '"></div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
placeholder : function placeholder ( value ) {
2017-06-27 13:42:01 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div class="' + globalClasses . placeholder + '">\n ' + value + '\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
item : function item ( data ) {
2017-06-27 13:42:01 +02:00
var _classNames2 ;
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . item , ( _classNames2 = { } , _defineProperty ( _classNames2 , globalClasses . highlightedState , data . highlighted ) , _defineProperty ( _classNames2 , globalClasses . itemSelectable , ! data . highlighted ) , _classNames2 ) ) ;
2017-07-13 17:00:51 +02:00
if ( _this22 . config . removeItemButton ) {
2017-06-27 13:42:01 +02:00
var _classNames3 ;
localClasses = ( 0 , _classnames2 . default ) ( globalClasses . item , ( _classNames3 = { } , _defineProperty ( _classNames3 , globalClasses . highlightedState , data . highlighted ) , _defineProperty ( _classNames3 , globalClasses . itemSelectable , ! data . disabled ) , _classNames3 ) ) ;
2017-06-29 09:42:16 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + localClasses + '"\n data-item\n data-id="' + data . id + '"\n data-value="' + data . value + '"\n data-deletable\n ' + ( data . active ? 'aria-selected="true"' : '' ) + '\n ' + ( data . disabled ? 'aria-disabled="true"' : '' ) + '\n >\n ' + data . label + '<!--\n --><button\n type="button"\n class="' + globalClasses . button + '"\n data-button\n aria-label="Remove item: \'' + data . value + '\'"\n >\n Remove item\n </button>\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
}
2017-06-27 13:42:01 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + localClasses + '"\n data-item\n data-id="' + data . id + '"\n data-value="' + data . value + '"\n ' + ( data . active ? 'aria-selected="true"' : '' ) + '\n ' + ( data . disabled ? 'aria-disabled="true"' : '' ) + '\n >\n ' + data . label + '\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
choiceList : function choiceList ( ) {
2017-07-13 17:00:51 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + globalClasses . list + '"\n dir="ltr"\n role="listbox"\n ' + ( ! _this22 . isSelectOneElement ? 'aria-multiselectable="true"' : '' ) + '\n >\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
choiceGroup : function choiceGroup ( data ) {
2017-06-27 13:42:01 +02:00
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . group , _defineProperty ( { } , globalClasses . itemDisabled , data . disabled ) ) ;
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + localClasses + '"\n data-group\n data-id="' + data . id + '"\n data-value="' + data . value + '"\n role="group"\n ' + ( data . disabled ? 'aria-disabled="true"' : '' ) + '\n >\n <div class="' + globalClasses . groupHeading + '">' + data . value + '</div>\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
choice : function choice ( data ) {
2017-06-27 13:42:01 +02:00
var _classNames5 ;
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . item , globalClasses . itemChoice , ( _classNames5 = { } , _defineProperty ( _classNames5 , globalClasses . itemDisabled , data . disabled ) , _defineProperty ( _classNames5 , globalClasses . itemSelectable , ! data . disabled ) , _classNames5 ) ) ;
2017-07-13 17:00:51 +02:00
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + localClasses + '"\n data-select-text="' + _this22 . config . itemSelectText + '"\n data-choice\n data-id="' + data . id + '"\n data-value="' + data . value + '"\n ' + ( data . disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable' ) + '\n id="' + data . elementId + '"\n ' + ( data . groupId > 0 ? 'role="treeitem"' : 'role="option"' ) + '\n >\n ' + data . label + '\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
input : function input ( ) {
2017-06-27 13:42:01 +02:00
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . input , globalClasses . inputCloned ) ;
return ( 0 , _utils . strToEl ) ( '\n <input\n type="text"\n class="' + localClasses + '"\n autocomplete="off"\n autocapitalize="off"\n spellcheck="false"\n role="textbox"\n aria-autocomplete="list"\n >\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
dropdown : function dropdown ( ) {
2017-06-27 13:42:01 +02:00
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . list , globalClasses . listDropdown ) ;
return ( 0 , _utils . strToEl ) ( '\n <div\n class="' + localClasses + '"\n aria-expanded="false"\n >\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
notice : function notice ( label ) {
2017-06-27 13:42:01 +02:00
var localClasses = ( 0 , _classnames2 . default ) ( globalClasses . item , globalClasses . itemChoice ) ;
return ( 0 , _utils . strToEl ) ( '\n <div class="' + localClasses + '">\n ' + label + '\n </div>\n ' ) ;
2016-09-05 23:31:20 +02:00
} ,
option : function option ( data ) {
2017-03-28 15:42:35 +02:00
return ( 0 , _utils . strToEl ) ( '\n <option value="' + data . value + '" selected>' + data . label + '</option>\n ' ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
} ;
2016-08-23 08:24:45 +02:00
2016-09-30 09:46:27 +02:00
// User's custom templates
var callbackTemplate = this . config . callbackOnCreateTemplates ;
var userTemplates = { } ;
2016-10-10 14:17:35 +02:00
if ( callbackTemplate && ( 0 , _utils . isType ) ( 'Function' , callbackTemplate ) ) {
2016-11-07 11:37:47 +01:00
userTemplates = callbackTemplate . call ( this , _utils . strToEl ) ;
2016-09-30 09:46:27 +02:00
}
2017-01-01 17:01:35 +01:00
2016-09-30 09:46:27 +02:00
this . config . templates = ( 0 , _utils . extend ) ( templates , userTemplates ) ;
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Create DOM structure around passed select element
* @ return
* @ private
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : '_createInput' ,
value : function _createInput ( ) {
2017-07-13 17:00:51 +02:00
var _this23 = this ;
2016-09-05 23:31:20 +02:00
var direction = this . passedElement . getAttribute ( 'dir' ) || 'ltr' ;
var containerOuter = this . _getTemplate ( 'containerOuter' , direction ) ;
var containerInner = this . _getTemplate ( 'containerInner' ) ;
var itemList = this . _getTemplate ( 'itemList' ) ;
var choiceList = this . _getTemplate ( 'choiceList' ) ;
var input = this . _getTemplate ( 'input' ) ;
var dropdown = this . _getTemplate ( 'dropdown' ) ;
var placeholder = this . config . placeholder ? this . config . placeholderValue || this . passedElement . getAttribute ( 'placeholder' ) : false ;
this . containerOuter = containerOuter ;
this . containerInner = containerInner ;
this . input = input ;
this . choiceList = choiceList ;
this . itemList = itemList ;
this . dropdown = dropdown ;
// Hide passed input
this . passedElement . classList . add ( this . config . classNames . input , this . config . classNames . hiddenState ) ;
2017-05-29 12:12:48 +02:00
2017-07-19 21:48:25 +02:00
// Remove element from tab index
2016-09-05 23:31:20 +02:00
this . passedElement . tabIndex = '-1' ;
2017-07-19 21:48:25 +02:00
2017-07-17 12:35:50 +02:00
// Backup original styles if any
var origStyle = this . passedElement . getAttribute ( 'style' ) ;
2017-07-19 21:48:25 +02:00
2017-07-17 12:35:50 +02:00
if ( Boolean ( origStyle ) ) {
this . passedElement . setAttribute ( 'data-choice-orig-style' , origStyle ) ;
2017-07-14 23:53:43 +02:00
}
2017-07-19 21:48:25 +02:00
2016-09-05 23:31:20 +02:00
this . passedElement . setAttribute ( 'style' , 'display:none;' ) ;
this . passedElement . setAttribute ( 'aria-hidden' , 'true' ) ;
this . passedElement . setAttribute ( 'data-choice' , 'active' ) ;
// Wrap input in container preserving DOM ordering
( 0 , _utils . wrap ) ( this . passedElement , containerInner ) ;
// Wrapper inner container with outer container
( 0 , _utils . wrap ) ( containerInner , containerOuter ) ;
// If placeholder has been enabled and we have a value
if ( placeholder ) {
input . placeholder = placeholder ;
2017-07-13 17:00:51 +02:00
if ( ! this . isSelectOneElement ) {
2016-09-05 23:31:20 +02:00
input . style . width = ( 0 , _utils . getWidthOfInput ) ( input ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
if ( ! this . config . addItems ) {
this . disable ( ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
containerOuter . appendChild ( containerInner ) ;
containerOuter . appendChild ( dropdown ) ;
containerInner . appendChild ( itemList ) ;
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( ! this . isTextElement ) {
2016-09-05 23:31:20 +02:00
dropdown . appendChild ( choiceList ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-13 17:00:51 +02:00
if ( this . isSelectMultipleElement || this . isTextElement ) {
2016-09-05 23:31:20 +02:00
containerInner . appendChild ( input ) ;
} else if ( this . canSearch ) {
dropdown . insertBefore ( input , dropdown . firstChild ) ;
}
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
if ( this . isSelectElement ) {
2016-09-05 23:31:20 +02:00
var passedGroups = Array . from ( this . passedElement . getElementsByTagName ( 'OPTGROUP' ) ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . highlightPosition = 0 ;
this . isSearching = false ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( passedGroups && passedGroups . length ) {
2017-02-05 10:46:37 +01:00
passedGroups . forEach ( function ( group ) {
2017-07-13 17:00:51 +02:00
_this23 . _addGroup ( group , group . id || null ) ;
2016-09-05 23:31:20 +02:00
} ) ;
} else {
2017-02-17 10:26:08 +01:00
var passedOptions = Array . from ( this . passedElement . options ) ;
var filter = this . config . sortFilter ;
var allChoices = this . presetChoices ;
// Create array of options from option elements
passedOptions . forEach ( function ( o ) {
allChoices . push ( {
value : o . value ,
label : o . innerHTML ,
selected : o . selected ,
disabled : o . disabled || o . parentNode . disabled
2016-09-05 23:31:20 +02:00
} ) ;
2017-02-17 10:26:08 +01:00
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
// If sorting is enabled or the user is searching, filter choices
if ( this . config . shouldSort ) {
allChoices . sort ( filter ) ;
}
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
// Determine whether there is a selected choice
var hasSelectedChoice = allChoices . some ( function ( choice ) {
2017-06-27 17:30:08 +02:00
return choice . selected ;
2017-02-17 10:26:08 +01:00
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
// Add each choice
allChoices . forEach ( function ( choice , index ) {
// Pre-select first choice if it's a single select
2017-07-13 17:00:51 +02:00
if ( _this23 . isSelectOneElement ) {
2017-02-17 10:26:08 +01:00
if ( hasSelectedChoice || ! hasSelectedChoice && index > 0 ) {
// If there is a selected choice already or the choice is not
// the first in the array, add each choice normally
2017-07-13 17:00:51 +02:00
_this23 . _addChoice ( choice . value , choice . label , choice . selected , choice . disabled , undefined , choice . customProperties ) ;
2016-09-05 23:31:20 +02:00
} else {
2017-02-17 10:26:08 +01:00
// Otherwise pre-select the first choice in the array
2017-07-13 17:00:51 +02:00
_this23 . _addChoice ( choice . value , choice . label , true , false , undefined , choice . customProperties ) ;
2016-09-05 23:31:20 +02:00
}
2017-02-17 10:26:08 +01:00
} else {
2017-07-13 17:00:51 +02:00
_this23 . _addChoice ( choice . value , choice . label , choice . selected , choice . disabled , undefined , choice . customProperties ) ;
2017-02-17 10:26:08 +01:00
}
} ) ;
2016-08-23 08:24:45 +02:00
}
2016-10-26 16:43:15 +02:00
} else if ( this . isTextElement ) {
2016-09-05 23:31:20 +02:00
// Add any preset values seperated by delimiter
this . presetItems . forEach ( function ( item ) {
2017-02-17 10:26:08 +01:00
var itemType = ( 0 , _utils . getType ) ( item ) ;
if ( itemType === 'Object' ) {
2017-05-18 18:57:35 +02:00
if ( ! item . value ) {
return ;
}
2017-07-13 17:00:51 +02:00
_this23 . _addItem ( item . value , item . label , item . id , undefined , item . customProperties ) ;
2017-02-17 10:26:08 +01:00
} else if ( itemType === 'String' ) {
2017-07-13 17:00:51 +02:00
_this23 . _addItem ( item ) ;
2016-09-05 23:31:20 +02:00
}
} ) ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-29 15:16:28 +02:00
/*===== End of Private functions ======*/
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} ] ) ;
return Choices ;
2016-08-23 08:24:45 +02:00
} ( ) ;
2016-10-18 15:15:00 +02:00
module . exports = Choices ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2016-08-23 08:24:45 +02:00
/* 2 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
/ * *
* @ license
* Fuse - Lightweight fuzzy - search
*
* Copyright ( c ) 2012 - 2016 Kirollos Risk < kirollos @ gmail . com > .
* All Rights Reserved . Apache Software License 2.0
*
* Licensed under the Apache License , Version 2.0 ( the "License" )
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
; ( function ( global ) {
'use strict'
2017-02-17 10:26:08 +01:00
/** @type {function(...*)} */
2016-08-23 08:24:45 +02:00
function log ( ) {
console . log . apply ( console , arguments )
}
var defaultOptions = {
// The name of the identifier property. If specified, the returned result will be a list
// of the items' dentifiers, otherwise it will be a list of the items.
id : null ,
// Indicates whether comparisons should be case sensitive.
caseSensitive : false ,
// An array of values that should be included from the searcher's output. When this array
// contains elements, each result in the list will be of the form `{ item: ..., include1: ..., include2: ... }`.
// Values you can include are `score`, `matchedLocations`
include : [ ] ,
// Whether to sort the result list, by score
shouldSort : true ,
// The search function to use
// Note that the default search function ([[Function]]) must conform to the following API:
//
// @param pattern The pattern string to search
// @param options The search option
// [[Function]].constructor = function(pattern, options)
//
// @param text: the string to search in for the pattern
// @return Object in the form of:
// - isMatch: boolean
// - score: Int
// [[Function]].prototype.search = function(text)
searchFn : BitapSearcher ,
// Default sort function
sortFn : function ( a , b ) {
return a . score - b . score
} ,
// The get function to use when fetching an object's properties.
// The default will search nested paths *ie foo.bar.baz*
getFn : deepValue ,
// List of properties that will be searched. This also supports nested properties.
keys : [ ] ,
// Will print to the console. Useful for debugging.
verbose : false ,
// When true, the search algorithm will search individual words **and** the full string,
// computing the final score as a function of both. Note that when `tokenize` is `true`,
// the `threshold`, `distance`, and `location` are inconsequential for individual tokens.
tokenize : false ,
2016-09-04 16:23:19 +02:00
// When true, the result set will only include records that match all tokens. Will only work
// if `tokenize` is also true.
matchAllTokens : false ,
2016-08-23 08:24:45 +02:00
// Regex used to separate words when searching. Only applicable when `tokenize` is `true`.
2017-02-17 10:26:08 +01:00
tokenSeparator : / +/g ,
// Minimum number of characters that must be matched before a result is considered a match
minMatchCharLength : 1 ,
// When true, the algorithm continues searching to the end of the input even if a perfect
// match is found before the end of the same input.
findAllMatches : false
2016-08-23 08:24:45 +02:00
}
2017-02-17 10:26:08 +01:00
/ * *
* @ constructor
* @ param { ! Array } list
* @ param { ! Object < string , * > } options
* /
2016-08-23 08:24:45 +02:00
function Fuse ( list , options ) {
var key
this . list = list
this . options = options = options || { }
2017-02-17 10:26:08 +01:00
for ( key in defaultOptions ) {
if ( ! defaultOptions . hasOwnProperty ( key ) ) {
continue ;
}
// Add boolean type options
if ( typeof defaultOptions [ key ] === 'boolean' ) {
this . options [ key ] = key in options ? options [ key ] : defaultOptions [ key ] ;
// Add all other options
} else {
this . options [ key ] = options [ key ] || defaultOptions [ key ]
}
2016-08-23 08:24:45 +02:00
}
}
2017-05-18 18:57:35 +02:00
Fuse . VERSION = '2.7.3'
2016-08-23 08:24:45 +02:00
/ * *
* Sets a new list for Fuse to match against .
2017-02-17 10:26:08 +01:00
* @ param { ! Array } list
* @ return { ! Array } The newly set list
2016-08-23 08:24:45 +02:00
* @ public
* /
Fuse . prototype . set = function ( list ) {
this . list = list
return list
}
Fuse . prototype . search = function ( pattern ) {
if ( this . options . verbose ) log ( '\nSearch term:' , pattern , '\n' )
this . pattern = pattern
this . results = [ ]
this . resultMap = { }
this . _keyMap = null
this . _prepareSearchers ( )
this . _startSearch ( )
this . _computeScore ( )
this . _sort ( )
var output = this . _format ( )
return output
}
Fuse . prototype . _prepareSearchers = function ( ) {
var options = this . options
var pattern = this . pattern
var searchFn = options . searchFn
var tokens = pattern . split ( options . tokenSeparator )
var i = 0
var len = tokens . length
if ( this . options . tokenize ) {
this . tokenSearchers = [ ]
for ( ; i < len ; i ++ ) {
this . tokenSearchers . push ( new searchFn ( tokens [ i ] , options ) )
}
}
this . fullSeacher = new searchFn ( pattern , options )
}
Fuse . prototype . _startSearch = function ( ) {
var options = this . options
var getFn = options . getFn
var list = this . list
var listLen = list . length
var keys = this . options . keys
var keysLen = keys . length
var key
var weight
var item = null
var i
var j
// Check the first item in the list, if it's a string, then we assume
// that every item in the list is also a string, and thus it's a flattened array.
if ( typeof list [ 0 ] === 'string' ) {
// Iterate over every item
for ( i = 0 ; i < listLen ; i ++ ) {
this . _analyze ( '' , list [ i ] , i , i )
}
} else {
this . _keyMap = { }
// Otherwise, the first item is an Object (hopefully), and thus the searching
// is done on the values of the keys of each item.
// Iterate over every item
for ( i = 0 ; i < listLen ; i ++ ) {
item = list [ i ]
// Iterate over every key
for ( j = 0 ; j < keysLen ; j ++ ) {
key = keys [ j ]
if ( typeof key !== 'string' ) {
weight = ( 1 - key . weight ) || 1
this . _keyMap [ key . name ] = {
weight : weight
}
if ( key . weight <= 0 || key . weight > 1 ) {
throw new Error ( 'Key weight has to be > 0 and <= 1' )
}
key = key . name
} else {
this . _keyMap [ key ] = {
weight : 1
}
}
this . _analyze ( key , getFn ( item , key , [ ] ) , item , i )
}
}
}
}
Fuse . prototype . _analyze = function ( key , text , entity , index ) {
var options = this . options
var words
var scores
var exists = false
var existingResult
var averageScore
var finalScore
var scoresLen
var mainSearchResult
var tokenSearcher
var termScores
var word
var tokenSearchResult
2016-09-04 16:23:19 +02:00
var hasMatchInText
var checkTextMatches
2016-08-23 08:24:45 +02:00
var i
var j
// Check if the text can be searched
if ( text === undefined || text === null ) {
return
}
scores = [ ]
2016-09-04 16:23:19 +02:00
var numTextMatches = 0
2016-08-23 08:24:45 +02:00
if ( typeof text === 'string' ) {
words = text . split ( options . tokenSeparator )
if ( options . verbose ) log ( '---------\nKey:' , key )
if ( this . options . tokenize ) {
for ( i = 0 ; i < this . tokenSearchers . length ; i ++ ) {
tokenSearcher = this . tokenSearchers [ i ]
if ( options . verbose ) log ( 'Pattern:' , tokenSearcher . pattern )
termScores = [ ]
2016-09-04 16:23:19 +02:00
hasMatchInText = false
2016-08-23 08:24:45 +02:00
for ( j = 0 ; j < words . length ; j ++ ) {
word = words [ j ]
tokenSearchResult = tokenSearcher . search ( word )
var obj = { }
if ( tokenSearchResult . isMatch ) {
obj [ word ] = tokenSearchResult . score
exists = true
2016-09-04 16:23:19 +02:00
hasMatchInText = true
2016-08-23 08:24:45 +02:00
scores . push ( tokenSearchResult . score )
} else {
obj [ word ] = 1
2016-09-04 16:23:19 +02:00
if ( ! this . options . matchAllTokens ) {
scores . push ( 1 )
}
2016-08-23 08:24:45 +02:00
}
termScores . push ( obj )
}
2016-09-04 16:23:19 +02:00
if ( hasMatchInText ) {
numTextMatches ++
}
2016-08-23 08:24:45 +02:00
if ( options . verbose ) log ( 'Token scores:' , termScores )
}
averageScore = scores [ 0 ]
scoresLen = scores . length
for ( i = 1 ; i < scoresLen ; i ++ ) {
averageScore += scores [ i ]
}
averageScore = averageScore / scoresLen
if ( options . verbose ) log ( 'Token score average:' , averageScore )
}
mainSearchResult = this . fullSeacher . search ( text )
if ( options . verbose ) log ( 'Full text score:' , mainSearchResult . score )
finalScore = mainSearchResult . score
if ( averageScore !== undefined ) {
finalScore = ( finalScore + averageScore ) / 2
}
if ( options . verbose ) log ( 'Score average:' , finalScore )
2016-09-04 16:23:19 +02:00
checkTextMatches = ( this . options . tokenize && this . options . matchAllTokens ) ? numTextMatches >= this . tokenSearchers . length : true
if ( options . verbose ) log ( 'Check Matches' , checkTextMatches )
2016-08-23 08:24:45 +02:00
// If a match is found, add the item to <rawResults>, including its score
2016-09-04 16:23:19 +02:00
if ( ( exists || mainSearchResult . isMatch ) && checkTextMatches ) {
2016-08-23 08:24:45 +02:00
// Check if the item already exists in our results
existingResult = this . resultMap [ index ]
if ( existingResult ) {
// Use the lowest score
// existingResult.score, bitapResult.score
existingResult . output . push ( {
key : key ,
score : finalScore ,
matchedIndices : mainSearchResult . matchedIndices
} )
} else {
// Add it to the raw result list
this . resultMap [ index ] = {
item : entity ,
output : [ {
key : key ,
score : finalScore ,
matchedIndices : mainSearchResult . matchedIndices
} ]
}
this . results . push ( this . resultMap [ index ] )
}
}
} else if ( isArray ( text ) ) {
for ( i = 0 ; i < text . length ; i ++ ) {
this . _analyze ( key , text [ i ] , entity , index )
}
}
}
Fuse . prototype . _computeScore = function ( ) {
var i
var j
var keyMap = this . _keyMap
var totalScore
var output
var scoreLen
var score
var weight
var results = this . results
var bestScore
var nScore
if ( this . options . verbose ) log ( '\n\nComputing score:\n' )
for ( i = 0 ; i < results . length ; i ++ ) {
totalScore = 0
output = results [ i ] . output
scoreLen = output . length
bestScore = 1
for ( j = 0 ; j < scoreLen ; j ++ ) {
score = output [ j ] . score
weight = keyMap ? keyMap [ output [ j ] . key ] . weight : 1
nScore = score * weight
if ( weight !== 1 ) {
bestScore = Math . min ( bestScore , nScore )
} else {
totalScore += nScore
output [ j ] . nScore = nScore
}
}
if ( bestScore === 1 ) {
results [ i ] . score = totalScore / scoreLen
} else {
results [ i ] . score = bestScore
}
if ( this . options . verbose ) log ( results [ i ] )
}
}
Fuse . prototype . _sort = function ( ) {
var options = this . options
if ( options . shouldSort ) {
if ( options . verbose ) log ( '\n\nSorting....' )
this . results . sort ( options . sortFn )
}
}
Fuse . prototype . _format = function ( ) {
var options = this . options
var getFn = options . getFn
var finalOutput = [ ]
var i
var len
var results = this . results
var replaceValue
var getItemAtIndex
var include = options . include
if ( options . verbose ) log ( '\n\nOutput:\n\n' , results )
// Helper function, here for speed-up, which replaces the item with its value,
// if the options specifies it,
replaceValue = options . id ? function ( index ) {
results [ index ] . item = getFn ( results [ index ] . item , options . id , [ ] ) [ 0 ]
} : function ( ) { }
getItemAtIndex = function ( index ) {
var record = results [ index ]
var data
var j
var output
var _item
var _result
// If `include` has values, put the item in the result
if ( include . length > 0 ) {
data = {
item : record . item
}
if ( include . indexOf ( 'matches' ) !== - 1 ) {
output = record . output
data . matches = [ ]
for ( j = 0 ; j < output . length ; j ++ ) {
_item = output [ j ]
_result = {
indices : _item . matchedIndices
}
if ( _item . key ) {
_result . key = _item . key
}
data . matches . push ( _result )
}
}
if ( include . indexOf ( 'score' ) !== - 1 ) {
data . score = results [ index ] . score
}
} else {
data = record . item
}
return data
}
// From the results, push into a new array only the item identifier (if specified)
// of the entire item. This is because we don't want to return the <results>,
// since it contains other metadata
for ( i = 0 , len = results . length ; i < len ; i ++ ) {
replaceValue ( i )
2017-05-18 18:57:35 +02:00
finalOutput . push ( getItemAtIndex ( i ) )
2016-08-23 08:24:45 +02:00
}
return finalOutput
}
// Helpers
function deepValue ( obj , path , list ) {
var firstSegment
var remaining
var dotIndex
var value
var i
var len
if ( ! path ) {
// If there's no path left, we've gotten to the object we care about.
list . push ( obj )
} else {
dotIndex = path . indexOf ( '.' )
if ( dotIndex !== - 1 ) {
firstSegment = path . slice ( 0 , dotIndex )
remaining = path . slice ( dotIndex + 1 )
} else {
firstSegment = path
}
value = obj [ firstSegment ]
if ( value !== null && value !== undefined ) {
if ( ! remaining && ( typeof value === 'string' || typeof value === 'number' ) ) {
list . push ( value )
} else if ( isArray ( value ) ) {
// Search each item in the array.
for ( i = 0 , len = value . length ; i < len ; i ++ ) {
deepValue ( value [ i ] , remaining , list )
}
} else if ( remaining ) {
// An object. Recurse further.
deepValue ( value , remaining , list )
}
}
}
return list
}
function isArray ( obj ) {
return Object . prototype . toString . call ( obj ) === '[object Array]'
}
/ * *
* Adapted from "Diff, Match and Patch" , by Google
*
* http : //code.google.com/p/google-diff-match-patch/
*
* Modified by : Kirollos Risk < kirollos @ gmail . com >
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
* Details : the algorithm and structure was modified to allow the creation of
* < Searcher > instances with a < search > method which does the actual
* bitap search . The < pattern > ( the string that is searched for ) is only defined
* once per instance and thus it eliminates redundant re - creation when searching
* over a list of strings .
*
* Licensed under the Apache License , Version 2.0 ( the "License" )
* you may not use this file except in compliance with the License .
2017-02-17 10:26:08 +01:00
*
* @ constructor
2016-08-23 08:24:45 +02:00
* /
function BitapSearcher ( pattern , options ) {
options = options || { }
this . options = options
this . options . location = options . location || BitapSearcher . defaultOptions . location
this . options . distance = 'distance' in options ? options . distance : BitapSearcher . defaultOptions . distance
this . options . threshold = 'threshold' in options ? options . threshold : BitapSearcher . defaultOptions . threshold
this . options . maxPatternLength = options . maxPatternLength || BitapSearcher . defaultOptions . maxPatternLength
this . pattern = options . caseSensitive ? pattern : pattern . toLowerCase ( )
this . patternLen = pattern . length
if ( this . patternLen <= this . options . maxPatternLength ) {
this . matchmask = 1 << ( this . patternLen - 1 )
this . patternAlphabet = this . _calculatePatternAlphabet ( )
}
}
BitapSearcher . defaultOptions = {
// Approximately where in the text is the pattern expected to be found?
location : 0 ,
// Determines how close the match must be to the fuzzy location (specified above).
// An exact letter match which is 'distance' characters away from the fuzzy location
// would score as a complete mismatch. A distance of '0' requires the match be at
// the exact location specified, a threshold of '1000' would require a perfect match
// to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
distance : 100 ,
// At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
// (of both letters and location), a threshold of '1.0' would match anything.
threshold : 0.6 ,
// Machine word size
maxPatternLength : 32
}
/ * *
* Initialize the alphabet for the Bitap algorithm .
* @ return { Object } Hash of character locations .
* @ private
* /
BitapSearcher . prototype . _calculatePatternAlphabet = function ( ) {
var mask = { } ,
i = 0
for ( i = 0 ; i < this . patternLen ; i ++ ) {
mask [ this . pattern . charAt ( i ) ] = 0
}
for ( i = 0 ; i < this . patternLen ; i ++ ) {
mask [ this . pattern . charAt ( i ) ] |= 1 << ( this . pattern . length - i - 1 )
}
return mask
}
/ * *
* Compute and return the score for a match with ` e ` errors and ` x ` location .
* @ param { number } errors Number of errors in match .
* @ param { number } location Location of match .
* @ return { number } Overall score for match ( 0.0 = good , 1.0 = bad ) .
* @ private
* /
BitapSearcher . prototype . _bitapScore = function ( errors , location ) {
var accuracy = errors / this . patternLen ,
proximity = Math . abs ( this . options . location - location )
if ( ! this . options . distance ) {
// Dodge divide by zero error.
return proximity ? 1.0 : accuracy
}
return accuracy + ( proximity / this . options . distance )
}
/ * *
* Compute and return the result of the search
2017-02-17 10:26:08 +01:00
* @ param { string } text The text to search in
* @ return { { isMatch : boolean , score : number } } Literal containing :
* isMatch - Whether the text is a match or not
* score - Overall score for the match
2016-08-23 08:24:45 +02:00
* @ public
* /
BitapSearcher . prototype . search = function ( text ) {
var options = this . options
var i
var j
var textLen
2017-02-17 10:26:08 +01:00
var findAllMatches
2016-08-23 08:24:45 +02:00
var location
var threshold
var bestLoc
var binMin
var binMid
var binMax
var start , finish
var bitArr
var lastBitArr
var charMatch
var score
var locations
var matches
var isMatched
var matchMask
var matchedIndices
var matchesLen
var match
text = options . caseSensitive ? text : text . toLowerCase ( )
if ( this . pattern === text ) {
// Exact match
return {
isMatch : true ,
score : 0 ,
matchedIndices : [ [ 0 , text . length - 1 ] ]
}
}
// When pattern length is greater than the machine word length, just do a a regex comparison
if ( this . patternLen > options . maxPatternLength ) {
matches = text . match ( new RegExp ( this . pattern . replace ( options . tokenSeparator , '|' ) ) )
isMatched = ! ! matches
if ( isMatched ) {
matchedIndices = [ ]
for ( i = 0 , matchesLen = matches . length ; i < matchesLen ; i ++ ) {
match = matches [ i ]
matchedIndices . push ( [ text . indexOf ( match ) , match . length - 1 ] )
}
}
return {
isMatch : isMatched ,
// TODO: revisit this score
score : isMatched ? 0.5 : 1 ,
matchedIndices : matchedIndices
}
}
2017-02-17 10:26:08 +01:00
findAllMatches = options . findAllMatches
2016-08-23 08:24:45 +02:00
location = options . location
// Set starting location at beginning text and initialize the alphabet.
textLen = text . length
// Highest score beyond which we give up.
threshold = options . threshold
// Is there a nearby exact match? (speedup)
bestLoc = text . indexOf ( this . pattern , location )
// a mask of the matches
matchMask = [ ]
for ( i = 0 ; i < textLen ; i ++ ) {
matchMask [ i ] = 0
}
if ( bestLoc != - 1 ) {
threshold = Math . min ( this . _bitapScore ( 0 , bestLoc ) , threshold )
// What about in the other direction? (speed up)
bestLoc = text . lastIndexOf ( this . pattern , location + this . patternLen )
if ( bestLoc != - 1 ) {
threshold = Math . min ( this . _bitapScore ( 0 , bestLoc ) , threshold )
}
}
bestLoc = - 1
score = 1
locations = [ ]
binMax = this . patternLen + textLen
for ( i = 0 ; i < this . patternLen ; i ++ ) {
// Scan for the best match; each iteration allows for one more error.
// Run a binary search to determine how far from the match location we can stray
// at this error level.
binMin = 0
binMid = binMax
while ( binMin < binMid ) {
if ( this . _bitapScore ( i , location + binMid ) <= threshold ) {
binMin = binMid
} else {
binMax = binMid
}
binMid = Math . floor ( ( binMax - binMin ) / 2 + binMin )
}
// Use the result from this iteration as the maximum for the next.
binMax = binMid
start = Math . max ( 1 , location - binMid + 1 )
2017-02-17 10:26:08 +01:00
if ( findAllMatches ) {
finish = textLen ;
} else {
finish = Math . min ( location + binMid , textLen ) + this . patternLen
}
2016-08-23 08:24:45 +02:00
// Initialize the bit array
bitArr = Array ( finish + 2 )
bitArr [ finish + 1 ] = ( 1 << i ) - 1
for ( j = finish ; j >= start ; j -- ) {
charMatch = this . patternAlphabet [ text . charAt ( j - 1 ) ]
if ( charMatch ) {
matchMask [ j - 1 ] = 1
}
2017-05-18 18:57:35 +02:00
bitArr [ j ] = ( ( bitArr [ j + 1 ] << 1 ) | 1 ) & charMatch
if ( i !== 0 ) {
2016-08-23 08:24:45 +02:00
// Subsequent passes: fuzzy match.
2017-05-18 18:57:35 +02:00
bitArr [ j ] |= ( ( ( lastBitArr [ j + 1 ] | lastBitArr [ j ] ) << 1 ) | 1 ) | lastBitArr [ j + 1 ]
2016-08-23 08:24:45 +02:00
}
if ( bitArr [ j ] & this . matchmask ) {
score = this . _bitapScore ( i , j - 1 )
// This match will almost certainly be better than any existing match.
// But check anyway.
if ( score <= threshold ) {
// Indeed it is
threshold = score
bestLoc = j - 1
locations . push ( bestLoc )
2017-05-18 18:57:35 +02:00
// Already passed loc, downhill from here on in.
if ( bestLoc <= location ) {
2016-08-23 08:24:45 +02:00
break
}
2017-05-18 18:57:35 +02:00
// When passing loc, don't exceed our current distance from loc.
start = Math . max ( 1 , 2 * location - bestLoc )
2016-08-23 08:24:45 +02:00
}
}
}
// No hope for a (better) match at greater error levels.
if ( this . _bitapScore ( i + 1 , location ) > threshold ) {
break
}
lastBitArr = bitArr
}
matchedIndices = this . _getMatchedIndices ( matchMask )
// Count exact matches (those with a score of 0) to be "almost" exact
return {
isMatch : bestLoc >= 0 ,
score : score === 0 ? 0.001 : score ,
matchedIndices : matchedIndices
}
}
BitapSearcher . prototype . _getMatchedIndices = function ( matchMask ) {
var matchedIndices = [ ]
var start = - 1
var end = - 1
var i = 0
var match
var len = matchMask . length
for ( ; i < len ; i ++ ) {
match = matchMask [ i ]
if ( match && start === - 1 ) {
start = i
} else if ( ! match && start !== - 1 ) {
end = i - 1
2017-02-17 10:26:08 +01:00
if ( ( end - start ) + 1 >= this . options . minMatchCharLength ) {
matchedIndices . push ( [ start , end ] )
}
2016-08-23 08:24:45 +02:00
start = - 1
}
}
if ( matchMask [ i - 1 ] ) {
2017-02-17 10:26:08 +01:00
if ( ( i - 1 - start ) + 1 >= this . options . minMatchCharLength ) {
matchedIndices . push ( [ start , i - 1 ] )
}
2016-08-23 08:24:45 +02:00
}
return matchedIndices
}
// Export to Common JS Loader
if ( true ) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module . exports = Fuse
} else if ( typeof define === 'function' && define . amd ) {
// AMD. Register as an anonymous module.
define ( function ( ) {
return Fuse
} )
} else {
// Browser globals (root is window)
global . Fuse = Fuse
}
2017-02-17 10:26:08 +01:00
} ) ( this ) ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2016-08-23 08:24:45 +02:00
/* 3 */
2017-06-27 13:42:01 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
var _ _WEBPACK _AMD _DEFINE _ARRAY _ _ , _ _WEBPACK _AMD _DEFINE _RESULT _ _ ; / * !
Copyright ( c ) 2016 Jed Watson .
Licensed under the MIT License ( MIT ) , see
http : //jedwatson.github.io/classnames
* /
/* global define */
( function ( ) {
'use strict' ;
var hasOwn = { } . hasOwnProperty ;
function classNames ( ) {
var classes = [ ] ;
for ( var i = 0 ; i < arguments . length ; i ++ ) {
var arg = arguments [ i ] ;
if ( ! arg ) continue ;
var argType = typeof arg ;
if ( argType === 'string' || argType === 'number' ) {
classes . push ( arg ) ;
} else if ( Array . isArray ( arg ) ) {
classes . push ( classNames . apply ( null , arg ) ) ;
} else if ( argType === 'object' ) {
for ( var key in arg ) {
if ( hasOwn . call ( arg , key ) && arg [ key ] ) {
classes . push ( key ) ;
}
}
}
}
return classes . join ( ' ' ) ;
}
if ( typeof module !== 'undefined' && module . exports ) {
module . exports = classNames ;
} else if ( true ) {
// register as 'classnames', consistent with npm package name
! ( _ _WEBPACK _AMD _DEFINE _ARRAY _ _ = [ ] , _ _WEBPACK _AMD _DEFINE _RESULT _ _ = function ( ) {
return classNames ;
} . apply ( exports , _ _WEBPACK _AMD _DEFINE _ARRAY _ _ ) , _ _WEBPACK _AMD _DEFINE _RESULT _ _ !== undefined && ( module . exports = _ _WEBPACK _AMD _DEFINE _RESULT _ _ ) ) ;
} else {
window . classNames = classNames ;
}
} ( ) ) ;
/***/ } ) ,
/* 4 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
2017-06-27 13:42:01 +02:00
var _redux = _ _webpack _require _ _ ( 5 ) ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _index = _ _webpack _require _ _ ( 26 ) ;
2016-08-23 08:24:45 +02:00
var _index2 = _interopRequireDefault ( _index ) ;
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
var Store = function ( ) {
2016-09-05 23:31:20 +02:00
function Store ( ) {
_classCallCheck ( this , Store ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
this . store = ( 0 , _redux . createStore ) ( _index2 . default , window . devToolsExtension ? window . devToolsExtension ( ) : undefined ) ;
}
2017-07-19 21:48:25 +02:00
/ * *
* Get store object ( wrapping Redux method )
* @ return { Object } State
2016-09-05 23:31:20 +02:00
* /
_createClass ( Store , [ {
key : 'getState' ,
value : function getState ( ) {
return this . store . getState ( ) ;
2016-08-23 08:24:45 +02:00
}
2017-07-19 21:48:25 +02:00
/ * *
* Dispatch event to store ( wrapped Redux method )
* @ param { Function } action Action function to trigger
* @ return
2016-08-23 08:24:45 +02:00
* /
2016-09-05 23:31:20 +02:00
} , {
key : 'dispatch' ,
value : function dispatch ( action ) {
this . store . dispatch ( action ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Subscribe store to function call ( wrapped Redux method )
* @ param { Function } onChange Function to trigger when state changes
* @ return
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'subscribe' ,
value : function subscribe ( onChange ) {
this . store . subscribe ( onChange ) ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get items from store
* @ return { Array } Item objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getItems' ,
value : function getItems ( ) {
var state = this . store . getState ( ) ;
return state . items ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get active items from store
* @ return { Array } Item objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getItemsFilteredByActive' ,
value : function getItemsFilteredByActive ( ) {
var items = this . getItems ( ) ;
var values = items . filter ( function ( item ) {
return item . active === true ;
} , [ ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return values ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get items from store reduced to just their values
* @ return { Array } Item objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getItemsReducedToValues' ,
value : function getItemsReducedToValues ( ) {
2016-10-26 16:43:15 +02:00
var items = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : this . getItems ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var values = items . reduce ( function ( prev , current ) {
prev . push ( current . value ) ;
return prev ;
} , [ ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return values ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get choices from store
* @ return { Array } Option objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getChoices' ,
value : function getChoices ( ) {
var state = this . store . getState ( ) ;
return state . choices ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get active choices from store
* @ return { Array } Option objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getChoicesFilteredByActive' ,
value : function getChoicesFilteredByActive ( ) {
var choices = this . getChoices ( ) ;
var values = choices . filter ( function ( choice ) {
return choice . active === true ;
} , [ ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return values ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get selectable choices from store
* @ return { Array } Option objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getChoicesFilteredBySelectable' ,
value : function getChoicesFilteredBySelectable ( ) {
var choices = this . getChoices ( ) ;
var values = choices . filter ( function ( choice ) {
return choice . disabled !== true ;
} , [ ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return values ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get single choice by it ' s ID
* @ return { Object } Found choice
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getChoiceById' ,
value : function getChoiceById ( id ) {
if ( id ) {
var choices = this . getChoicesFilteredByActive ( ) ;
var foundChoice = choices . find ( function ( choice ) {
return choice . id === parseInt ( id , 10 ) ;
} ) ;
return foundChoice ;
}
return false ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get groups from store
* @ return { Array } Group objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getGroups' ,
value : function getGroups ( ) {
var state = this . store . getState ( ) ;
return state . groups ;
}
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get active groups from store
* @ return { Array } Group objects
2016-09-05 23:31:20 +02:00
* /
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
} , {
key : 'getGroupsFilteredByActive' ,
value : function getGroupsFilteredByActive ( ) {
var groups = this . getGroups ( ) ;
var choices = this . getChoices ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var values = groups . filter ( function ( group ) {
var isActive = group . active === true && group . disabled === false ;
var hasActiveOptions = choices . some ( function ( choice ) {
return choice . active === true && choice . disabled === false ;
} ) ;
return isActive && hasActiveOptions ;
} , [ ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return values ;
}
2016-10-18 20:41:05 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Get group by group id
* @ param { Number } id Group ID
* @ return { Object } Group data
2016-10-18 20:41:05 +02:00
* /
} , {
key : 'getGroupById' ,
value : function getGroupById ( id ) {
var groups = this . getGroups ( ) ;
var foundGroup = groups . find ( function ( group ) {
return group . id === id ;
} ) ;
return foundGroup ;
}
2016-09-05 23:31:20 +02:00
} ] ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return Store ;
2016-08-23 08:24:45 +02:00
} ( ) ;
exports . default = Store ;
module . exports = Store ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 5 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
exports . compose = exports . applyMiddleware = exports . bindActionCreators = exports . combineReducers = exports . createStore = undefined ;
2017-06-27 13:42:01 +02:00
var _createStore = _ _webpack _require _ _ ( 6 ) ;
2016-08-23 08:24:45 +02:00
var _createStore2 = _interopRequireDefault ( _createStore ) ;
2017-06-27 13:42:01 +02:00
var _combineReducers = _ _webpack _require _ _ ( 21 ) ;
2016-08-23 08:24:45 +02:00
var _combineReducers2 = _interopRequireDefault ( _combineReducers ) ;
2017-06-27 13:42:01 +02:00
var _bindActionCreators = _ _webpack _require _ _ ( 23 ) ;
2016-08-23 08:24:45 +02:00
var _bindActionCreators2 = _interopRequireDefault ( _bindActionCreators ) ;
2017-06-27 13:42:01 +02:00
var _applyMiddleware = _ _webpack _require _ _ ( 24 ) ;
2016-08-23 08:24:45 +02:00
var _applyMiddleware2 = _interopRequireDefault ( _applyMiddleware ) ;
2017-06-27 13:42:01 +02:00
var _compose = _ _webpack _require _ _ ( 25 ) ;
2016-08-23 08:24:45 +02:00
var _compose2 = _interopRequireDefault ( _compose ) ;
2017-06-27 13:42:01 +02:00
var _warning = _ _webpack _require _ _ ( 22 ) ;
2016-08-23 08:24:45 +02:00
var _warning2 = _interopRequireDefault ( _warning ) ;
2016-10-26 16:43:15 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
2016-08-23 08:24:45 +02:00
/ *
* This is a dummy function to check if the function name has been altered by minification .
* If the function has been minified and NODE _ENV !== 'production' , warn the user .
* /
function isCrushed ( ) { }
if ( false ) {
2016-10-26 16:43:15 +02:00
( 0 , _warning2 [ 'default' ] ) ( 'You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.' ) ;
2016-08-23 08:24:45 +02:00
}
2016-10-26 16:43:15 +02:00
exports . createStore = _createStore2 [ 'default' ] ;
exports . combineReducers = _combineReducers2 [ 'default' ] ;
exports . bindActionCreators = _bindActionCreators2 [ 'default' ] ;
exports . applyMiddleware = _applyMiddleware2 [ 'default' ] ;
exports . compose = _compose2 [ 'default' ] ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 6 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
exports . ActionTypes = undefined ;
2016-10-26 16:43:15 +02:00
exports [ 'default' ] = createStore ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _isPlainObject = _ _webpack _require _ _ ( 7 ) ;
2016-08-23 08:24:45 +02:00
var _isPlainObject2 = _interopRequireDefault ( _isPlainObject ) ;
2017-06-27 13:42:01 +02:00
var _symbolObservable = _ _webpack _require _ _ ( 17 ) ;
2016-08-23 08:24:45 +02:00
var _symbolObservable2 = _interopRequireDefault ( _symbolObservable ) ;
2016-10-26 16:43:15 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
2016-08-23 08:24:45 +02:00
/ * *
* These are private action types reserved by Redux .
* For any unknown actions , you must return the current state .
* If the current state is undefined , you must return the initial state .
* Do not reference these action types directly in your code .
* /
var ActionTypes = exports . ActionTypes = {
INIT : '@@redux/INIT'
2017-07-19 21:48:25 +02:00
} ;
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Creates a Redux store that holds the state tree .
* The only way to change the data in the store is to call ` dispatch() ` on it .
*
* There should only be a single store in your app . To specify how different
* parts of the state tree respond to actions , you may combine several reducers
* into a single reducer function by using ` combineReducers ` .
*
* @ param { Function } reducer A function that returns the next state tree , given
* the current state tree and the action to handle .
*
* @ param { any } [ preloadedState ] The initial state . You may optionally specify it
* to hydrate the state from the server in universal apps , or to restore a
* previously serialized user session .
* If you use ` combineReducers ` to produce the root reducer function , this must be
* an object with the same shape as ` combineReducers ` keys .
*
* @ param { Function } enhancer The store enhancer . You may optionally specify it
* to enhance the store with third - party capabilities such as middleware ,
* time travel , persistence , etc . The only store enhancer that ships with Redux
* is ` applyMiddleware() ` .
*
* @ returns { Store } A Redux store that lets you read the state , dispatch actions
* and subscribe to changes .
* /
function createStore ( reducer , preloadedState , enhancer ) {
2016-08-23 08:24:45 +02:00
var _ref2 ;
2016-10-26 16:43:15 +02:00
if ( typeof preloadedState === 'function' && typeof enhancer === 'undefined' ) {
enhancer = preloadedState ;
preloadedState = undefined ;
2016-08-23 08:24:45 +02:00
}
if ( typeof enhancer !== 'undefined' ) {
if ( typeof enhancer !== 'function' ) {
throw new Error ( 'Expected the enhancer to be a function.' ) ;
}
2016-10-26 16:43:15 +02:00
return enhancer ( createStore ) ( reducer , preloadedState ) ;
2016-08-23 08:24:45 +02:00
}
if ( typeof reducer !== 'function' ) {
throw new Error ( 'Expected the reducer to be a function.' ) ;
}
var currentReducer = reducer ;
2016-10-26 16:43:15 +02:00
var currentState = preloadedState ;
2016-08-23 08:24:45 +02:00
var currentListeners = [ ] ;
var nextListeners = currentListeners ;
var isDispatching = false ;
function ensureCanMutateNextListeners ( ) {
if ( nextListeners === currentListeners ) {
nextListeners = currentListeners . slice ( ) ;
}
}
/ * *
* Reads the state tree managed by the store .
*
* @ returns { any } The current state tree of your application .
* /
function getState ( ) {
return currentState ;
}
/ * *
* Adds a change listener . It will be called any time an action is dispatched ,
* and some part of the state tree may potentially have changed . You may then
* call ` getState() ` to read the current state tree inside the callback .
*
* You may call ` dispatch() ` from a change listener , with the following
* caveats :
*
* 1. The subscriptions are snapshotted just before every ` dispatch() ` call .
* If you subscribe or unsubscribe while the listeners are being invoked , this
* will not have any effect on the ` dispatch() ` that is currently in progress .
* However , the next ` dispatch() ` call , whether nested or not , will use a more
* recent snapshot of the subscription list .
*
* 2. The listener should not expect to see all state changes , as the state
* might have been updated multiple times during a nested ` dispatch() ` before
* the listener is called . It is , however , guaranteed that all subscribers
* registered before the ` dispatch() ` started will be called with the latest
* state by the time it exits .
*
* @ param { Function } listener A callback to be invoked on every dispatch .
* @ returns { Function } A function to remove this change listener .
* /
function subscribe ( listener ) {
if ( typeof listener !== 'function' ) {
throw new Error ( 'Expected listener to be a function.' ) ;
}
var isSubscribed = true ;
ensureCanMutateNextListeners ( ) ;
nextListeners . push ( listener ) ;
return function unsubscribe ( ) {
if ( ! isSubscribed ) {
return ;
}
isSubscribed = false ;
ensureCanMutateNextListeners ( ) ;
var index = nextListeners . indexOf ( listener ) ;
nextListeners . splice ( index , 1 ) ;
} ;
}
/ * *
* Dispatches an action . It is the only way to trigger a state change .
*
* The ` reducer ` function , used to create the store , will be called with the
* current state tree and the given ` action ` . Its return value will
* be considered the * * next * * state of the tree , and the change listeners
* will be notified .
*
* The base implementation only supports plain object actions . If you want to
* dispatch a Promise , an Observable , a thunk , or something else , you need to
* wrap your store creating function into the corresponding middleware . For
* example , see the documentation for the ` redux-thunk ` package . Even the
* middleware will eventually dispatch plain object actions using this method .
*
* @ param { Object } action A plain object representing “ what changed ” . It is
* a good idea to keep actions serializable so you can record and replay user
* sessions , or use the time travelling ` redux-devtools ` . An action must have
* a ` type ` property which may not be ` undefined ` . It is a good idea to use
* string constants for action types .
*
* @ returns { Object } For convenience , the same action object you dispatched .
*
* Note that , if you use a custom middleware , it may wrap ` dispatch() ` to
* return something else ( for example , a Promise you can await ) .
* /
function dispatch ( action ) {
2016-10-26 16:43:15 +02:00
if ( ! ( 0 , _isPlainObject2 [ 'default' ] ) ( action ) ) {
2016-08-23 08:24:45 +02:00
throw new Error ( 'Actions must be plain objects. ' + 'Use custom middleware for async actions.' ) ;
}
if ( typeof action . type === 'undefined' ) {
throw new Error ( 'Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?' ) ;
}
if ( isDispatching ) {
throw new Error ( 'Reducers may not dispatch actions.' ) ;
}
try {
isDispatching = true ;
currentState = currentReducer ( currentState , action ) ;
} finally {
isDispatching = false ;
}
var listeners = currentListeners = nextListeners ;
for ( var i = 0 ; i < listeners . length ; i ++ ) {
2017-07-19 21:48:25 +02:00
listeners [ i ] ( ) ;
2016-08-23 08:24:45 +02:00
}
return action ;
}
/ * *
* Replaces the reducer currently used by the store to calculate the state .
*
* You might need this if your app implements code splitting and you want to
* load some of the reducers dynamically . You might also need this if you
* implement a hot reloading mechanism for Redux .
*
* @ param { Function } nextReducer The reducer for the store to use instead .
* @ returns { void }
* /
function replaceReducer ( nextReducer ) {
if ( typeof nextReducer !== 'function' ) {
throw new Error ( 'Expected the nextReducer to be a function.' ) ;
}
currentReducer = nextReducer ;
dispatch ( { type : ActionTypes . INIT } ) ;
}
/ * *
* Interoperability point for observable / reactive libraries .
* @ returns { observable } A minimal observable of state changes .
* For more information , see the observable proposal :
2017-07-19 21:48:25 +02:00
* https : //github.com/zenparsing/es-observable
2016-08-23 08:24:45 +02:00
* /
function observable ( ) {
var _ref ;
var outerSubscribe = subscribe ;
return _ref = {
/ * *
* The minimal observable subscription method .
* @ param { Object } observer Any object that can be used as an observer .
* The observer object should have a ` next ` method .
* @ returns { subscription } An object with an ` unsubscribe ` method that can
* be used to unsubscribe the observable from the store , and prevent further
* emission of values from the observable .
* /
subscribe : function subscribe ( observer ) {
if ( typeof observer !== 'object' ) {
throw new TypeError ( 'Expected the observer to be an object.' ) ;
}
function observeState ( ) {
if ( observer . next ) {
observer . next ( getState ( ) ) ;
}
}
observeState ( ) ;
var unsubscribe = outerSubscribe ( observeState ) ;
return { unsubscribe : unsubscribe } ;
}
2016-10-26 16:43:15 +02:00
} , _ref [ _symbolObservable2 [ 'default' ] ] = function ( ) {
2016-08-23 08:24:45 +02:00
return this ;
} , _ref ;
}
// When a store is created, an "INIT" action is dispatched so that every
// reducer returns their initial state. This effectively populates
// the initial state tree.
dispatch ( { type : ActionTypes . INIT } ) ;
return _ref2 = {
dispatch : dispatch ,
subscribe : subscribe ,
getState : getState ,
replaceReducer : replaceReducer
2016-10-26 16:43:15 +02:00
} , _ref2 [ _symbolObservable2 [ 'default' ] ] = observable , _ref2 ;
2016-08-23 08:24:45 +02:00
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 7 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var baseGetTag = _ _webpack _require _ _ ( 8 ) ,
getPrototype = _ _webpack _require _ _ ( 14 ) ,
isObjectLike = _ _webpack _require _ _ ( 16 ) ;
2016-08-23 08:24:45 +02:00
/** `Object#toString` result references. */
var objectTag = '[object Object]' ;
/** Used for built-in method references. */
2016-09-04 16:23:19 +02:00
var funcProto = Function . prototype ,
objectProto = Object . prototype ;
2016-08-23 08:24:45 +02:00
/** Used to resolve the decompiled source of functions. */
2016-09-04 16:23:19 +02:00
var funcToString = funcProto . toString ;
2016-08-23 08:24:45 +02:00
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto . hasOwnProperty ;
/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString . call ( Object ) ;
/ * *
* Checks if ` value ` is a plain object , that is , an object created by the
* ` Object ` constructor or one with a ` [[Prototype]] ` of ` null ` .
*
* @ static
* @ memberOf _
* @ since 0.8 . 0
* @ category Lang
* @ param { * } value The value to check .
2016-09-04 16:23:19 +02:00
* @ returns { boolean } Returns ` true ` if ` value ` is a plain object , else ` false ` .
2016-08-23 08:24:45 +02:00
* @ example
*
* function Foo ( ) {
* this . a = 1 ;
* }
*
* _ . isPlainObject ( new Foo ) ;
* // => false
*
* _ . isPlainObject ( [ 1 , 2 , 3 ] ) ;
* // => false
*
* _ . isPlainObject ( { 'x' : 0 , 'y' : 0 } ) ;
* // => true
*
* _ . isPlainObject ( Object . create ( null ) ) ;
* // => true
* /
function isPlainObject ( value ) {
2017-02-17 10:26:08 +01:00
if ( ! isObjectLike ( value ) || baseGetTag ( value ) != objectTag ) {
2016-08-23 08:24:45 +02:00
return false ;
}
var proto = getPrototype ( value ) ;
if ( proto === null ) {
return true ;
}
var Ctor = hasOwnProperty . call ( proto , 'constructor' ) && proto . constructor ;
2017-02-17 10:26:08 +01:00
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
funcToString . call ( Ctor ) == objectCtorString ;
2016-08-23 08:24:45 +02:00
}
module . exports = isPlainObject ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 8 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var Symbol = _ _webpack _require _ _ ( 9 ) ,
getRawTag = _ _webpack _require _ _ ( 12 ) ,
objectToString = _ _webpack _require _ _ ( 13 ) ;
2017-02-17 10:26:08 +01:00
/** `Object#toString` result references. */
var nullTag = '[object Null]' ,
undefinedTag = '[object Undefined]' ;
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol . toStringTag : undefined ;
/ * *
* The base implementation of ` getTag ` without fallbacks for buggy environments .
*
* @ private
* @ param { * } value The value to query .
* @ returns { string } Returns the ` toStringTag ` .
* /
function baseGetTag ( value ) {
if ( value == null ) {
return value === undefined ? undefinedTag : nullTag ;
}
return ( symToStringTag && symToStringTag in Object ( value ) )
? getRawTag ( value )
: objectToString ( value ) ;
}
module . exports = baseGetTag ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 9 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2017-02-17 10:26:08 +01:00
2017-06-27 13:42:01 +02:00
var root = _ _webpack _require _ _ ( 10 ) ;
2017-02-17 10:26:08 +01:00
/** Built-in value references. */
var Symbol = root . Symbol ;
module . exports = Symbol ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 10 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2017-02-17 10:26:08 +01:00
2017-06-27 13:42:01 +02:00
var freeGlobal = _ _webpack _require _ _ ( 11 ) ;
2017-02-17 10:26:08 +01:00
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self . Object === Object && self ;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function ( 'return this' ) ( ) ;
module . exports = root ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 11 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2017-02-17 10:26:08 +01:00
/* WEBPACK VAR INJECTION */ ( function ( global ) { /** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global . Object === Object && global ;
module . exports = freeGlobal ;
/* WEBPACK VAR INJECTION */ } . call ( exports , ( function ( ) { return this ; } ( ) ) ) )
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 12 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2017-02-17 10:26:08 +01:00
2017-06-27 13:42:01 +02:00
var Symbol = _ _webpack _require _ _ ( 9 ) ;
2017-02-17 10:26:08 +01:00
/** Used for built-in method references. */
var objectProto = Object . prototype ;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto . hasOwnProperty ;
/ * *
* Used to resolve the
* [ ` toStringTag ` ] ( http : //ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values .
* /
var nativeObjectToString = objectProto . toString ;
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol . toStringTag : undefined ;
/ * *
* A specialized version of ` baseGetTag ` which ignores ` Symbol.toStringTag ` values .
*
* @ private
* @ param { * } value The value to query .
* @ returns { string } Returns the raw ` toStringTag ` .
* /
function getRawTag ( value ) {
var isOwn = hasOwnProperty . call ( value , symToStringTag ) ,
tag = value [ symToStringTag ] ;
try {
value [ symToStringTag ] = undefined ;
var unmasked = true ;
} catch ( e ) { }
var result = nativeObjectToString . call ( value ) ;
if ( unmasked ) {
if ( isOwn ) {
value [ symToStringTag ] = tag ;
} else {
delete value [ symToStringTag ] ;
}
}
return result ;
}
module . exports = getRawTag ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 13 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2017-02-17 10:26:08 +01:00
/** Used for built-in method references. */
var objectProto = Object . prototype ;
/ * *
* Used to resolve the
* [ ` toStringTag ` ] ( http : //ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values .
* /
var nativeObjectToString = objectProto . toString ;
/ * *
* Converts ` value ` to a string using ` Object.prototype.toString ` .
*
* @ private
* @ param { * } value The value to convert .
* @ returns { string } Returns the converted string .
* /
function objectToString ( value ) {
return nativeObjectToString . call ( value ) ;
}
module . exports = objectToString ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 14 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2017-02-17 10:26:08 +01:00
2017-06-27 13:42:01 +02:00
var overArg = _ _webpack _require _ _ ( 15 ) ;
2016-08-23 08:24:45 +02:00
2016-09-04 16:23:19 +02:00
/** Built-in value references. */
var getPrototype = overArg ( Object . getPrototypeOf , Object ) ;
2016-08-23 08:24:45 +02:00
module . exports = getPrototype ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 15 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
/ * *
2016-09-04 16:23:19 +02:00
* Creates a unary function that invokes ` func ` with its argument transformed .
2016-08-23 08:24:45 +02:00
*
* @ private
* @ param { Function } func The function to wrap .
* @ param { Function } transform The argument transform .
* @ returns { Function } Returns the new function .
* /
function overArg ( func , transform ) {
return function ( arg ) {
return func ( transform ( arg ) ) ;
} ;
}
module . exports = overArg ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 16 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
/ * *
* Checks if ` value ` is object - like . A value is object - like if it ' s not ` null `
* and has a ` typeof ` result of "object" .
*
* @ static
* @ memberOf _
* @ since 4.0 . 0
* @ category Lang
* @ param { * } value The value to check .
* @ returns { boolean } Returns ` true ` if ` value ` is object - like , else ` false ` .
* @ example
*
* _ . isObjectLike ( { } ) ;
* // => true
*
* _ . isObjectLike ( [ 1 , 2 , 3 ] ) ;
* // => true
*
* _ . isObjectLike ( _ . noop ) ;
* // => false
*
* _ . isObjectLike ( null ) ;
* // => false
* /
function isObjectLike ( value ) {
2016-10-26 16:43:15 +02:00
return value != null && typeof value == 'object' ;
2016-08-23 08:24:45 +02:00
}
module . exports = isObjectLike ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 17 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-10-26 16:43:15 +02:00
2017-06-27 13:42:01 +02:00
module . exports = _ _webpack _require _ _ ( 18 ) ;
2016-10-26 16:43:15 +02:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 18 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
2016-11-07 15:05:31 +01:00
/* WEBPACK VAR INJECTION */ ( function ( global , module ) { 'use strict' ;
2016-10-26 16:43:15 +02:00
Object . defineProperty ( exports , "__esModule" , {
2016-11-07 15:05:31 +01:00
value : true
2016-10-26 16:43:15 +02:00
} ) ;
2017-06-27 13:42:01 +02:00
var _ponyfill = _ _webpack _require _ _ ( 20 ) ;
2016-10-26 16:43:15 +02:00
var _ponyfill2 = _interopRequireDefault ( _ponyfill ) ;
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
2016-11-07 15:05:31 +01:00
var root ; /* global window */
2016-09-26 11:36:04 +02:00
2016-08-23 08:24:45 +02:00
2016-11-07 15:05:31 +01:00
if ( typeof self !== 'undefined' ) {
root = self ;
2016-10-26 16:43:15 +02:00
} else if ( typeof window !== 'undefined' ) {
2016-11-07 15:05:31 +01:00
root = window ;
} else if ( typeof global !== 'undefined' ) {
root = global ;
} else if ( true ) {
root = module ;
} else {
root = Function ( 'return this' ) ( ) ;
2016-10-26 16:43:15 +02:00
}
var result = ( 0 , _ponyfill2 [ 'default' ] ) ( root ) ;
exports [ 'default' ] = result ;
2017-06-27 13:42:01 +02:00
/* WEBPACK VAR INJECTION */ } . call ( exports , ( function ( ) { return this ; } ( ) ) , _ _webpack _require _ _ ( 19 ) ( module ) ) )
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 19 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-11-07 15:05:31 +01:00
2017-07-24 15:50:40 +02:00
module . exports = function ( module ) {
if ( ! module . webpackPolyfill ) {
module . deprecate = function ( ) { } ;
module . paths = [ ] ;
// module.parent = undefined by default
module . children = [ ] ;
module . webpackPolyfill = 1 ;
}
return module ;
}
2016-11-07 15:05:31 +01:00
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 20 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
2016-10-26 16:43:15 +02:00
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports [ 'default' ] = symbolObservablePonyfill ;
function symbolObservablePonyfill ( root ) {
2016-08-23 08:24:45 +02:00
var result ;
2016-10-26 16:43:15 +02:00
var _Symbol = root . Symbol ;
2016-08-23 08:24:45 +02:00
2016-10-26 16:43:15 +02:00
if ( typeof _Symbol === 'function' ) {
if ( _Symbol . observable ) {
result = _Symbol . observable ;
2016-08-23 08:24:45 +02:00
} else {
2016-10-26 16:43:15 +02:00
result = _Symbol ( 'observable' ) ;
_Symbol . observable = result ;
2016-08-23 08:24:45 +02:00
}
} else {
result = '@@observable' ;
}
return result ;
} ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 21 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
2016-10-26 16:43:15 +02:00
exports [ 'default' ] = combineReducers ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _createStore = _ _webpack _require _ _ ( 6 ) ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _isPlainObject = _ _webpack _require _ _ ( 7 ) ;
2016-08-23 08:24:45 +02:00
var _isPlainObject2 = _interopRequireDefault ( _isPlainObject ) ;
2017-06-27 13:42:01 +02:00
var _warning = _ _webpack _require _ _ ( 22 ) ;
2016-08-23 08:24:45 +02:00
var _warning2 = _interopRequireDefault ( _warning ) ;
2016-10-26 16:43:15 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
2016-08-23 08:24:45 +02:00
function getUndefinedStateErrorMessage ( key , action ) {
var actionType = action && action . type ;
var actionName = actionType && '"' + actionType . toString ( ) + '"' || 'an action' ;
2017-07-19 21:48:25 +02:00
return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.' ;
2016-08-23 08:24:45 +02:00
}
2016-10-26 16:43:15 +02:00
function getUnexpectedStateShapeWarningMessage ( inputState , reducers , action , unexpectedKeyCache ) {
2016-08-23 08:24:45 +02:00
var reducerKeys = Object . keys ( reducers ) ;
2016-10-26 16:43:15 +02:00
var argumentName = action && action . type === _createStore . ActionTypes . INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer' ;
2016-08-23 08:24:45 +02:00
if ( reducerKeys . length === 0 ) {
return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.' ;
}
2016-10-26 16:43:15 +02:00
if ( ! ( 0 , _isPlainObject2 [ 'default' ] ) ( inputState ) ) {
2016-08-23 08:24:45 +02:00
return 'The ' + argumentName + ' has unexpected type of "' + { } . toString . call ( inputState ) . match ( /\s([a-z|A-Z]+)/ ) [ 1 ] + '". Expected argument to be an object with the following ' + ( 'keys: "' + reducerKeys . join ( '", "' ) + '"' ) ;
}
var unexpectedKeys = Object . keys ( inputState ) . filter ( function ( key ) {
2016-10-26 16:43:15 +02:00
return ! reducers . hasOwnProperty ( key ) && ! unexpectedKeyCache [ key ] ;
} ) ;
unexpectedKeys . forEach ( function ( key ) {
unexpectedKeyCache [ key ] = true ;
2016-08-23 08:24:45 +02:00
} ) ;
if ( unexpectedKeys . length > 0 ) {
return 'Unexpected ' + ( unexpectedKeys . length > 1 ? 'keys' : 'key' ) + ' ' + ( '"' + unexpectedKeys . join ( '", "' ) + '" found in ' + argumentName + '. ' ) + 'Expected to find one of the known reducer keys instead: ' + ( '"' + reducerKeys . join ( '", "' ) + '". Unexpected keys will be ignored.' ) ;
}
}
2017-07-19 21:48:25 +02:00
function assertReducerSanity ( reducers ) {
2016-08-23 08:24:45 +02:00
Object . keys ( reducers ) . forEach ( function ( key ) {
var reducer = reducers [ key ] ;
var initialState = reducer ( undefined , { type : _createStore . ActionTypes . INIT } ) ;
if ( typeof initialState === 'undefined' ) {
2017-07-19 21:48:25 +02:00
throw new Error ( 'Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.' ) ;
2016-08-23 08:24:45 +02:00
}
var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math . random ( ) . toString ( 36 ) . substring ( 7 ) . split ( '' ) . join ( '.' ) ;
if ( typeof reducer ( undefined , { type : type } ) === 'undefined' ) {
2017-07-19 21:48:25 +02:00
throw new Error ( 'Reducer "' + key + '" returned undefined when probed with a random type. ' + ( 'Don\'t try to handle ' + _createStore . ActionTypes . INIT + ' or other actions in "redux/*" ' ) + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.' ) ;
2016-08-23 08:24:45 +02:00
}
} ) ;
}
/ * *
* Turns an object whose values are different reducer functions , into a single
* reducer function . It will call every child reducer , and gather their results
* into a single state object , whose keys correspond to the keys of the passed
* reducer functions .
*
* @ param { Object } reducers An object whose values correspond to different
* reducer functions that need to be combined into one . One handy way to obtain
* it is to use ES6 ` import * as reducers ` syntax . The reducers may never return
* undefined for any action . Instead , they should return their initial state
* if the state passed to them was undefined , and the current state for any
* unrecognized action .
*
* @ returns { Function } A reducer function that invokes every reducer inside the
* passed object , and builds a state object with the same shape .
* /
function combineReducers ( reducers ) {
var reducerKeys = Object . keys ( reducers ) ;
var finalReducers = { } ;
for ( var i = 0 ; i < reducerKeys . length ; i ++ ) {
var key = reducerKeys [ i ] ;
2016-10-26 16:43:15 +02:00
if ( false ) {
if ( typeof reducers [ key ] === 'undefined' ) {
( 0 , _warning2 [ 'default' ] ) ( 'No reducer provided for key "' + key + '"' ) ;
}
}
2016-08-23 08:24:45 +02:00
if ( typeof reducers [ key ] === 'function' ) {
finalReducers [ key ] = reducers [ key ] ;
}
}
var finalReducerKeys = Object . keys ( finalReducers ) ;
2016-10-26 16:43:15 +02:00
if ( false ) {
2017-07-19 21:48:25 +02:00
var unexpectedKeyCache = { } ;
2016-10-26 16:43:15 +02:00
}
2017-07-19 21:48:25 +02:00
var sanityError ;
2016-08-23 08:24:45 +02:00
try {
2017-07-19 21:48:25 +02:00
assertReducerSanity ( finalReducers ) ;
2016-08-23 08:24:45 +02:00
} catch ( e ) {
2017-07-19 21:48:25 +02:00
sanityError = e ;
2016-08-23 08:24:45 +02:00
}
return function combination ( ) {
2017-07-19 21:48:25 +02:00
var state = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
2016-08-23 08:24:45 +02:00
var action = arguments [ 1 ] ;
2017-07-19 21:48:25 +02:00
if ( sanityError ) {
throw sanityError ;
2016-08-23 08:24:45 +02:00
}
if ( false ) {
2016-10-26 16:43:15 +02:00
var warningMessage = getUnexpectedStateShapeWarningMessage ( state , finalReducers , action , unexpectedKeyCache ) ;
2016-08-23 08:24:45 +02:00
if ( warningMessage ) {
2016-10-26 16:43:15 +02:00
( 0 , _warning2 [ 'default' ] ) ( warningMessage ) ;
2016-08-23 08:24:45 +02:00
}
}
var hasChanged = false ;
var nextState = { } ;
2017-07-19 21:48:25 +02:00
for ( var i = 0 ; i < finalReducerKeys . length ; i ++ ) {
var key = finalReducerKeys [ i ] ;
var reducer = finalReducers [ key ] ;
var previousStateForKey = state [ key ] ;
2016-08-23 08:24:45 +02:00
var nextStateForKey = reducer ( previousStateForKey , action ) ;
if ( typeof nextStateForKey === 'undefined' ) {
2017-07-19 21:48:25 +02:00
var errorMessage = getUndefinedStateErrorMessage ( key , action ) ;
2016-08-23 08:24:45 +02:00
throw new Error ( errorMessage ) ;
}
2017-07-19 21:48:25 +02:00
nextState [ key ] = nextStateForKey ;
2016-08-23 08:24:45 +02:00
hasChanged = hasChanged || nextStateForKey !== previousStateForKey ;
}
return hasChanged ? nextState : state ;
} ;
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 22 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
2016-10-26 16:43:15 +02:00
exports [ 'default' ] = warning ;
2016-08-23 08:24:45 +02:00
/ * *
* Prints a warning in the console if it exists .
*
* @ param { String } message The warning message .
* @ returns { void }
* /
function warning ( message ) {
/* eslint-disable no-console */
if ( typeof console !== 'undefined' && typeof console . error === 'function' ) {
console . error ( message ) ;
}
/* eslint-enable no-console */
try {
// This error was thrown as a convenience so that if you enable
// "break on all exceptions" in your console,
// it would pause the execution at this line.
throw new Error ( message ) ;
/* eslint-disable no-empty */
} catch ( e ) { }
/* eslint-enable no-empty */
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 23 */
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
2016-10-26 16:43:15 +02:00
exports [ 'default' ] = bindActionCreators ;
2016-08-23 08:24:45 +02:00
function bindActionCreator ( actionCreator , dispatch ) {
return function ( ) {
return dispatch ( actionCreator . apply ( undefined , arguments ) ) ;
} ;
}
/ * *
* Turns an object whose values are action creators , into an object with the
* same keys , but with every function wrapped into a ` dispatch ` call so they
* may be invoked directly . This is just a convenience method , as you can call
* ` store.dispatch(MyActionCreators.doSomething()) ` yourself just fine .
*
* For convenience , you can also pass a single function as the first argument ,
* and get a function in return .
*
* @ param { Function | Object } actionCreators An object whose values are action
* creator functions . One handy way to obtain it is to use ES6 ` import * as `
* syntax . You may also pass a single function .
*
* @ param { Function } dispatch The ` dispatch ` function available on your Redux
* store .
*
* @ returns { Function | Object } The object mimicking the original object , but with
* every action creator wrapped into the ` dispatch ` call . If you passed a
* function as ` actionCreators ` , the return value will also be a single
* function .
* /
function bindActionCreators ( actionCreators , dispatch ) {
if ( typeof actionCreators === 'function' ) {
return bindActionCreator ( actionCreators , dispatch ) ;
}
if ( typeof actionCreators !== 'object' || actionCreators === null ) {
throw new Error ( 'bindActionCreators expected an object or a function, instead received ' + ( actionCreators === null ? 'null' : typeof actionCreators ) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?' ) ;
}
var keys = Object . keys ( actionCreators ) ;
var boundActionCreators = { } ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
var actionCreator = actionCreators [ key ] ;
if ( typeof actionCreator === 'function' ) {
boundActionCreators [ key ] = bindActionCreator ( actionCreator , dispatch ) ;
}
}
return boundActionCreators ;
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 24 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
exports . _ _esModule = true ;
var _extends = Object . assign || function ( target ) { for ( var i = 1 ; i < arguments . length ; i ++ ) { var source = arguments [ i ] ; for ( var key in source ) { if ( Object . prototype . hasOwnProperty . call ( source , key ) ) { target [ key ] = source [ key ] ; } } } return target ; } ;
2016-10-26 16:43:15 +02:00
exports [ 'default' ] = applyMiddleware ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _compose = _ _webpack _require _ _ ( 25 ) ;
2016-08-23 08:24:45 +02:00
var _compose2 = _interopRequireDefault ( _compose ) ;
2016-10-26 16:43:15 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
2016-08-23 08:24:45 +02:00
/ * *
* Creates a store enhancer that applies middleware to the dispatch method
* of the Redux store . This is handy for a variety of tasks , such as expressing
* asynchronous actions in a concise manner , or logging every action payload .
*
* See ` redux-thunk ` package as an example of the Redux middleware .
*
* Because middleware is potentially asynchronous , this should be the first
* store enhancer in the composition chain .
*
* Note that each middleware will be given the ` dispatch ` and ` getState ` functions
* as named arguments .
*
* @ param { ... Function } middlewares The middleware chain to be applied .
* @ returns { Function } A store enhancer applying the middleware .
* /
function applyMiddleware ( ) {
for ( var _len = arguments . length , middlewares = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
middlewares [ _key ] = arguments [ _key ] ;
}
return function ( createStore ) {
2016-10-26 16:43:15 +02:00
return function ( reducer , preloadedState , enhancer ) {
var store = createStore ( reducer , preloadedState , enhancer ) ;
2016-08-23 08:24:45 +02:00
var _dispatch = store . dispatch ;
var chain = [ ] ;
var middlewareAPI = {
getState : store . getState ,
dispatch : function dispatch ( action ) {
return _dispatch ( action ) ;
}
} ;
chain = middlewares . map ( function ( middleware ) {
return middleware ( middlewareAPI ) ;
} ) ;
2016-10-26 16:43:15 +02:00
_dispatch = _compose2 [ 'default' ] . apply ( undefined , chain ) ( store . dispatch ) ;
2016-08-23 08:24:45 +02:00
return _extends ( { } , store , {
dispatch : _dispatch
} ) ;
} ;
} ;
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 25 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
"use strict" ;
exports . _ _esModule = true ;
exports [ "default" ] = compose ;
/ * *
* Composes single - argument functions from right to left . The rightmost
* function can take multiple arguments as it provides the signature for
* the resulting composite function .
*
* @ param { ... Function } funcs The functions to compose .
* @ returns { Function } A function obtained by composing the argument functions
* from right to left . For example , compose ( f , g , h ) is identical to doing
* ( ... args ) => f ( g ( h ( ... args ) ) ) .
* /
function compose ( ) {
for ( var _len = arguments . length , funcs = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
funcs [ _key ] = arguments [ _key ] ;
}
if ( funcs . length === 0 ) {
return function ( arg ) {
return arg ;
} ;
2016-10-26 16:43:15 +02:00
}
2016-08-23 08:24:45 +02:00
2016-10-26 16:43:15 +02:00
if ( funcs . length === 1 ) {
return funcs [ 0 ] ;
2016-08-23 08:24:45 +02:00
}
2016-10-26 16:43:15 +02:00
2017-07-19 21:48:25 +02:00
var last = funcs [ funcs . length - 1 ] ;
var rest = funcs . slice ( 0 , - 1 ) ;
return function ( ) {
return rest . reduceRight ( function ( composed , f ) {
return f ( composed ) ;
} , last . apply ( undefined , arguments ) ) ;
} ;
2016-08-23 08:24:45 +02:00
}
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 26 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports , _ _webpack _require _ _ ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
2017-06-27 13:42:01 +02:00
var _redux = _ _webpack _require _ _ ( 5 ) ;
2016-08-23 08:24:45 +02:00
2017-06-27 13:42:01 +02:00
var _items = _ _webpack _require _ _ ( 27 ) ;
2016-08-23 08:24:45 +02:00
var _items2 = _interopRequireDefault ( _items ) ;
2017-06-27 13:42:01 +02:00
var _groups = _ _webpack _require _ _ ( 28 ) ;
2016-08-23 08:24:45 +02:00
var _groups2 = _interopRequireDefault ( _groups ) ;
2017-06-27 13:42:01 +02:00
var _choices = _ _webpack _require _ _ ( 29 ) ;
2016-08-23 08:24:45 +02:00
var _choices2 = _interopRequireDefault ( _choices ) ;
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
var appReducer = ( 0 , _redux . combineReducers ) ( {
2016-09-05 23:31:20 +02:00
items : _items2 . default ,
groups : _groups2 . default ,
choices : _choices2 . default
2016-08-23 08:24:45 +02:00
} ) ;
var rootReducer = function rootReducer ( passedState , action ) {
2016-09-05 23:31:20 +02:00
var state = passedState ;
// If we are clearing all items, groups and options we reassign
// state and then pass that state to our proper reducer. This isn't
// mutating our actual state
// See: http://stackoverflow.com/a/35641992
if ( action . type === 'CLEAR_ALL' ) {
state = undefined ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return appReducer ( state , action ) ;
2016-08-23 08:24:45 +02:00
} ;
exports . default = rootReducer ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 27 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
function _toConsumableArray ( arr ) { if ( Array . isArray ( arr ) ) { for ( var i = 0 , arr2 = Array ( arr . length ) ; i < arr . length ; i ++ ) { arr2 [ i ] = arr [ i ] ; } return arr2 ; } else { return Array . from ( arr ) ; } }
var items = function items ( ) {
2016-10-26 16:43:15 +02:00
var state = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : [ ] ;
2016-09-05 23:31:20 +02:00
var action = arguments [ 1 ] ;
switch ( action . type ) {
case 'ADD_ITEM' :
{
// Add object to items array
var newState = [ ] . concat ( _toConsumableArray ( state ) , [ {
id : action . id ,
choiceId : action . choiceId ,
2016-10-18 20:41:05 +02:00
groupId : action . groupId ,
2016-09-05 23:31:20 +02:00
value : action . value ,
label : action . label ,
active : true ,
2017-06-29 09:42:16 +02:00
highlighted : false ,
2017-07-19 19:48:46 +02:00
customProperties : action . customProperties ,
keyCode : null
2016-09-05 23:31:20 +02:00
} ] ) ;
return newState . map ( function ( item ) {
if ( item . highlighted ) {
item . highlighted = false ;
}
return item ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
case 'REMOVE_ITEM' :
{
// Set item to inactive
return state . map ( function ( item ) {
if ( item . id === action . id ) {
item . active = false ;
}
return item ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
case 'HIGHLIGHT_ITEM' :
{
return state . map ( function ( item ) {
if ( item . id === action . id ) {
item . highlighted = action . highlighted ;
}
return item ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
default :
{
return state ;
}
}
2016-08-23 08:24:45 +02:00
} ;
exports . default = items ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 28 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
function _toConsumableArray ( arr ) { if ( Array . isArray ( arr ) ) { for ( var i = 0 , arr2 = Array ( arr . length ) ; i < arr . length ; i ++ ) { arr2 [ i ] = arr [ i ] ; } return arr2 ; } else { return Array . from ( arr ) ; } }
var groups = function groups ( ) {
2016-10-26 16:43:15 +02:00
var state = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : [ ] ;
2016-09-05 23:31:20 +02:00
var action = arguments [ 1 ] ;
switch ( action . type ) {
case 'ADD_GROUP' :
{
return [ ] . concat ( _toConsumableArray ( state ) , [ {
id : action . id ,
value : action . value ,
active : action . active ,
disabled : action . disabled
} ] ) ;
}
2016-08-23 08:24:45 +02:00
2016-10-19 08:35:42 +02:00
case 'CLEAR_CHOICES' :
{
return state . groups = [ ] ;
}
2016-09-05 23:31:20 +02:00
default :
{
return state ;
}
}
2016-08-23 08:24:45 +02:00
} ;
exports . default = groups ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 29 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
function _toConsumableArray ( arr ) { if ( Array . isArray ( arr ) ) { for ( var i = 0 , arr2 = Array ( arr . length ) ; i < arr . length ; i ++ ) { arr2 [ i ] = arr [ i ] ; } return arr2 ; } else { return Array . from ( arr ) ; } }
var choices = function choices ( ) {
2016-10-26 16:43:15 +02:00
var state = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : [ ] ;
2016-09-05 23:31:20 +02:00
var action = arguments [ 1 ] ;
switch ( action . type ) {
case 'ADD_CHOICE' :
{
2017-07-19 21:48:25 +02:00
/ *
A disabled choice appears in the choice dropdown but cannot be selected
A selected choice has been added to the passed input ' s value ( added as an item )
An active choice appears within the choice dropdown
2016-09-05 23:31:20 +02:00
* /
return [ ] . concat ( _toConsumableArray ( state ) , [ {
id : action . id ,
2017-06-02 22:34:07 +02:00
elementId : action . elementId ,
2016-09-05 23:31:20 +02:00
groupId : action . groupId ,
value : action . value ,
2017-06-27 17:30:08 +02:00
label : action . label || action . value ,
2017-06-27 17:39:08 +02:00
disabled : action . disabled || false ,
2016-09-05 23:31:20 +02:00
selected : false ,
active : true ,
2017-06-29 09:42:16 +02:00
score : 9999 ,
2017-07-19 19:48:46 +02:00
customProperties : action . customProperties ,
keyCode : null
2016-09-05 23:31:20 +02:00
} ] ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
case 'ADD_ITEM' :
{
var newState = state ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If all choices need to be activated
if ( action . activateOptions ) {
newState = state . map ( function ( choice ) {
choice . active = action . active ;
return choice ;
} ) ;
}
// When an item is added and it has an associated choice,
// we want to disable it so it can't be chosen again
if ( action . choiceId > - 1 ) {
newState = state . map ( function ( choice ) {
if ( choice . id === parseInt ( action . choiceId , 10 ) ) {
choice . selected = true ;
}
return choice ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return newState ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
case 'REMOVE_ITEM' :
{
// When an item is removed and it has an associated choice,
// we want to re-enable it so it can be chosen again
if ( action . choiceId > - 1 ) {
return state . map ( function ( choice ) {
if ( choice . id === parseInt ( action . choiceId , 10 ) ) {
choice . selected = false ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
return choice ;
} ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return state ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
case 'FILTER_CHOICES' :
{
2017-02-17 10:26:08 +01:00
var filteredResults = action . results ;
var filteredState = state . map ( function ( choice ) {
// Set active state based on whether choice is
// within filtered results
choice . active = filteredResults . some ( function ( result ) {
if ( result . item . id === choice . id ) {
choice . score = result . score ;
return true ;
}
return false ;
2016-09-05 23:31:20 +02:00
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
return choice ;
} ) ;
2016-08-23 08:24:45 +02:00
2017-02-17 10:26:08 +01:00
return filteredState ;
2016-09-05 23:31:20 +02:00
}
case 'ACTIVATE_CHOICES' :
{
return state . map ( function ( choice ) {
choice . active = action . active ;
return choice ;
} ) ;
}
2016-09-26 18:11:32 +02:00
case 'CLEAR_CHOICES' :
{
return state . choices = [ ] ;
}
2016-09-05 23:31:20 +02:00
default :
{
return state ;
}
}
2016-08-23 08:24:45 +02:00
} ;
exports . default = choices ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 30 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
2017-07-19 19:48:46 +02:00
var addItem = exports . addItem = function addItem ( value , label , id , choiceId , groupId , customProperties , keyCode ) {
2016-09-05 23:31:20 +02:00
return {
type : 'ADD_ITEM' ,
value : value ,
label : label ,
id : id ,
choiceId : choiceId ,
2017-06-29 09:42:16 +02:00
groupId : groupId ,
2017-07-19 19:48:46 +02:00
customProperties : customProperties ,
keyCode : keyCode
2016-09-05 23:31:20 +02:00
} ;
2016-08-23 08:24:45 +02:00
} ;
var removeItem = exports . removeItem = function removeItem ( id , choiceId ) {
2016-09-05 23:31:20 +02:00
return {
type : 'REMOVE_ITEM' ,
id : id ,
choiceId : choiceId
} ;
2016-08-23 08:24:45 +02:00
} ;
var highlightItem = exports . highlightItem = function highlightItem ( id , highlighted ) {
2016-09-05 23:31:20 +02:00
return {
type : 'HIGHLIGHT_ITEM' ,
id : id ,
highlighted : highlighted
} ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 19:48:46 +02:00
var addChoice = exports . addChoice = function addChoice ( value , label , id , groupId , disabled , elementId , customProperties , keyCode ) {
2016-09-05 23:31:20 +02:00
return {
type : 'ADD_CHOICE' ,
value : value ,
label : label ,
id : id ,
groupId : groupId ,
2017-06-02 22:34:07 +02:00
disabled : disabled ,
2017-06-29 09:42:16 +02:00
elementId : elementId ,
2017-07-19 19:48:46 +02:00
customProperties : customProperties ,
keyCode : keyCode
2016-09-05 23:31:20 +02:00
} ;
2016-08-23 08:24:45 +02:00
} ;
var filterChoices = exports . filterChoices = function filterChoices ( results ) {
2016-09-05 23:31:20 +02:00
return {
type : 'FILTER_CHOICES' ,
results : results
} ;
2016-08-23 08:24:45 +02:00
} ;
var activateChoices = exports . activateChoices = function activateChoices ( ) {
2016-10-26 16:43:15 +02:00
var active = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : true ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return {
type : 'ACTIVATE_CHOICES' ,
active : active
} ;
2016-08-23 08:24:45 +02:00
} ;
2016-09-26 18:11:32 +02:00
var clearChoices = exports . clearChoices = function clearChoices ( ) {
return {
type : 'CLEAR_CHOICES'
} ;
} ;
2016-08-23 08:24:45 +02:00
var addGroup = exports . addGroup = function addGroup ( value , id , active , disabled ) {
2016-09-05 23:31:20 +02:00
return {
type : 'ADD_GROUP' ,
value : value ,
id : id ,
active : active ,
disabled : disabled
} ;
2016-08-23 08:24:45 +02:00
} ;
var clearAll = exports . clearAll = function clearAll ( ) {
2016-09-05 23:31:20 +02:00
return {
type : 'CLEAR_ALL'
} ;
2016-08-23 08:24:45 +02:00
} ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 31 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
2017-06-02 22:34:07 +02:00
'use strict' ;
2016-08-23 08:24:45 +02:00
Object . defineProperty ( exports , "__esModule" , {
2016-09-05 23:31:20 +02:00
value : true
2016-08-23 08:24:45 +02:00
} ) ;
2016-10-26 16:43:15 +02:00
var _typeof = typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ? function ( obj ) { return typeof obj ; } : function ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ;
2016-08-23 08:24:45 +02:00
/* eslint-disable */
2017-07-19 21:48:25 +02:00
/ * *
* Capitalises the first letter of each word in a string
* @ param { String } str String to capitalise
* @ return { String } Capitalised string
2016-08-23 08:24:45 +02:00
* /
var capitalise = exports . capitalise = function capitalise ( str ) {
2016-09-05 23:31:20 +02:00
return str . replace ( /\w\S*/g , function ( txt ) {
return txt . charAt ( 0 ) . toUpperCase ( ) + txt . substr ( 1 ) . toLowerCase ( ) ;
} ) ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Generates a string of random chars
* @ param { Number } length Length of the string to generate
* @ return { String } String of random chars
2017-06-02 22:34:07 +02:00
* /
var generateChars = exports . generateChars = function generateChars ( length ) {
var chars = '' ;
for ( var i = 0 ; i < length ; i ++ ) {
var randomChar = getRandomNumber ( 0 , 36 ) ;
chars += randomChar . toString ( 36 ) ;
}
return chars ;
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Generates a unique id based on an element
* @ param { HTMLElement } element Element to generate the id from
* @ param { String } Prefix for the Id
* @ return { String } Unique Id
2017-06-02 22:34:07 +02:00
* /
var generateId = exports . generateId = function generateId ( element , prefix ) {
var id = element . id || element . name && element . name + '-' + generateChars ( 2 ) || generateChars ( 4 ) ;
id = id . replace ( /(:|\.|\[|\]|,)/g , '' ) ;
id = prefix + id ;
return id ;
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Tests the type of an object
* @ param { String } type Type to test object against
* @ param { Object } obj Object to be tested
* @ return { Boolean }
2017-02-17 10:26:08 +01:00
* /
var getType = exports . getType = function getType ( obj ) {
return Object . prototype . toString . call ( obj ) . slice ( 8 , - 1 ) ;
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Tests the type of an object
* @ param { String } type Type to test object against
* @ param { Object } obj Object to be tested
* @ return { Boolean }
2016-08-23 08:24:45 +02:00
* /
var isType = exports . isType = function isType ( type , obj ) {
2017-02-17 10:26:08 +01:00
var clas = getType ( obj ) ;
2016-09-05 23:31:20 +02:00
return obj !== undefined && obj !== null && clas === type ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Tests to see if a passed object is a node
* @ param { Object } obj Object to be tested
* @ return { Boolean }
2016-08-23 08:24:45 +02:00
* /
var isNode = exports . isNode = function isNode ( o ) {
2017-06-02 22:34:07 +02:00
return ( typeof Node === 'undefined' ? 'undefined' : _typeof ( Node ) ) === "object" ? o instanceof Node : o && ( typeof o === 'undefined' ? 'undefined' : _typeof ( o ) ) === "object" && typeof o . nodeType === "number" && typeof o . nodeName === "string" ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Tests to see if a passed object is an element
* @ param { Object } obj Object to be tested
* @ return { Boolean }
2016-08-23 08:24:45 +02:00
* /
var isElement = exports . isElement = function isElement ( o ) {
2017-06-02 22:34:07 +02:00
return ( typeof HTMLElement === 'undefined' ? 'undefined' : _typeof ( HTMLElement ) ) === "object" ? o instanceof HTMLElement : //DOM2
o && ( typeof o === 'undefined' ? 'undefined' : _typeof ( o ) ) === "object" && o !== null && o . nodeType === 1 && typeof o . nodeName === "string" ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Merges unspecified amount of objects into new object
* @ private
* @ return { Object } Merged object of arguments
2016-08-23 08:24:45 +02:00
* /
var extend = exports . extend = function extend ( ) {
2016-09-05 23:31:20 +02:00
var extended = { } ;
var length = arguments . length ;
2016-08-23 08:24:45 +02:00
2017-07-19 21:48:25 +02:00
/ * *
* Merge one object into another
* @ param { Object } obj Object to merge into extended object
2016-09-05 23:31:20 +02:00
* /
var merge = function merge ( obj ) {
for ( var prop in obj ) {
if ( Object . prototype . hasOwnProperty . call ( obj , prop ) ) {
// If deep merge and property is an object, merge properties
2016-09-20 13:57:44 +02:00
if ( isType ( 'Object' , obj [ prop ] ) ) {
2016-09-05 23:31:20 +02:00
extended [ prop ] = extend ( true , extended [ prop ] , obj [ prop ] ) ;
} else {
extended [ prop ] = obj [ prop ] ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
}
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Loop through each passed argument
for ( var i = 0 ; i < length ; i ++ ) {
// store argument at position i
var obj = arguments [ i ] ;
2016-08-23 08:24:45 +02:00
2016-09-20 13:57:44 +02:00
// If we are in fact dealing with an object, merge it.
2016-09-05 23:31:20 +02:00
if ( isType ( 'Object' , obj ) ) {
merge ( obj ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return extended ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* CSS transition end event listener
* @ return
2016-08-23 08:24:45 +02:00
* /
var whichTransitionEvent = exports . whichTransitionEvent = function whichTransitionEvent ( ) {
2016-09-05 23:31:20 +02:00
var t ,
el = document . createElement ( "fakeelement" ) ;
var transitions = {
"transition" : "transitionend" ,
"OTransition" : "oTransitionEnd" ,
"MozTransition" : "transitionend" ,
"WebkitTransition" : "webkitTransitionEnd"
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
for ( t in transitions ) {
if ( el . style [ t ] !== undefined ) {
return transitions [ t ] ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* CSS animation end event listener
* @ return
2016-08-23 08:24:45 +02:00
* /
var whichAnimationEvent = exports . whichAnimationEvent = function whichAnimationEvent ( ) {
2016-09-05 23:31:20 +02:00
var t ,
el = document . createElement ( 'fakeelement' ) ;
var animations = {
'animation' : 'animationend' ,
'OAnimation' : 'oAnimationEnd' ,
'MozAnimation' : 'animationend' ,
'WebkitAnimation' : 'webkitAnimationEnd'
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
for ( t in animations ) {
if ( el . style [ t ] !== undefined ) {
return animations [ t ] ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Get the ancestors of each element in the current set of matched elements ,
* up to but not including the element matched by the selector
* @ param { NodeElement } elem Element to begin search from
* @ param { NodeElement } parent Parent to find
* @ param { String } selector Class to find
* @ return { Array } Array of parent elements
2016-08-23 08:24:45 +02:00
* /
var getParentsUntil = exports . getParentsUntil = function getParentsUntil ( elem , parent , selector ) {
2016-09-05 23:31:20 +02:00
var parents = [ ] ;
// Get matches
for ( ; elem && elem !== document ; elem = elem . parentNode ) {
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// Check if parent has been reached
if ( parent ) {
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var parentType = parent . charAt ( 0 ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If parent is a class
if ( parentType === '.' ) {
if ( elem . classList . contains ( parent . substr ( 1 ) ) ) {
break ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If parent is an ID
if ( parentType === '#' ) {
if ( elem . id === parent . substr ( 1 ) ) {
break ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If parent is a data attribute
if ( parentType === '[' ) {
if ( elem . hasAttribute ( parent . substr ( 1 , parent . length - 1 ) ) ) {
break ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If parent is a tag
if ( elem . tagName . toLowerCase ( ) === parent ) {
break ;
}
}
if ( selector ) {
var selectorType = selector . charAt ( 0 ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If selector is a class
if ( selectorType === '.' ) {
if ( elem . classList . contains ( selector . substr ( 1 ) ) ) {
parents . push ( elem ) ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If selector is an ID
if ( selectorType === '#' ) {
if ( elem . id === selector . substr ( 1 ) ) {
parents . push ( elem ) ;
}
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If selector is a data attribute
if ( selectorType === '[' ) {
if ( elem . hasAttribute ( selector . substr ( 1 , selector . length - 1 ) ) ) {
parents . push ( elem ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
// If selector is a tag
if ( elem . tagName . toLowerCase ( ) === selector ) {
parents . push ( elem ) ;
}
2016-08-23 08:24:45 +02:00
} else {
2016-09-05 23:31:20 +02:00
parents . push ( elem ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
// Return parents if any exist
if ( parents . length === 0 ) {
return null ;
} else {
return parents ;
}
2016-08-23 08:24:45 +02:00
} ;
var wrap = exports . wrap = function wrap ( element , wrapper ) {
2016-09-05 23:31:20 +02:00
wrapper = wrapper || document . createElement ( 'div' ) ;
if ( element . nextSibling ) {
element . parentNode . insertBefore ( wrapper , element . nextSibling ) ;
} else {
element . parentNode . appendChild ( wrapper ) ;
}
return wrapper . appendChild ( element ) ;
2016-08-23 08:24:45 +02:00
} ;
var getSiblings = exports . getSiblings = function getSiblings ( elem ) {
2016-09-05 23:31:20 +02:00
var siblings = [ ] ;
var sibling = elem . parentNode . firstChild ;
for ( ; sibling ; sibling = sibling . nextSibling ) {
if ( sibling . nodeType === 1 && sibling !== elem ) {
siblings . push ( sibling ) ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
}
return siblings ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Find ancestor in DOM tree
* @ param { NodeElement } el Element to start search from
* @ param { [ type ] } cls Class of parent
* @ return { NodeElement } Found parent element
2016-08-23 08:24:45 +02:00
* /
var findAncestor = exports . findAncestor = function findAncestor ( el , cls ) {
2016-09-05 23:31:20 +02:00
while ( ( el = el . parentElement ) && ! el . classList . contains ( cls ) ) { }
return el ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Find ancestor in DOM tree by attribute name
* @ param { NodeElement } el Element to start search from
* @ param { string } attr Attribute name of parent
* @ return { ? NodeElement } Found parent element or null
2017-03-12 14:17:46 +01:00
* /
2017-03-28 15:42:35 +02:00
var findAncestorByAttrName = exports . findAncestorByAttrName = function findAncestorByAttrName ( el , attr ) {
2017-03-12 14:17:46 +01:00
var target = el ;
while ( target ) {
if ( target . hasAttribute ( attr ) ) {
return target ;
}
target = target . parentElement ;
}
return null ;
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Debounce an event handler .
* @ param { Function } func Function to run after wait
* @ param { Number } wait The delay before the function is executed
* @ param { Boolean } immediate If passed , trigger the function on the leading edge , instead of the trailing .
* @ return { Function } A function will be called after it stops being called for a given delay
2016-08-23 08:24:45 +02:00
* /
var debounce = exports . debounce = function debounce ( func , wait , immediate ) {
2016-09-05 23:31:20 +02:00
var timeout ;
return function ( ) {
var context = this ,
args = arguments ;
var later = function later ( ) {
timeout = null ;
if ( ! immediate ) func . apply ( context , args ) ;
2016-08-23 08:24:45 +02:00
} ;
2016-09-05 23:31:20 +02:00
var callNow = immediate && ! timeout ;
clearTimeout ( timeout ) ;
timeout = setTimeout ( later , wait ) ;
if ( callNow ) func . apply ( context , args ) ;
} ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Get an element ' s distance from the top of the page
* @ private
* @ param { NodeElement } el Element to test for
* @ return { Number } Elements Distance from top of page
2016-08-23 08:24:45 +02:00
* /
var getElemDistance = exports . getElemDistance = function getElemDistance ( el ) {
2016-09-05 23:31:20 +02:00
var location = 0 ;
if ( el . offsetParent ) {
do {
location += el . offsetTop ;
el = el . offsetParent ;
} while ( el ) ;
}
return location >= 0 ? location : 0 ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Determine element height multiplied by any offsets
* @ private
* @ param { HTMLElement } el Element to test for
* @ return { Number } Height of element
2016-08-23 08:24:45 +02:00
* /
var getElementOffset = exports . getElementOffset = function getElementOffset ( el , offset ) {
2016-09-05 23:31:20 +02:00
var elOffset = offset ;
if ( elOffset > 1 ) elOffset = 1 ;
if ( elOffset > 0 ) elOffset = 0 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return Math . max ( el . offsetHeight * elOffset ) ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Get the next or previous element from a given start point
* @ param { HTMLElement } startEl Element to start position from
* @ param { String } className The class we will look through
* @ param { Number } direction Positive next element , negative previous element
* @ return { [ HTMLElement } Found element
2016-08-23 08:24:45 +02:00
* /
var getAdjacentEl = exports . getAdjacentEl = function getAdjacentEl ( startEl , className ) {
2016-10-26 16:43:15 +02:00
var direction = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : 1 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( ! startEl || ! className ) return ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var parent = startEl . parentNode . parentNode ;
var children = Array . from ( parent . querySelectorAll ( className ) ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var startPos = children . indexOf ( startEl ) ;
var operatorDirection = direction > 0 ? 1 : - 1 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return children [ startPos + operatorDirection ] ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Get scroll position based on top / bottom position
* @ private
* @ return { String } Position of scroll
2016-08-23 08:24:45 +02:00
* /
var getScrollPosition = exports . getScrollPosition = function getScrollPosition ( position ) {
2016-09-05 23:31:20 +02:00
if ( position === 'bottom' ) {
// Scroll position from the bottom of the viewport
return Math . max ( ( window . scrollY || window . pageYOffset ) + ( window . innerHeight || document . documentElement . clientHeight ) ) ;
} else {
// Scroll position from the top of the viewport
return window . scrollY || window . pageYOffset ;
}
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Determine whether an element is within the viewport
* @ param { HTMLElement } el Element to test
* @ return { String } Position of scroll
* @ return { Boolean }
2016-08-23 08:24:45 +02:00
* /
var isInView = exports . isInView = function isInView ( el , position , offset ) {
2016-09-05 23:31:20 +02:00
// If the user has scrolled further than the distance from the element to the top of its parent
return this . getScrollPosition ( position ) > this . getElemDistance ( el ) + this . getElementOffset ( el , offset ) ? true : false ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Determine whether an element is within
* @ param { HTMLElement } el Element to test
* @ param { HTMLElement } parent Scrolling parent
* @ param { Number } direction Whether element is visible from above or below
* @ return { Boolean }
2016-08-23 08:24:45 +02:00
* /
var isScrolledIntoView = exports . isScrolledIntoView = function isScrolledIntoView ( el , parent ) {
2016-10-26 16:43:15 +02:00
var direction = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : 1 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( ! el ) return ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var isVisible = void 0 ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( direction > 0 ) {
// In view from bottom
isVisible = parent . scrollTop + parent . offsetHeight >= el . offsetTop + el . offsetHeight ;
} else {
// In view from top
isVisible = el . offsetTop >= parent . scrollTop ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return isVisible ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Remove html tags from a string
* @ param { String } Initial string / html
* @ return { String } Sanitised string
2016-08-23 08:24:45 +02:00
* /
var stripHTML = exports . stripHTML = function stripHTML ( html ) {
2016-09-05 23:31:20 +02:00
var el = document . createElement ( "DIV" ) ;
el . innerHTML = html ;
return el . textContent || el . innerText || "" ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Adds animation to an element and removes it upon animation completion
* @ param { Element } el Element to add animation to
* @ param { String } animation Animation class to add to element
* @ return
2016-08-23 08:24:45 +02:00
* /
var addAnimation = exports . addAnimation = function addAnimation ( el , animation ) {
2016-09-05 23:31:20 +02:00
var animationEvent = whichAnimationEvent ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
var removeAnimation = function removeAnimation ( ) {
el . classList . remove ( animation ) ;
el . removeEventListener ( animationEvent , removeAnimation , false ) ;
} ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
el . classList . add ( animation ) ;
el . addEventListener ( animationEvent , removeAnimation , false ) ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Get a random number between a range
* @ param { Number } min Minimum range
* @ param { Number } max Maximum range
* @ return { Number } Random number
2016-08-23 08:24:45 +02:00
* /
var getRandomNumber = exports . getRandomNumber = function getRandomNumber ( min , max ) {
2016-09-05 23:31:20 +02:00
return Math . floor ( Math . random ( ) * ( max - min ) + min ) ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Turn a string into a node
* @ param { String } String to convert
* @ return { HTMLElement } Converted node element
2016-08-23 08:24:45 +02:00
* /
var strToEl = exports . strToEl = function ( ) {
2016-09-05 23:31:20 +02:00
var tmpEl = document . createElement ( 'div' ) ;
return function ( str ) {
2017-06-27 13:42:01 +02:00
var cleanedInput = str . trim ( ) ;
var r = void 0 ;
tmpEl . innerHTML = cleanedInput ;
2016-09-05 23:31:20 +02:00
r = tmpEl . children [ 0 ] ;
while ( tmpEl . firstChild ) {
tmpEl . removeChild ( tmpEl . firstChild ) ;
}
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
return r ;
} ;
2016-08-23 08:24:45 +02:00
} ( ) ;
2017-07-19 21:48:25 +02:00
/ * *
* Sets the width of a passed input based on its value
* @ return { Number } Width of input
2016-08-23 08:24:45 +02:00
* /
var getWidthOfInput = exports . getWidthOfInput = function getWidthOfInput ( input ) {
2016-09-05 23:31:20 +02:00
var value = input . value || input . placeholder ;
var width = input . offsetWidth ;
if ( value ) {
2017-06-02 22:34:07 +02:00
var testEl = strToEl ( '<span>' + value + '</span>' ) ;
2016-09-05 23:31:20 +02:00
testEl . style . position = 'absolute' ;
testEl . style . padding = '0' ;
testEl . style . top = '-9999px' ;
testEl . style . left = '-9999px' ;
testEl . style . width = 'auto' ;
testEl . style . whiteSpace = 'pre' ;
document . body . appendChild ( testEl ) ;
if ( value && testEl . offsetWidth !== input . offsetWidth ) {
width = testEl . offsetWidth + 4 ;
2016-08-23 08:24:45 +02:00
}
2016-09-05 23:31:20 +02:00
document . body . removeChild ( testEl ) ;
}
2017-06-02 22:34:07 +02:00
return width + 'px' ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Sorting function for current and previous string
* @ param { String } a Current value
* @ param { String } b Next value
* @ return { Number } - 1 for after previous ,
* 1 for before ,
* 0 for same location
2017-01-01 17:01:35 +01:00
* /
2016-08-23 08:24:45 +02:00
var sortByAlpha = exports . sortByAlpha = function sortByAlpha ( a , b ) {
2016-09-05 23:31:20 +02:00
var labelA = ( a . label || a . value ) . toLowerCase ( ) ;
var labelB = ( b . label || b . value ) . toLowerCase ( ) ;
2016-08-23 08:24:45 +02:00
2016-09-05 23:31:20 +02:00
if ( labelA < labelB ) return - 1 ;
if ( labelA > labelB ) return 1 ;
return 0 ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Sort by numeric score
* @ param { Object } a Current value
* @ param { Object } b Next value
* @ return { Number } - 1 for after previous ,
* 1 for before ,
* 0 for same location
2017-01-01 17:01:35 +01:00
* /
2016-08-23 08:24:45 +02:00
var sortByScore = exports . sortByScore = function sortByScore ( a , b ) {
2016-09-05 23:31:20 +02:00
return a . score - b . score ;
2016-08-23 08:24:45 +02:00
} ;
2017-07-19 21:48:25 +02:00
/ * *
* Trigger native event
* @ param { NodeElement } element Element to trigger event on
* @ param { String } type Type of event to trigger
* @ param { Object } customArgs Data to pass with event
* @ return { Object } Triggered event
2017-01-01 17:01:35 +01:00
* /
var triggerEvent = exports . triggerEvent = function triggerEvent ( element , type ) {
var customArgs = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : null ;
var event = new CustomEvent ( type , {
detail : customArgs ,
bubbles : true ,
cancelable : true
} ) ;
return element . dispatchEvent ( event ) ;
} ;
2017-05-18 18:57:35 +02:00
/***/ } ) ,
2017-06-27 13:42:01 +02:00
/* 32 */
2017-05-18 18:57:35 +02:00
/***/ ( function ( module , exports ) {
2016-08-23 08:24:45 +02:00
'use strict' ;
/* eslint-disable */
2017-01-01 17:01:35 +01:00
( function ( ) {
// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
if ( ! Array . from ) {
Array . from = function ( ) {
var toStr = Object . prototype . toString ;
var isCallable = function isCallable ( fn ) {
return typeof fn === 'function' || toStr . call ( fn ) === '[object Function]' ;
} ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
var toInteger = function toInteger ( value ) {
var number = Number ( value ) ;
if ( isNaN ( number ) ) {
return 0 ;
}
if ( number === 0 || ! isFinite ( number ) ) {
return number ;
}
return ( number > 0 ? 1 : - 1 ) * Math . floor ( Math . abs ( number ) ) ;
} ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
var maxSafeInteger = Math . pow ( 2 , 53 ) - 1 ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
var toLength = function toLength ( value ) {
var len = toInteger ( value ) ;
return Math . min ( Math . max ( len , 0 ) , maxSafeInteger ) ;
} ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// The length property of the from method is 1.
return function from ( arrayLike /*, mapFn, thisArg */ ) {
// 1. Let C be the this value.
var C = this ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// 2. Let items be ToObject(arrayLike).
var items = Object ( arrayLike ) ;
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// 3. ReturnIfAbrupt(items).
if ( arrayLike == null ) {
throw new TypeError ( "Array.from requires an array-like object - not null or undefined" ) ;
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments . length > 1 ? arguments [ 1 ] : void undefined ;
var T ;
if ( typeof mapFn !== 'undefined' ) {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if ( ! isCallable ( mapFn ) ) {
throw new TypeError ( 'Array.from: when provided, the second argument must be a function' ) ;
}
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if ( arguments . length > 2 ) {
T = arguments [ 2 ] ;
}
2016-09-05 23:31:20 +02:00
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength ( items . length ) ;
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable ( C ) ? Object ( new C ( len ) ) : new Array ( len ) ;
// 16. Let k be 0.
var k = 0 ;
// 17. Repeat, while k < len… (also steps a - h)
var kValue ;
while ( k < len ) {
kValue = items [ k ] ;
if ( mapFn ) {
A [ k ] = typeof T === 'undefined' ? mapFn ( kValue , k ) : mapFn . call ( T , kValue , k ) ;
} else {
A [ k ] = kValue ;
}
k += 1 ;
2016-09-05 23:31:20 +02:00
}
2017-01-01 17:01:35 +01:00
// 18. Let putStatus be Put(A, "length", len, true).
A . length = len ;
// 20. Return A.
return A ;
} ;
} ( ) ;
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
// Reference: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find
if ( ! Array . prototype . find ) {
Array . prototype . find = function ( predicate ) {
'use strict' ;
if ( this == null ) {
throw new TypeError ( 'Array.prototype.find called on null or undefined' ) ;
}
if ( typeof predicate !== 'function' ) {
throw new TypeError ( 'predicate must be a function' ) ;
}
var list = Object ( this ) ;
var length = list . length >>> 0 ;
var thisArg = arguments [ 1 ] ;
var value ;
for ( var i = 0 ; i < length ; i ++ ) {
value = list [ i ] ;
if ( predicate . call ( thisArg , value , i , list ) ) {
return value ;
2016-09-05 23:31:20 +02:00
}
}
2017-01-01 17:01:35 +01:00
return undefined ;
2016-09-05 23:31:20 +02:00
} ;
2017-01-01 17:01:35 +01:00
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
function CustomEvent ( event , params ) {
params = params || {
bubbles : false ,
cancelable : false ,
detail : undefined
} ;
var evt = document . createEvent ( 'CustomEvent' ) ;
evt . initCustomEvent ( event , params . bubbles , params . cancelable , params . detail ) ;
return evt ;
}
2016-08-23 08:24:45 +02:00
2017-01-01 17:01:35 +01:00
CustomEvent . prototype = window . Event . prototype ;
window . CustomEvent = CustomEvent ;
} ) ( ) ;
2016-08-23 08:24:45 +02:00
2017-05-18 18:57:35 +02:00
/***/ } )
2016-10-18 15:15:00 +02:00
/******/ ] )
} ) ;
;
2017-07-24 15:50:40 +02:00
//# sourceMappingURL=choices.js.map