From dab60475c79ff272c2a941326d609fed5fa4032e Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 7 Apr 2017 13:57:03 +0000 Subject: Update droplab --- .babelrc | 1 - app/assets/javascripts/droplab/constants.js | 11 + app/assets/javascripts/droplab/drop_down.js | 137 +++ app/assets/javascripts/droplab/drop_lab.js | 152 +++ app/assets/javascripts/droplab/droplab.js | 741 -------------- app/assets/javascripts/droplab/droplab_ajax.js | 103 -- .../javascripts/droplab/droplab_ajax_filter.js | 164 ---- app/assets/javascripts/droplab/droplab_filter.js | 76 -- app/assets/javascripts/droplab/hook.js | 22 + app/assets/javascripts/droplab/hook_button.js | 65 ++ app/assets/javascripts/droplab/hook_input.js | 119 +++ app/assets/javascripts/droplab/keyboard.js | 113 +++ app/assets/javascripts/droplab/plugins/ajax.js | 65 ++ .../javascripts/droplab/plugins/ajax_filter.js | 133 +++ app/assets/javascripts/droplab/plugins/filter.js | 95 ++ .../javascripts/droplab/plugins/input_setter.js | 52 + app/assets/javascripts/droplab/utils.js | 38 + .../javascripts/filtered_search/dropdown_hint.js | 10 +- .../filtered_search/dropdown_non_user.js | 22 +- .../javascripts/filtered_search/dropdown_user.js | 17 +- .../filtered_search/filtered_search_dropdown.js | 2 +- .../filtered_search_dropdown_manager.js | 2 +- .../filtered_search/filtered_search_manager.js | 2 +- app/assets/javascripts/main.js | 6 - app/assets/stylesheets/framework/filters.scss | 6 +- app/views/shared/issuable/_search_bar.html.haml | 2 +- .../issues/filtered_search/dropdown_hint_spec.rb | 14 +- .../issues/filtered_search/dropdown_label_spec.rb | 31 +- .../filtered_search/dropdown_milestone_spec.rb | 14 +- .../issues/filtered_search/search_bar_spec.rb | 18 +- spec/javascripts/droplab/constants_spec.js | 29 + spec/javascripts/droplab/drop_down_spec.js | 578 +++++++++++ spec/javascripts/droplab/hook_spec.js | 82 ++ .../droplab/plugins/input_setter_spec.js | 246 +++++ .../filtered_search/dropdown_user_spec.js | 8 +- yarn.lock | 1031 +++++++++++--------- 36 files changed, 2585 insertions(+), 1622 deletions(-) create mode 100644 app/assets/javascripts/droplab/constants.js create mode 100644 app/assets/javascripts/droplab/drop_down.js create mode 100644 app/assets/javascripts/droplab/drop_lab.js delete mode 100644 app/assets/javascripts/droplab/droplab.js delete mode 100644 app/assets/javascripts/droplab/droplab_ajax.js delete mode 100644 app/assets/javascripts/droplab/droplab_ajax_filter.js delete mode 100644 app/assets/javascripts/droplab/droplab_filter.js create mode 100644 app/assets/javascripts/droplab/hook.js create mode 100644 app/assets/javascripts/droplab/hook_button.js create mode 100644 app/assets/javascripts/droplab/hook_input.js create mode 100644 app/assets/javascripts/droplab/keyboard.js create mode 100644 app/assets/javascripts/droplab/plugins/ajax.js create mode 100644 app/assets/javascripts/droplab/plugins/ajax_filter.js create mode 100644 app/assets/javascripts/droplab/plugins/filter.js create mode 100644 app/assets/javascripts/droplab/plugins/input_setter.js create mode 100644 app/assets/javascripts/droplab/utils.js create mode 100644 spec/javascripts/droplab/constants_spec.js create mode 100644 spec/javascripts/droplab/drop_down_spec.js create mode 100644 spec/javascripts/droplab/hook_spec.js create mode 100644 spec/javascripts/droplab/plugins/input_setter_spec.js diff --git a/.babelrc b/.babelrc index ee4c391da30..2bae7ca9fbf 100644 --- a/.babelrc +++ b/.babelrc @@ -8,7 +8,6 @@ "plugins": [ ["istanbul", { "exclude": [ - "app/assets/javascripts/droplab/**/*", "spec/javascripts/**/*" ] }], diff --git a/app/assets/javascripts/droplab/constants.js b/app/assets/javascripts/droplab/constants.js new file mode 100644 index 00000000000..a23d914772a --- /dev/null +++ b/app/assets/javascripts/droplab/constants.js @@ -0,0 +1,11 @@ +const DATA_TRIGGER = 'data-dropdown-trigger'; +const DATA_DROPDOWN = 'data-dropdown'; +const SELECTED_CLASS = 'droplab-item-selected'; +const ACTIVE_CLASS = 'droplab-item-active'; + +export { + DATA_TRIGGER, + DATA_DROPDOWN, + SELECTED_CLASS, + ACTIVE_CLASS, +}; diff --git a/app/assets/javascripts/droplab/drop_down.js b/app/assets/javascripts/droplab/drop_down.js new file mode 100644 index 00000000000..f686ad33f6f --- /dev/null +++ b/app/assets/javascripts/droplab/drop_down.js @@ -0,0 +1,137 @@ +/* eslint-disable */ + +import utils from './utils'; +import { SELECTED_CLASS } from './constants'; + +var DropDown = function(list) { + this.currentIndex = 0; + this.hidden = true; + this.list = typeof list === 'string' ? document.querySelector(list) : list; + this.items = []; + + this.eventWrapper = {}; + + this.getItems(); + this.initTemplateString(); + this.addEvents(); + + this.initialState = list.innerHTML; +}; + +Object.assign(DropDown.prototype, { + getItems: function() { + this.items = [].slice.call(this.list.querySelectorAll('li')); + return this.items; + }, + + initTemplateString: function() { + var items = this.items || this.getItems(); + + var templateString = ''; + if (items.length > 0) templateString = items[items.length - 1].outerHTML; + this.templateString = templateString; + + return this.templateString; + }, + + clickEvent: function(e) { + var selected = utils.closest(e.target, 'LI'); + if (!selected) return; + + this.addSelectedClass(selected); + + e.preventDefault(); + this.hide(); + + var listEvent = new CustomEvent('click.dl', { + detail: { + list: this, + selected: selected, + data: e.target.dataset, + }, + }); + this.list.dispatchEvent(listEvent); + }, + + addSelectedClass: function (selected) { + this.removeSelectedClasses(); + selected.classList.add(SELECTED_CLASS); + }, + + removeSelectedClasses: function () { + const items = this.items || this.getItems(); + + items.forEach(item => item.classList.remove(SELECTED_CLASS)); + }, + + addEvents: function() { + this.eventWrapper.clickEvent = this.clickEvent.bind(this) + this.list.addEventListener('click', this.eventWrapper.clickEvent); + }, + + toggle: function() { + this.hidden ? this.show() : this.hide(); + }, + + setData: function(data) { + this.data = data; + this.render(data); + }, + + addData: function(data) { + this.data = (this.data || []).concat(data); + this.render(this.data); + }, + + render: function(data) { + const children = data ? data.map(this.renderChildren.bind(this)) : []; + const renderableList = this.list.querySelector('ul[data-dynamic]') || this.list; + + renderableList.innerHTML = children.join(''); + }, + + renderChildren: function(data) { + var html = utils.t(this.templateString, data); + var template = document.createElement('div'); + + template.innerHTML = html; + this.setImagesSrc(template); + template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block'; + + return template.firstChild.outerHTML; + }, + + setImagesSrc: function(template) { + const images = [].slice.call(template.querySelectorAll('img[data-src]')); + + images.forEach((image) => { + image.src = image.getAttribute('data-src'); + image.removeAttribute('data-src'); + }); + }, + + show: function() { + if (!this.hidden) return; + this.list.style.display = 'block'; + this.currentIndex = 0; + this.hidden = false; + }, + + hide: function() { + if (this.hidden) return; + this.list.style.display = 'none'; + this.currentIndex = 0; + this.hidden = true; + }, + + toggle: function () { + this.hidden ? this.show() : this.hide(); + }, + + destroy: function() { + this.hide(); + this.list.removeEventListener('click', this.eventWrapper.clickEvent); + } +}); + +export default DropDown; diff --git a/app/assets/javascripts/droplab/drop_lab.js b/app/assets/javascripts/droplab/drop_lab.js new file mode 100644 index 00000000000..6eb9f314af7 --- /dev/null +++ b/app/assets/javascripts/droplab/drop_lab.js @@ -0,0 +1,152 @@ +/* eslint-disable */ + +import HookButton from './hook_button'; +import HookInput from './hook_input'; +import utils from './utils'; +import Keyboard from './keyboard'; +import { DATA_TRIGGER } from './constants'; + +var DropLab = function() { + this.ready = false; + this.hooks = []; + this.queuedData = []; + this.config = {}; + + this.eventWrapper = {}; +}; + +Object.assign(DropLab.prototype, { + loadStatic: function(){ + var dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`)); + this.addHooks(dropdownTriggers); + }, + + addData: function () { + var args = [].slice.apply(arguments); + this.applyArgs(args, '_addData'); + }, + + setData: function() { + var args = [].slice.apply(arguments); + this.applyArgs(args, '_setData'); + }, + + destroy: function() { + this.hooks.forEach(hook => hook.destroy()); + this.hooks = []; + this.removeEvents(); + }, + + applyArgs: function(args, methodName) { + if (this.ready) return this[methodName].apply(this, args); + + this.queuedData = this.queuedData || []; + this.queuedData.push(args); + }, + + _addData: function(trigger, data) { + this._processData(trigger, data, 'addData'); + }, + + _setData: function(trigger, data) { + this._processData(trigger, data, 'setData'); + }, + + _processData: function(trigger, data, methodName) { + this.hooks.forEach((hook) => { + if (Array.isArray(trigger)) hook.list[methodName](trigger); + + if (hook.trigger.id === trigger) hook.list[methodName](data); + }); + }, + + addEvents: function() { + this.eventWrapper.documentClicked = this.documentClicked.bind(this) + document.addEventListener('click', this.eventWrapper.documentClicked); + }, + + documentClicked: function(e) { + let thisTag = e.target; + + if (thisTag.tagName !== 'UL') thisTag = utils.closest(thisTag, 'UL'); + if (utils.isDropDownParts(thisTag, this.hooks) || utils.isDropDownParts(e.target, this.hooks)) return; + + this.hooks.forEach(hook => hook.list.hide()); + }, + + removeEvents: function(){ + document.removeEventListener('click', this.eventWrapper.documentClicked); + }, + + changeHookList: function(trigger, list, plugins, config) { + const availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger; + + + this.hooks.forEach((hook, i) => { + hook.list.list.dataset.dropdownActive = false; + + if (hook.trigger !== availableTrigger) return; + + hook.destroy(); + this.hooks.splice(i, 1); + this.addHook(availableTrigger, list, plugins, config); + }); + }, + + addHook: function(hook, list, plugins, config) { + const availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook; + let availableList; + + if (typeof list === 'string') { + availableList = document.querySelector(list); + } else if (list instanceof Element) { + availableList = list; + } else { + availableList = document.querySelector(hook.dataset[utils.toCamelCase(DATA_TRIGGER)]); + } + + availableList.dataset.dropdownActive = true; + + const HookObject = availableHook.tagName === 'INPUT' ? HookInput : HookButton; + this.hooks.push(new HookObject(availableHook, availableList, plugins, config)); + + return this; + }, + + addHooks: function(hooks, plugins, config) { + hooks.forEach(hook => this.addHook(hook, null, plugins, config)); + return this; + }, + + setConfig: function(obj){ + this.config = obj; + }, + + fireReady: function() { + const readyEvent = new CustomEvent('ready.dl', { + detail: { + dropdown: this, + }, + }); + document.dispatchEvent(readyEvent); + + this.ready = true; + }, + + init: function (hook, list, plugins, config) { + hook ? this.addHook(hook, list, plugins, config) : this.loadStatic(); + + this.addEvents(); + + Keyboard(); + + this.fireReady(); + + this.queuedData.forEach(data => this.addData(data)); + this.queuedData = []; + + return this; + }, +}); + +export default DropLab; diff --git a/app/assets/javascripts/droplab/droplab.js b/app/assets/javascripts/droplab/droplab.js deleted file mode 100644 index 8b14191395b..00000000000 --- a/app/assets/javascripts/droplab/droplab.js +++ /dev/null @@ -1,741 +0,0 @@ -/* eslint-disable */ -// Determine where to place this -if (typeof Object.assign != 'function') { - Object.assign = function (target, varArgs) { // .length of function is 2 - 'use strict'; - if (target == null) { // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }; -} - -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.droplab = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { - templateString = items[items.length - 1].outerHTML; - } - this.templateString = templateString; - return this.templateString; - }, - - clickEvent: function(e) { - // climb up the tree to find the LI - var selected = utils.closest(e.target, 'LI'); - - if(selected) { - e.preventDefault(); - this.hide(); - var listEvent = new CustomEvent('click.dl', { - detail: { - list: this, - selected: selected, - data: e.target.dataset, - }, - }); - this.list.dispatchEvent(listEvent); - } - }, - - addEvents: function() { - this.clickWrapper = this.clickEvent.bind(this); - // event delegation. - this.list.addEventListener('click', this.clickWrapper); - }, - - toggle: function() { - if(this.hidden) { - this.show(); - } else { - this.hide(); - } - }, - - setData: function(data) { - this.data = data; - this.render(data); - }, - - addData: function(data) { - this.data = (this.data || []).concat(data); - this.render(this.data); - }, - - // call render manually on data; - render: function(data){ - // debugger - // empty the list first - var templateString = this.templateString; - var newChildren = []; - var toAppend; - - newChildren = (data ||[]).map(function(dat){ - var html = utils.t(templateString, dat); - var template = document.createElement('div'); - template.innerHTML = html; - - // Help set the image src template - var imageTags = template.querySelectorAll('img[data-src]'); - // debugger - for(var i = 0; i < imageTags.length; i++) { - var imageTag = imageTags[i]; - imageTag.src = imageTag.getAttribute('data-src'); - imageTag.removeAttribute('data-src'); - } - - if(dat.hasOwnProperty('droplab_hidden') && dat.droplab_hidden){ - template.firstChild.style.display = 'none' - }else{ - template.firstChild.style.display = 'block'; - } - return template.firstChild.outerHTML; - }); - toAppend = this.list.querySelector('ul[data-dynamic]'); - if(toAppend) { - toAppend.innerHTML = newChildren.join(''); - } else { - this.list.innerHTML = newChildren.join(''); - } - }, - - show: function() { - if (this.hidden) { - // debugger - this.list.style.display = 'block'; - this.currentIndex = 0; - this.hidden = false; - } - }, - - hide: function() { - if (!this.hidden) { - // debugger - this.list.style.display = 'none'; - this.currentIndex = 0; - this.hidden = true; - } - }, - - destroy: function() { - this.hide(); - this.list.removeEventListener('click', this.clickWrapper); - } -}); - -module.exports = DropDown; - -},{"./custom_event_polyfill":2,"./utils":10}],4:[function(require,module,exports){ -require('./window')(function(w){ - module.exports = function(deps) { - deps = deps || {}; - var window = deps.window || w; - var document = deps.document || window.document; - var CustomEvent = deps.CustomEvent || require('./custom_event_polyfill'); - var HookButton = deps.HookButton || require('./hook_button'); - var HookInput = deps.HookInput || require('./hook_input'); - var utils = deps.utils || require('./utils'); - var DATA_TRIGGER = require('./constants').DATA_TRIGGER; - - var DropLab = function(hook){ - if (!(this instanceof DropLab)) return new DropLab(hook); - this.ready = false; - this.hooks = []; - this.queuedData = []; - this.config = {}; - this.loadWrapper; - if(typeof hook !== 'undefined'){ - this.addHook(hook); - } - }; - - - Object.assign(DropLab.prototype, { - load: function() { - this.loadWrapper(); - }, - - loadWrapper: function(){ - var dropdownTriggers = [].slice.apply(document.querySelectorAll('['+DATA_TRIGGER+']')); - this.addHooks(dropdownTriggers).init(); - }, - - addData: function () { - var args = [].slice.apply(arguments); - this.applyArgs(args, '_addData'); - }, - - setData: function() { - var args = [].slice.apply(arguments); - this.applyArgs(args, '_setData'); - }, - - destroy: function() { - for(var i = 0; i < this.hooks.length; i++) { - this.hooks[i].destroy(); - } - this.hooks = []; - this.removeEvents(); - }, - - applyArgs: function(args, methodName) { - if(this.ready) { - this[methodName].apply(this, args); - } else { - this.queuedData = this.queuedData || []; - this.queuedData.push(args); - } - }, - - _addData: function(trigger, data) { - this._processData(trigger, data, 'addData'); - }, - - _setData: function(trigger, data) { - this._processData(trigger, data, 'setData'); - }, - - _processData: function(trigger, data, methodName) { - for(var i = 0; i < this.hooks.length; i++) { - var hook = this.hooks[i]; - if(hook.trigger.dataset.hasOwnProperty('id')) { - if(hook.trigger.dataset.id === trigger) { - hook.list[methodName](data); - } - } - } - }, - - addEvents: function() { - var self = this; - this.windowClickedWrapper = function(e){ - var thisTag = e.target; - if(thisTag.tagName !== 'UL'){ - // climb up the tree to find the UL - thisTag = utils.closest(thisTag, 'UL'); - } - if(utils.isDropDownParts(thisTag)){ return } - if(utils.isDropDownParts(e.target)){ return } - for(var i = 0; i < self.hooks.length; i++) { - self.hooks[i].list.hide(); - } - }.bind(this); - document.addEventListener('click', this.windowClickedWrapper); - }, - - removeEvents: function(){ - w.removeEventListener('click', this.windowClickedWrapper); - w.removeEventListener('load', this.loadWrapper); - }, - - changeHookList: function(trigger, list, plugins, config) { - trigger = document.querySelector('[data-id="'+trigger+'"]'); - // list = document.querySelector(list); - this.hooks.every(function(hook, i) { - if(hook.trigger === trigger) { - hook.destroy(); - this.hooks.splice(i, 1); - this.addHook(trigger, list, plugins, config); - return false; - } - return true - }.bind(this)); - }, - - addHook: function(hook, list, plugins, config) { - if(!(hook instanceof HTMLElement) && typeof hook === 'string'){ - hook = document.querySelector(hook); - } - if(!list){ - list = document.querySelector(hook.dataset[utils.toDataCamelCase(DATA_TRIGGER)]); - } - - if(hook) { - if(hook.tagName === 'A' || hook.tagName === 'BUTTON') { - this.hooks.push(new HookButton(hook, list, plugins, config)); - } else if(hook.tagName === 'INPUT') { - this.hooks.push(new HookInput(hook, list, plugins, config)); - } - } - return this; - }, - - addHooks: function(hooks, plugins, config) { - for(var i = 0; i < hooks.length; i++) { - var hook = hooks[i]; - this.addHook(hook, null, plugins, config); - } - return this; - }, - - setConfig: function(obj){ - this.config = obj; - }, - - init: function () { - this.addEvents(); - var readyEvent = new CustomEvent('ready.dl', { - detail: { - dropdown: this, - }, - }); - window.dispatchEvent(readyEvent); - this.ready = true; - for(var i = 0; i < this.queuedData.length; i++) { - this.addData.apply(this, this.queuedData[i]); - } - this.queuedData = []; - return this; - }, - }); - - return DropLab; - }; -}); - -},{"./constants":1,"./custom_event_polyfill":2,"./hook_button":6,"./hook_input":7,"./utils":10,"./window":11}],5:[function(require,module,exports){ -var DropDown = require('./dropdown'); - -var Hook = function(trigger, list, plugins, config){ - this.trigger = trigger; - this.list = new DropDown(list); - this.type = 'Hook'; - this.event = 'click'; - this.plugins = plugins || []; - this.config = config || {}; - this.id = trigger.dataset.id; -}; - -Object.assign(Hook.prototype, { - - addEvents: function(){}, - - constructor: Hook, -}); - -module.exports = Hook; - -},{"./dropdown":3}],6:[function(require,module,exports){ -var CustomEvent = require('./custom_event_polyfill'); -var Hook = require('./hook'); - -var HookButton = function(trigger, list, plugins, config) { - Hook.call(this, trigger, list, plugins, config); - this.type = 'button'; - this.event = 'click'; - this.addEvents(); - this.addPlugins(); -}; - -HookButton.prototype = Object.create(Hook.prototype); - -Object.assign(HookButton.prototype, { - addPlugins: function() { - for(var i = 0; i < this.plugins.length; i++) { - this.plugins[i].init(this); - } - }, - - clicked: function(e){ - var buttonEvent = new CustomEvent('click.dl', { - detail: { - hook: this, - }, - bubbles: true, - cancelable: true - }); - this.list.show(); - e.target.dispatchEvent(buttonEvent); - }, - - addEvents: function(){ - this.clickedWrapper = this.clicked.bind(this); - this.trigger.addEventListener('click', this.clickedWrapper); - }, - - removeEvents: function(){ - this.trigger.removeEventListener('click', this.clickedWrapper); - }, - - restoreInitialState: function() { - this.list.list.innerHTML = this.list.initialState; - }, - - removePlugins: function() { - for(var i = 0; i < this.plugins.length; i++) { - this.plugins[i].destroy(); - } - }, - - destroy: function() { - this.restoreInitialState(); - this.removeEvents(); - this.removePlugins(); - }, - - - constructor: HookButton, -}); - - -module.exports = HookButton; - -},{"./custom_event_polyfill":2,"./hook":5}],7:[function(require,module,exports){ -var CustomEvent = require('./custom_event_polyfill'); -var Hook = require('./hook'); - -var HookInput = function(trigger, list, plugins, config) { - Hook.call(this, trigger, list, plugins, config); - this.type = 'input'; - this.event = 'input'; - this.addPlugins(); - this.addEvents(); -}; - -Object.assign(HookInput.prototype, { - addPlugins: function() { - var self = this; - for(var i = 0; i < this.plugins.length; i++) { - this.plugins[i].init(self); - } - }, - - addEvents: function(){ - var self = this; - - this.mousedown = function mousedown(e) { - if(self.hasRemovedEvents) return; - - var mouseEvent = new CustomEvent('mousedown.dl', { - detail: { - hook: self, - text: e.target.value, - }, - bubbles: true, - cancelable: true - }); - e.target.dispatchEvent(mouseEvent); - } - - this.input = function input(e) { - if(self.hasRemovedEvents) return; - - self.list.show(); - - var inputEvent = new CustomEvent('input.dl', { - detail: { - hook: self, - text: e.target.value, - }, - bubbles: true, - cancelable: true - }); - e.target.dispatchEvent(inputEvent); - } - - this.keyup = function keyup(e) { - if(self.hasRemovedEvents) return; - - keyEvent(e, 'keyup.dl'); - } - - this.keydown = function keydown(e) { - if(self.hasRemovedEvents) return; - - keyEvent(e, 'keydown.dl'); - } - - function keyEvent(e, keyEventName){ - self.list.show(); - - var keyEvent = new CustomEvent(keyEventName, { - detail: { - hook: self, - text: e.target.value, - which: e.which, - key: e.key, - }, - bubbles: true, - cancelable: true - }); - e.target.dispatchEvent(keyEvent); - } - - this.events = this.events || {}; - this.events.mousedown = this.mousedown; - this.events.input = this.input; - this.events.keyup = this.keyup; - this.events.keydown = this.keydown; - this.trigger.addEventListener('mousedown', this.mousedown); - this.trigger.addEventListener('input', this.input); - this.trigger.addEventListener('keyup', this.keyup); - this.trigger.addEventListener('keydown', this.keydown); - }, - - removeEvents: function() { - this.hasRemovedEvents = true; - this.trigger.removeEventListener('mousedown', this.mousedown); - this.trigger.removeEventListener('input', this.input); - this.trigger.removeEventListener('keyup', this.keyup); - this.trigger.removeEventListener('keydown', this.keydown); - }, - - restoreInitialState: function() { - this.list.list.innerHTML = this.list.initialState; - }, - - removePlugins: function() { - for(var i = 0; i < this.plugins.length; i++) { - this.plugins[i].destroy(); - } - }, - - destroy: function() { - this.restoreInitialState(); - this.removeEvents(); - this.removePlugins(); - this.list.destroy(); - } -}); - -module.exports = HookInput; - -},{"./custom_event_polyfill":2,"./hook":5}],8:[function(require,module,exports){ -var DropLab = require('./droplab')(); -var DATA_TRIGGER = require('./constants').DATA_TRIGGER; -var keyboard = require('./keyboard')(); -var setup = function() { - window.DropLab = DropLab; -}; - - -module.exports = setup(); - -},{"./constants":1,"./droplab":4,"./keyboard":9}],9:[function(require,module,exports){ -require('./window')(function(w){ - module.exports = function(){ - var currentKey; - var currentFocus; - var isUpArrow = false; - var isDownArrow = false; - var removeHighlight = function removeHighlight(list) { - var listItems = Array.prototype.slice.call(list.list.querySelectorAll('li:not(.divider)'), 0); - var listItemsTmp = []; - for(var i = 0; i < listItems.length; i++) { - var listItem = listItems[i]; - listItem.classList.remove('dropdown-active'); - - if (listItem.style.display !== 'none') { - listItemsTmp.push(listItem); - } - } - return listItemsTmp; - }; - - var setMenuForArrows = function setMenuForArrows(list) { - var listItems = removeHighlight(list); - if(list.currentIndex>0){ - if(!listItems[list.currentIndex-1]){ - list.currentIndex = list.currentIndex-1; - } - - if (listItems[list.currentIndex-1]) { - var el = listItems[list.currentIndex-1]; - var filterDropdownEl = el.closest('.filter-dropdown'); - el.classList.add('dropdown-active'); - - if (filterDropdownEl) { - var filterDropdownBottom = filterDropdownEl.offsetHeight; - var elOffsetTop = el.offsetTop - 30; - - if (elOffsetTop > filterDropdownBottom) { - filterDropdownEl.scrollTop = elOffsetTop - filterDropdownBottom; - } - } - } - } - }; - - var mousedown = function mousedown(e) { - var list = e.detail.hook.list; - removeHighlight(list); - list.show(); - list.currentIndex = 0; - isUpArrow = false; - isDownArrow = false; - }; - var selectItem = function selectItem(list) { - var listItems = removeHighlight(list); - var currentItem = listItems[list.currentIndex-1]; - var listEvent = new CustomEvent('click.dl', { - detail: { - list: list, - selected: currentItem, - data: currentItem.dataset, - }, - }); - list.list.dispatchEvent(listEvent); - list.hide(); - } - - var keydown = function keydown(e){ - var typedOn = e.target; - var list = e.detail.hook.list; - var currentIndex = list.currentIndex; - isUpArrow = false; - isDownArrow = false; - - if(e.detail.which){ - currentKey = e.detail.which; - if(currentKey === 13){ - selectItem(e.detail.hook.list); - return; - } - if(currentKey === 38) { - isUpArrow = true; - } - if(currentKey === 40) { - isDownArrow = true; - } - } else if(e.detail.key) { - currentKey = e.detail.key; - if(currentKey === 'Enter'){ - selectItem(e.detail.hook.list); - return; - } - if(currentKey === 'ArrowUp') { - isUpArrow = true; - } - if(currentKey === 'ArrowDown') { - isDownArrow = true; - } - } - if(isUpArrow){ currentIndex--; } - if(isDownArrow){ currentIndex++; } - if(currentIndex < 0){ currentIndex = 0; } - list.currentIndex = currentIndex; - setMenuForArrows(e.detail.hook.list); - }; - - w.addEventListener('mousedown.dl', mousedown); - w.addEventListener('keydown.dl', keydown); - }; -}); -},{"./window":11}],10:[function(require,module,exports){ -var DATA_TRIGGER = require('./constants').DATA_TRIGGER; -var DATA_DROPDOWN = require('./constants').DATA_DROPDOWN; - -var toDataCamelCase = function(attr){ - return this.camelize(attr.split('-').slice(1).join(' ')); -}; - -// the tiniest damn templating I can do -var t = function(s,d){ - for(var p in d) - s=s.replace(new RegExp('{{'+p+'}}','g'), d[p]); - return s; -}; - -var camelize = function(str) { - return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) { - return index == 0 ? letter.toLowerCase() : letter.toUpperCase(); - }).replace(/\s+/g, ''); -}; - -var closest = function(thisTag, stopTag) { - while(thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML'){ - thisTag = thisTag.parentNode; - } - return thisTag; -}; - -var isDropDownParts = function(target) { - if(!target || target.tagName === 'HTML') { return false; } - return ( - target.hasAttribute(DATA_TRIGGER) || - target.hasAttribute(DATA_DROPDOWN) - ); -}; - -module.exports = { - toDataCamelCase: toDataCamelCase, - t: t, - camelize: camelize, - closest: closest, - isDropDownParts: isDropDownParts, -}; - -},{"./constants":1}],11:[function(require,module,exports){ -module.exports = function(callback) { - return (function() { - callback(this); - }).call(null); -}; - -},{}]},{},[8])(8) -}); diff --git a/app/assets/javascripts/droplab/droplab_ajax.js b/app/assets/javascripts/droplab/droplab_ajax.js deleted file mode 100644 index 020f8b4ac65..00000000000 --- a/app/assets/javascripts/droplab/droplab_ajax.js +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.droplab||(g.droplab = {}));g=(g.ajax||(g.ajax = {}));g=(g.datasource||(g.datasource = {}));g.js = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1; - var focusEvent = e.type === 'focus'; - - if (invalidKeyPressed || this.loading) { - return; - } - - if (this.timeout) { - clearTimeout(this.timeout); - } - - this.timeout = setTimeout(this.trigger.bind(this, focusEvent), 200); - }, - - trigger: function trigger(getEntireList) { - var config = this.hook.config.droplabAjaxFilter; - var searchValue = this.trigger.value; - - if (!config || !config.endpoint || !config.searchKey) { - return; - } - - if (config.searchValueFunction) { - searchValue = config.searchValueFunction(); - } - - if (config.loadingTemplate && this.hook.list.data === undefined || - this.hook.list.data.length === 0) { - var dynamicList = this.hook.list.list.querySelector('[data-dynamic]'); - - var loadingTemplate = document.createElement('div'); - loadingTemplate.innerHTML = config.loadingTemplate; - loadingTemplate.setAttribute('data-loading-template', true); - - this.listTemplate = dynamicList.outerHTML; - dynamicList.outerHTML = loadingTemplate.outerHTML; - } - - if (getEntireList) { - searchValue = ''; - } - - if (config.searchKey === searchValue) { - return this.list.show(); - } - - this.loading = true; - - var params = config.params || {}; - params[config.searchKey] = searchValue; - var self = this; - self.cache = self.cache || {}; - var url = config.endpoint + this.buildParams(params); - var urlCachedData = self.cache[url]; - - if (urlCachedData) { - self._loadData(urlCachedData, config, self); - } else { - this._loadUrlData(url) - .then(function(data) { - self._loadData(data, config, self); - }, function(xhrError) { - // TODO: properly handle errors due to XHR cancellation - return; - }); - } - }, - - _loadUrlData: function _loadUrlData(url) { - var self = this; - return new Promise(function(resolve, reject) { - var xhr = new XMLHttpRequest; - xhr.open('GET', url, true); - xhr.onreadystatechange = function () { - if(xhr.readyState === XMLHttpRequest.DONE) { - if (xhr.status === 200) { - var data = JSON.parse(xhr.responseText); - self.cache[url] = data; - return resolve(data); - } else { - return reject([xhr.responseText, xhr.status]); - } - } - }; - xhr.send(); - }); - }, - - _loadData: function _loadData(data, config, self) { - if (config.loadingTemplate && self.hook.list.data === undefined || - self.hook.list.data.length === 0) { - const dataLoadingTemplate = self.hook.list.list.querySelector('[data-loading-template]'); - - if (dataLoadingTemplate) { - dataLoadingTemplate.outerHTML = self.listTemplate; - } - } - - if (!self.destroyed) { - var hookListChildren = self.hook.list.list.children; - var onlyDynamicList = hookListChildren.length === 1 && hookListChildren[0].hasAttribute('data-dynamic'); - - if (onlyDynamicList && data.length === 0) { - self.hook.list.hide(); - } - - self.hook.list.setData.call(self.hook.list, data); - } - self.notLoading(); - self.hook.list.currentIndex = 0; - }, - - buildParams: function(params) { - if (!params) return ''; - var paramsArray = Object.keys(params).map(function(param) { - return param + '=' + (params[param] || ''); - }); - return '?' + paramsArray.join('&'); - }, - - destroy: function destroy() { - if (this.timeout) { - clearTimeout(this.timeout); - } - - this.destroyed = true; - - this.hook.trigger.removeEventListener('keydown.dl', this.debounceTriggerWrapper); - this.hook.trigger.removeEventListener('focus', this.debounceTriggerWrapper); - } - }; -}); -},{"../window":2}],2:[function(require,module,exports){ -module.exports = function(callback) { - return (function() { - callback(this); - }).call(null); -}; - -},{}]},{},[1])(1) -}); diff --git a/app/assets/javascripts/droplab/droplab_filter.js b/app/assets/javascripts/droplab/droplab_filter.js deleted file mode 100644 index 7f7d93f3e27..00000000000 --- a/app/assets/javascripts/droplab/droplab_filter.js +++ /dev/null @@ -1,76 +0,0 @@ -/* eslint-disable */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.droplab||(g.droplab = {}));g=(g.filter||(g.filter = {}));g.js = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o plugin.init(this)); + }, + + clicked: function(e){ + var buttonEvent = new CustomEvent('click.dl', { + detail: { + hook: this, + }, + bubbles: true, + cancelable: true + }); + e.target.dispatchEvent(buttonEvent); + + this.list.toggle(); + }, + + addEvents: function(){ + this.eventWrapper.clicked = this.clicked.bind(this); + this.trigger.addEventListener('click', this.eventWrapper.clicked); + }, + + removeEvents: function(){ + this.trigger.removeEventListener('click', this.eventWrapper.clicked); + }, + + restoreInitialState: function() { + this.list.list.innerHTML = this.list.initialState; + }, + + removePlugins: function() { + this.plugins.forEach(plugin => plugin.destroy()); + }, + + destroy: function() { + this.restoreInitialState(); + + this.removeEvents(); + this.removePlugins(); + }, + + constructor: HookButton, +}); + + +export default HookButton; diff --git a/app/assets/javascripts/droplab/hook_input.js b/app/assets/javascripts/droplab/hook_input.js new file mode 100644 index 00000000000..05082334045 --- /dev/null +++ b/app/assets/javascripts/droplab/hook_input.js @@ -0,0 +1,119 @@ +/* eslint-disable */ + +import Hook from './hook'; + +var HookInput = function(trigger, list, plugins, config) { + Hook.call(this, trigger, list, plugins, config); + + this.type = 'input'; + this.event = 'input'; + + this.eventWrapper = {}; + + this.addEvents(); + this.addPlugins(); +}; + +Object.assign(HookInput.prototype, { + addPlugins: function() { + this.plugins.forEach(plugin => plugin.init(this)); + }, + + addEvents: function(){ + this.eventWrapper.mousedown = this.mousedown.bind(this); + this.eventWrapper.input = this.input.bind(this); + this.eventWrapper.keyup = this.keyup.bind(this); + this.eventWrapper.keydown = this.keydown.bind(this); + + this.trigger.addEventListener('mousedown', this.eventWrapper.mousedown); + this.trigger.addEventListener('input', this.eventWrapper.input); + this.trigger.addEventListener('keyup', this.eventWrapper.keyup); + this.trigger.addEventListener('keydown', this.eventWrapper.keydown); + }, + + removeEvents: function() { + this.hasRemovedEvents = true; + + this.trigger.removeEventListener('mousedown', this.eventWrapper.mousedown); + this.trigger.removeEventListener('input', this.eventWrapper.input); + this.trigger.removeEventListener('keyup', this.eventWrapper.keyup); + this.trigger.removeEventListener('keydown', this.eventWrapper.keydown); + }, + + input: function(e) { + if(this.hasRemovedEvents) return; + + this.list.show(); + + const inputEvent = new CustomEvent('input.dl', { + detail: { + hook: this, + text: e.target.value, + }, + bubbles: true, + cancelable: true + }); + e.target.dispatchEvent(inputEvent); + }, + + mousedown: function(e) { + if (this.hasRemovedEvents) return; + + const mouseEvent = new CustomEvent('mousedown.dl', { + detail: { + hook: this, + text: e.target.value, + }, + bubbles: true, + cancelable: true, + }); + e.target.dispatchEvent(mouseEvent); + }, + + keyup: function(e) { + if (this.hasRemovedEvents) return; + + this.keyEvent(e, 'keyup.dl'); + }, + + keydown: function(e) { + if (this.hasRemovedEvents) return; + + this.keyEvent(e, 'keydown.dl'); + }, + + keyEvent: function(e, eventName) { + this.list.show(); + + const keyEvent = new CustomEvent(eventName, { + detail: { + hook: this, + text: e.target.value, + which: e.which, + key: e.key, + }, + bubbles: true, + cancelable: true, + }); + e.target.dispatchEvent(keyEvent); + }, + + restoreInitialState: function() { + this.list.list.innerHTML = this.list.initialState; + }, + + removePlugins: function() { + this.plugins.forEach(plugin => plugin.destroy()); + }, + + destroy: function() { + this.restoreInitialState(); + + this.removeEvents(); + this.removePlugins(); + + this.list.destroy(); + } +}); + +export default HookInput; diff --git a/app/assets/javascripts/droplab/keyboard.js b/app/assets/javascripts/droplab/keyboard.js new file mode 100644 index 00000000000..36740a430e1 --- /dev/null +++ b/app/assets/javascripts/droplab/keyboard.js @@ -0,0 +1,113 @@ +/* eslint-disable */ + +import { ACTIVE_CLASS } from './constants'; + +const Keyboard = function () { + var currentKey; + var currentFocus; + var isUpArrow = false; + var isDownArrow = false; + var removeHighlight = function removeHighlight(list) { + var itemElements = Array.prototype.slice.call(list.list.querySelectorAll('li:not(.divider)'), 0); + var listItems = []; + for(var i = 0; i < itemElements.length; i++) { + var listItem = itemElements[i]; + listItem.classList.remove(ACTIVE_CLASS); + + if (listItem.style.display !== 'none') { + listItems.push(listItem); + } + } + return listItems; + }; + + var setMenuForArrows = function setMenuForArrows(list) { + var listItems = removeHighlight(list); + if(list.currentIndex>0){ + if(!listItems[list.currentIndex-1]){ + list.currentIndex = list.currentIndex-1; + } + + if (listItems[list.currentIndex-1]) { + var el = listItems[list.currentIndex-1]; + var filterDropdownEl = el.closest('.filter-dropdown'); + el.classList.add(ACTIVE_CLASS); + + if (filterDropdownEl) { + var filterDropdownBottom = filterDropdownEl.offsetHeight; + var elOffsetTop = el.offsetTop - 30; + + if (elOffsetTop > filterDropdownBottom) { + filterDropdownEl.scrollTop = elOffsetTop - filterDropdownBottom; + } + } + } + } + }; + + var mousedown = function mousedown(e) { + var list = e.detail.hook.list; + removeHighlight(list); + list.show(); + list.currentIndex = 0; + isUpArrow = false; + isDownArrow = false; + }; + var selectItem = function selectItem(list) { + var listItems = removeHighlight(list); + var currentItem = listItems[list.currentIndex-1]; + var listEvent = new CustomEvent('click.dl', { + detail: { + list: list, + selected: currentItem, + data: currentItem.dataset, + }, + }); + list.list.dispatchEvent(listEvent); + list.hide(); + } + + var keydown = function keydown(e){ + var typedOn = e.target; + var list = e.detail.hook.list; + var currentIndex = list.currentIndex; + isUpArrow = false; + isDownArrow = false; + + if(e.detail.which){ + currentKey = e.detail.which; + if(currentKey === 13){ + selectItem(e.detail.hook.list); + return; + } + if(currentKey === 38) { + isUpArrow = true; + } + if(currentKey === 40) { + isDownArrow = true; + } + } else if(e.detail.key) { + currentKey = e.detail.key; + if(currentKey === 'Enter'){ + selectItem(e.detail.hook.list); + return; + } + if(currentKey === 'ArrowUp') { + isUpArrow = true; + } + if(currentKey === 'ArrowDown') { + isDownArrow = true; + } + } + if(isUpArrow){ currentIndex--; } + if(isDownArrow){ currentIndex++; } + if(currentIndex < 0){ currentIndex = 0; } + list.currentIndex = currentIndex; + setMenuForArrows(e.detail.hook.list); + }; + + document.addEventListener('mousedown.dl', mousedown); + document.addEventListener('keydown.dl', keydown); +}; + +export default Keyboard; diff --git a/app/assets/javascripts/droplab/plugins/ajax.js b/app/assets/javascripts/droplab/plugins/ajax.js new file mode 100644 index 00000000000..12afe53ed76 --- /dev/null +++ b/app/assets/javascripts/droplab/plugins/ajax.js @@ -0,0 +1,65 @@ +/* eslint-disable */ + +const Ajax = { + _loadUrlData: function _loadUrlData(url) { + var self = this; + return new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest; + xhr.open('GET', url, true); + xhr.onreadystatechange = function () { + if(xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 200) { + var data = JSON.parse(xhr.responseText); + self.cache[url] = data; + return resolve(data); + } else { + return reject([xhr.responseText, xhr.status]); + } + } + }; + xhr.send(); + }); + }, + _loadData: function _loadData(data, config, self) { + if (config.loadingTemplate) { + var dataLoadingTemplate = self.hook.list.list.querySelector('[data-loading-template]'); + if (dataLoadingTemplate) dataLoadingTemplate.outerHTML = self.listTemplate; + } + + if (!self.destroyed) self.hook.list[config.method].call(self.hook.list, data); + }, + init: function init(hook) { + var self = this; + self.destroyed = false; + self.cache = self.cache || {}; + var config = hook.config.Ajax; + this.hook = hook; + if (!config || !config.endpoint || !config.method) { + return; + } + if (config.method !== 'setData' && config.method !== 'addData') { + return; + } + if (config.loadingTemplate) { + var dynamicList = hook.list.list.querySelector('[data-dynamic]'); + var loadingTemplate = document.createElement('div'); + loadingTemplate.innerHTML = config.loadingTemplate; + loadingTemplate.setAttribute('data-loading-template', ''); + this.listTemplate = dynamicList.outerHTML; + dynamicList.outerHTML = loadingTemplate.outerHTML; + } + if (self.cache[config.endpoint]) { + self._loadData(self.cache[config.endpoint], config, self); + } else { + this._loadUrlData(config.endpoint) + .then(function(d) { + self._loadData(d, config, self); + }, config.onError).catch(config.onError); + } + }, + destroy: function() { + this.destroyed = true; + } +}; + +export default Ajax; diff --git a/app/assets/javascripts/droplab/plugins/ajax_filter.js b/app/assets/javascripts/droplab/plugins/ajax_filter.js new file mode 100644 index 00000000000..cfd7e2ca189 --- /dev/null +++ b/app/assets/javascripts/droplab/plugins/ajax_filter.js @@ -0,0 +1,133 @@ +/* eslint-disable */ + +const AjaxFilter = { + init: function(hook) { + this.destroyed = false; + this.hook = hook; + this.notLoading(); + + this.eventWrapper = {}; + this.eventWrapper.debounceTrigger = this.debounceTrigger.bind(this); + this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceTrigger); + this.hook.trigger.addEventListener('focus', this.eventWrapper.debounceTrigger); + + this.trigger(true); + }, + + notLoading: function notLoading() { + this.loading = false; + }, + + debounceTrigger: function debounceTrigger(e) { + var NON_CHARACTER_KEYS = [16, 17, 18, 20, 37, 38, 39, 40, 91, 93]; + var invalidKeyPressed = NON_CHARACTER_KEYS.indexOf(e.detail.which || e.detail.keyCode) > -1; + var focusEvent = e.type === 'focus'; + if (invalidKeyPressed || this.loading) { + return; + } + if (this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(this.trigger.bind(this, focusEvent), 200); + }, + + trigger: function trigger(getEntireList) { + var config = this.hook.config.AjaxFilter; + var searchValue = this.trigger.value; + if (!config || !config.endpoint || !config.searchKey) { + return; + } + if (config.searchValueFunction) { + searchValue = config.searchValueFunction(); + } + if (config.loadingTemplate && this.hook.list.data === undefined || + this.hook.list.data.length === 0) { + var dynamicList = this.hook.list.list.querySelector('[data-dynamic]'); + var loadingTemplate = document.createElement('div'); + loadingTemplate.innerHTML = config.loadingTemplate; + loadingTemplate.setAttribute('data-loading-template', true); + this.listTemplate = dynamicList.outerHTML; + dynamicList.outerHTML = loadingTemplate.outerHTML; + } + if (getEntireList) { + searchValue = ''; + } + if (config.searchKey === searchValue) { + return this.list.show(); + } + this.loading = true; + var params = config.params || {}; + params[config.searchKey] = searchValue; + var self = this; + self.cache = self.cache || {}; + var url = config.endpoint + this.buildParams(params); + var urlCachedData = self.cache[url]; + if (urlCachedData) { + self._loadData(urlCachedData, config, self); + } else { + this._loadUrlData(url) + .then(function(data) { + self._loadData(data, config, self); + }, config.onError).catch(config.onError); + } + }, + + _loadUrlData: function _loadUrlData(url) { + var self = this; + return new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest; + xhr.open('GET', url, true); + xhr.onreadystatechange = function () { + if(xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 200) { + var data = JSON.parse(xhr.responseText); + self.cache[url] = data; + return resolve(data); + } else { + return reject([xhr.responseText, xhr.status]); + } + } + }; + xhr.send(); + }); + }, + + _loadData: function _loadData(data, config, self) { + const list = self.hook.list; + if (config.loadingTemplate && list.data === undefined || + list.data.length === 0) { + const dataLoadingTemplate = list.list.querySelector('[data-loading-template]'); + if (dataLoadingTemplate) { + dataLoadingTemplate.outerHTML = self.listTemplate; + } + } + if (!self.destroyed) { + var hookListChildren = list.list.children; + var onlyDynamicList = hookListChildren.length === 1 && hookListChildren[0].hasAttribute('data-dynamic'); + if (onlyDynamicList && data.length === 0) { + list.hide(); + } + list.setData.call(list, data); + } + self.notLoading(); + list.currentIndex = 0; + }, + + buildParams: function(params) { + if (!params) return ''; + var paramsArray = Object.keys(params).map(function(param) { + return param + '=' + (params[param] || ''); + }); + return '?' + paramsArray.join('&'); + }, + + destroy: function destroy() { + if (this.timeout)clearTimeout(this.timeout); + this.destroyed = true; + + this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceTrigger); + this.hook.trigger.removeEventListener('focus', this.eventWrapper.debounceTrigger); + } +}; + +export default AjaxFilter; diff --git a/app/assets/javascripts/droplab/plugins/filter.js b/app/assets/javascripts/droplab/plugins/filter.js new file mode 100644 index 00000000000..d6a1aadd49c --- /dev/null +++ b/app/assets/javascripts/droplab/plugins/filter.js @@ -0,0 +1,95 @@ +/* eslint-disable */ + +const Filter = { + keydown: function(e){ + if (this.destroyed) return; + + var hiddenCount = 0; + var dataHiddenCount = 0; + + var list = e.detail.hook.list; + var data = list.data; + var value = e.detail.hook.trigger.value.toLowerCase(); + var config = e.detail.hook.config.Filter; + var matches = []; + var filterFunction; + // will only work on dynamically set data + if(!data){ + return; + } + + if (config && config.filterFunction && typeof config.filterFunction === 'function') { + filterFunction = config.filterFunction; + } else { + filterFunction = function(o){ + // cheap string search + o.droplab_hidden = o[config.template].toLowerCase().indexOf(value) === -1; + return o; + }; + } + + dataHiddenCount = data.filter(function(o) { + return !o.droplab_hidden; + }).length; + + matches = data.map(function(o) { + return filterFunction(o, value); + }); + + hiddenCount = matches.filter(function(o) { + return !o.droplab_hidden; + }).length; + + if (dataHiddenCount !== hiddenCount) { + list.setData(matches); + list.currentIndex = 0; + } + }, + + debounceKeydown: function debounceKeydown(e) { + if ([ + 13, // enter + 16, // shift + 17, // ctrl + 18, // alt + 20, // caps lock + 37, // left arrow + 38, // up arrow + 39, // right arrow + 40, // down arrow + 91, // left window + 92, // right window + 93, // select + ].indexOf(e.detail.which || e.detail.keyCode) > -1) return; + + if (this.timeout) clearTimeout(this.timeout); + this.timeout = setTimeout(this.keydown.bind(this, e), 200); + }, + + init: function init(hook) { + var config = hook.config.Filter; + + if (!config || !config.template) return; + + this.hook = hook; + this.destroyed = false; + + this.eventWrapper = {}; + this.eventWrapper.debounceKeydown = this.debounceKeydown.bind(this); + + this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown); + this.hook.trigger.addEventListener('mousedown.dl', this.eventWrapper.debounceKeydown); + + this.debounceKeydown({ detail: { hook: this.hook } }); + }, + + destroy: function destroy() { + if (this.timeout) clearTimeout(this.timeout); + this.destroyed = true; + + this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceKeydown); + this.hook.trigger.removeEventListener('mousedown.dl', this.eventWrapper.debounceKeydown); + } +}; + +export default Filter; diff --git a/app/assets/javascripts/droplab/plugins/input_setter.js b/app/assets/javascripts/droplab/plugins/input_setter.js new file mode 100644 index 00000000000..c292cfa7b8f --- /dev/null +++ b/app/assets/javascripts/droplab/plugins/input_setter.js @@ -0,0 +1,52 @@ +/* eslint-disable */ + +const InputSetter = { + init(hook) { + this.hook = hook; + this.destroyed = false; + this.config = hook.config.InputSetter || (this.hook.config.InputSetter = {}); + + this.eventWrapper = {}; + + this.addEvents(); + }, + + addEvents() { + this.eventWrapper.setInputs = this.setInputs.bind(this); + this.hook.list.list.addEventListener('click.dl', this.eventWrapper.setInputs); + }, + + removeEvents() { + this.hook.list.list.removeEventListener('click.dl', this.eventWrapper.setInputs); + }, + + setInputs(e) { + if (this.destroyed) return; + + const selectedItem = e.detail.selected; + + if (!Array.isArray(this.config)) this.config = [this.config]; + + this.config.forEach(config => this.setInput(config, selectedItem)); + }, + + setInput(config, selectedItem) { + const input = config.input || this.hook.trigger; + const newValue = selectedItem.getAttribute(config.valueAttribute); + const inputAttribute = config.inputAttribute; + + if (!newValue) return; + + if (input.hasAttribute(inputAttribute)) return input.setAttribute(inputAttribute, newValue); + if (input.tagName === 'INPUT') return input.value = newValue; + return input.textContent = newValue; + }, + + destroy() { + this.destroyed = true; + + this.removeEvents(); + }, +}; + +export default InputSetter; diff --git a/app/assets/javascripts/droplab/utils.js b/app/assets/javascripts/droplab/utils.js new file mode 100644 index 00000000000..c149a33a1e9 --- /dev/null +++ b/app/assets/javascripts/droplab/utils.js @@ -0,0 +1,38 @@ +/* eslint-disable */ + +import { DATA_TRIGGER, DATA_DROPDOWN } from './constants'; + +const utils = { + toCamelCase(attr) { + return this.camelize(attr.split('-').slice(1).join(' ')); + }, + + t(s, d) { + for (const p in d) { + if (Object.prototype.hasOwnProperty.call(d, p)) { + s = s.replace(new RegExp(`{{${p}}}`, 'g'), d[p]); + } + } + return s; + }, + + camelize(str) { + return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => { + return index === 0 ? letter.toLowerCase() : letter.toUpperCase(); + }).replace(/\s+/g, ''); + }, + + closest(thisTag, stopTag) { + while (thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML') { + thisTag = thisTag.parentNode; + } + return thisTag; + }, + + isDropDownParts(target) { + if (!target || target.tagName === 'HTML') return false; + return target.hasAttribute(DATA_TRIGGER) || target.hasAttribute(DATA_DROPDOWN); + }, +}; + +export default utils; diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js b/app/assets/javascripts/filtered_search/dropdown_hint.js index 64d7153e547..381c40c03d8 100644 --- a/app/assets/javascripts/filtered_search/dropdown_hint.js +++ b/app/assets/javascripts/filtered_search/dropdown_hint.js @@ -1,13 +1,13 @@ -require('./filtered_search_dropdown'); +import Filter from '~/droplab/plugins/filter'; -/* global droplabFilter */ +require('./filtered_search_dropdown'); (() => { class DropdownHint extends gl.FilteredSearchDropdown { constructor(droplab, dropdown, input, filter) { super(droplab, dropdown, input, filter); this.config = { - droplabFilter: { + Filter: { template: 'hint', filterFunction: gl.DropdownUtils.filterHint.bind(null, input), }, @@ -69,12 +69,12 @@ require('./filtered_search_dropdown'); } }); - this.droplab.changeHookList(this.hookId, this.dropdown, [droplabFilter], this.config); + this.droplab.changeHookList(this.hookId, this.dropdown, [Filter], this.config); this.droplab.setData(this.hookId, dropdownData); } init() { - this.droplab.addHook(this.input, this.dropdown, [droplabFilter], this.config).init(); + this.droplab.addHook(this.input, this.dropdown, [Filter], this.config).init(); } } diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js b/app/assets/javascripts/filtered_search/dropdown_non_user.js index b3dc3e502c5..6296965b911 100644 --- a/app/assets/javascripts/filtered_search/dropdown_non_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js @@ -1,7 +1,9 @@ -require('./filtered_search_dropdown'); +/* global Flash */ + +import Ajax from '~/droplab/plugins/ajax'; +import Filter from '~/droplab/plugins/filter'; -/* global droplabAjax */ -/* global droplabFilter */ +require('./filtered_search_dropdown'); (() => { class DropdownNonUser extends gl.FilteredSearchDropdown { @@ -9,13 +11,19 @@ require('./filtered_search_dropdown'); super(droplab, dropdown, input, filter); this.symbol = symbol; this.config = { - droplabAjax: { + Ajax: { endpoint, method: 'setData', loadingTemplate: this.loadingTemplate, + onError() { + /* eslint-disable no-new */ + new Flash('An error occured fetching the dropdown data.'); + /* eslint-enable no-new */ + }, }, - droplabFilter: { + Filter: { filterFunction: gl.DropdownUtils.filterWithSymbol.bind(null, this.symbol, input), + template: 'title', }, }; } @@ -29,13 +37,13 @@ require('./filtered_search_dropdown'); renderContent(forceShowList = false) { this.droplab - .changeHookList(this.hookId, this.dropdown, [droplabAjax, droplabFilter], this.config); + .changeHookList(this.hookId, this.dropdown, [Ajax, Filter], this.config); super.renderContent(forceShowList); } init() { this.droplab - .addHook(this.input, this.dropdown, [droplabAjax, droplabFilter], this.config).init(); + .addHook(this.input, this.dropdown, [Ajax, Filter], this.config).init(); } } diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js index 04e2afad02f..38b5d315bcf 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_user.js @@ -1,13 +1,15 @@ -require('./filtered_search_dropdown'); +/* global Flash */ + +import AjaxFilter from '~/droplab/plugins/ajax_filter'; -/* global droplabAjaxFilter */ +require('./filtered_search_dropdown'); (() => { class DropdownUser extends gl.FilteredSearchDropdown { constructor(droplab, dropdown, input, filter) { super(droplab, dropdown, input, filter); this.config = { - droplabAjaxFilter: { + AjaxFilter: { endpoint: `${gon.relative_url_root || ''}/autocomplete/users.json`, searchKey: 'search', params: { @@ -18,6 +20,11 @@ require('./filtered_search_dropdown'); }, searchValueFunction: this.getSearchInput.bind(this), loadingTemplate: this.loadingTemplate, + onError() { + /* eslint-disable no-new */ + new Flash('An error occured fetching the dropdown data.'); + /* eslint-enable no-new */ + }, }, }; } @@ -28,7 +35,7 @@ require('./filtered_search_dropdown'); } renderContent(forceShowList = false) { - this.droplab.changeHookList(this.hookId, this.dropdown, [droplabAjaxFilter], this.config); + this.droplab.changeHookList(this.hookId, this.dropdown, [AjaxFilter], this.config); super.renderContent(forceShowList); } @@ -56,7 +63,7 @@ require('./filtered_search_dropdown'); } init() { - this.droplab.addHook(this.input, this.dropdown, [droplabAjaxFilter], this.config).init(); + this.droplab.addHook(this.input, this.dropdown, [AjaxFilter], this.config).init(); } } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js index e7bf530d343..d58eeeebf81 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js @@ -4,7 +4,7 @@ class FilteredSearchDropdown { constructor(droplab, dropdown, input, filter) { this.droplab = droplab; - this.hookId = input && input.getAttribute('data-id'); + this.hookId = input && input.id; this.input = input; this.filter = filter; this.dropdown = dropdown; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index 5fbe0450bb8..ec481b9ef97 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -1,4 +1,4 @@ -/* global DropLab */ +import DropLab from '~/droplab/drop_lab'; import FilteredSearchContainer from './container'; (() => { diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 2a8a6b81b3f..b93a8f1d322 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -154,7 +154,7 @@ import eventHub from './event_hub'; if (e.keyCode === 13) { const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; const dropdownEl = dropdown.element; - const activeElements = dropdownEl.querySelectorAll('.dropdown-active'); + const activeElements = dropdownEl.querySelectorAll('.droplab-item-active'); e.preventDefault(); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 5b50bc62876..177cf66b37d 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -75,12 +75,6 @@ import './u2f/error'; import './u2f/register'; import './u2f/util'; -// droplab -import './droplab/droplab'; -import './droplab/droplab_ajax'; -import './droplab/droplab_ajax_filter'; -import './droplab/droplab_filter'; - // everything else import './abuse_reports'; import './activities'; diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 484df6214d3..12465d4a70b 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -446,10 +446,8 @@ } } -.filter-dropdown-item.dropdown-active { - .btn { - @extend %filter-dropdown-item-btn-hover; - } +.filter-dropdown-item.droplab-item-active .btn { + @extend %filter-dropdown-item-btn-hover; } .filter-dropdown-loading { diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 9e241c3ea12..b447996a8ab 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -23,7 +23,7 @@ .scroll-container %ul.tokens-container.list-unstyled %li.input-token - %input.form-control.filtered-search{ placeholder: 'Search or filter results...', data: { id: "filtered-search-#{type.to_s}", 'project-id' => @project.id, 'username-params' => @users.to_json(only: [:id, :username]), 'base-endpoint' => namespace_project_path(@project.namespace, @project) } } + %input.form-control.filtered-search{ id: "filtered-search-#{type.to_s}", placeholder: 'Search or filter results...', data: { 'project-id' => @project.id, 'username-params' => @users.to_json(only: [:id, :username]), 'base-endpoint' => namespace_project_path(@project.namespace, @project) } } = icon('filter') %button.clear-search.hidden{ type: 'button' } = icon('times') diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index bc8cbe30e66..cae01f37b6b 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'Dropdown hint', js: true, feature: true do +describe 'Dropdown hint', :js, :feature do include FilteredSearchHelpers include WaitForAjax @@ -9,10 +9,6 @@ describe 'Dropdown hint', js: true, feature: true do let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_hint) { '#js-dropdown-hint' } - def dropdown_hint_size - page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size - end - def click_hint(text) find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: text).click end @@ -46,14 +42,16 @@ describe 'Dropdown hint', js: true, feature: true do it 'does not filter `Press Enter or click to search`' do filtered_search.set('randomtext') - expect(page).to have_css(js_dropdown_hint, text: 'Press Enter or click to search', visible: false) - expect(dropdown_hint_size).to eq(0) + hint_dropdown = find(js_dropdown_hint) + + expect(hint_dropdown).to have_content('Press Enter or click to search') + expect(hint_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 0) end it 'filters with text' do filtered_search.set('a') - expect(dropdown_hint_size).to eq(3) + expect(find(js_dropdown_hint)).to have_selector('.filter-dropdown .filter-dropdown-item', count: 3) end end diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index c8645e08c4b..abe5d61e38c 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -28,10 +28,6 @@ describe 'Dropdown label', js: true, feature: true do filter_dropdown.find('.filter-dropdown-item', text: text).click end - def dropdown_label_size - filter_dropdown.all('.filter-dropdown-item').size - end - def clear_search_field find('.filtered-search-box .clear-search').click end @@ -81,7 +77,7 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.set('label:') expect(filter_dropdown).to have_content(bug_label.title) - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end @@ -97,7 +93,8 @@ describe 'Dropdown label', js: true, feature: true do expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible - expect(dropdown_label_size).to eq(2) + + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2) clear_search_field init_label_search @@ -106,14 +103,14 @@ describe 'Dropdown label', js: true, feature: true do expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible - expect(dropdown_label_size).to eq(2) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2) end it 'filters by multiple words with or without symbol' do filtered_search.send_keys('Hig') expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -121,14 +118,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~Hig') expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by multiple words containing single quotes with or without symbol' do filtered_search.send_keys('won\'t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -136,14 +133,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~won\'t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by multiple words containing double quotes with or without symbol' do filtered_search.send_keys('won"t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -151,14 +148,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~won"t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by special characters with or without symbol' do filtered_search.send_keys('^+') expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -166,7 +163,7 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~^+') expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end @@ -280,13 +277,13 @@ describe 'Dropdown label', js: true, feature: true do create(:label, project: project, title: 'bug-label') init_label_search - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) create(:label, project: project) clear_search_field init_label_search - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end end diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index 0a525bc68c9..448259057b0 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -65,7 +65,7 @@ describe 'Dropdown milestone', :feature, :js do it 'should load all the milestones when opened' do filtered_search.set('milestone:') - expect(dropdown_milestone_size).to be > 0 + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6) end end @@ -84,37 +84,37 @@ describe 'Dropdown milestone', :feature, :js do it 'filters by name' do filtered_search.send_keys('v1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by case insensitive name' do filtered_search.send_keys('V1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by name with symbol' do filtered_search.send_keys('%v1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by case insensitive name with symbol' do filtered_search.send_keys('%V1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by special characters' do filtered_search.send_keys('(+') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by special characters with symbol' do filtered_search.send_keys('%(+') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end end diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 48e7af67616..28137f11b92 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -26,7 +26,7 @@ describe 'Search bar', js: true, feature: true do filtered_search.native.send_keys(:down) page.within '#js-dropdown-hint' do - expect(page).to have_selector('.dropdown-active') + expect(page).to have_selector('.droplab-item-active') end end @@ -79,28 +79,30 @@ describe 'Search bar', js: true, feature: true do filtered_search.set('author') - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(1) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) find('.filtered-search-box .clear-search').click filtered_search.click - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(original_size) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size) end it 'resets the dropdown filters' do + filtered_search.click + + hint_offset = get_left_style(find('#js-dropdown-hint')['style']) + filtered_search.set('a') - hint_style = page.find('#js-dropdown-hint')['style'] - hint_offset = get_left_style(hint_style) filtered_search.set('author:') - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(0) + find('#js-dropdown-hint', visible: false) find('.filtered-search-box .clear-search').click filtered_search.click - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to be > 0 - expect(get_left_style(page.find('#js-dropdown-hint')['style'])).to eq(hint_offset) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 4) + expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset) end end end diff --git a/spec/javascripts/droplab/constants_spec.js b/spec/javascripts/droplab/constants_spec.js new file mode 100644 index 00000000000..35239e4fb8e --- /dev/null +++ b/spec/javascripts/droplab/constants_spec.js @@ -0,0 +1,29 @@ +/* eslint-disable */ + +import * as constants from '~/droplab/constants'; + +describe('constants', function () { + describe('DATA_TRIGGER', function () { + it('should be `data-dropdown-trigger`', function() { + expect(constants.DATA_TRIGGER).toBe('data-dropdown-trigger'); + }); + }); + + describe('DATA_DROPDOWN', function () { + it('should be `data-dropdown`', function() { + expect(constants.DATA_DROPDOWN).toBe('data-dropdown'); + }); + }); + + describe('SELECTED_CLASS', function () { + it('should be `droplab-item-selected`', function() { + expect(constants.SELECTED_CLASS).toBe('droplab-item-selected'); + }); + }); + + describe('ACTIVE_CLASS', function () { + it('should be `droplab-item-active`', function() { + expect(constants.ACTIVE_CLASS).toBe('droplab-item-active'); + }); + }); +}); diff --git a/spec/javascripts/droplab/drop_down_spec.js b/spec/javascripts/droplab/drop_down_spec.js new file mode 100644 index 00000000000..bbf953658c8 --- /dev/null +++ b/spec/javascripts/droplab/drop_down_spec.js @@ -0,0 +1,578 @@ +/* eslint-disable */ + +import DropDown from '~/droplab/drop_down'; +import utils from '~/droplab/utils'; +import { SELECTED_CLASS } from '~/droplab/constants'; + +describe('DropDown', function () { + describe('class constructor', function () { + beforeEach(function () { + spyOn(DropDown.prototype, 'getItems'); + spyOn(DropDown.prototype, 'initTemplateString'); + spyOn(DropDown.prototype, 'addEvents'); + + this.list = { innerHTML: 'innerHTML' }; + this.dropdown = new DropDown(this.list); + }); + + it('sets the .hidden property to true', function () { + expect(this.dropdown.hidden).toBe(true); + }) + + it('sets the .list property', function () { + expect(this.dropdown.list).toBe(this.list); + }); + + it('calls .getItems', function () { + expect(DropDown.prototype.getItems).toHaveBeenCalled(); + }); + + it('calls .initTemplateString', function () { + expect(DropDown.prototype.initTemplateString).toHaveBeenCalled(); + }); + + it('calls .addEvents', function () { + expect(DropDown.prototype.addEvents).toHaveBeenCalled(); + }); + + it('sets the .initialState property to the .list.innerHTML', function () { + expect(this.dropdown.initialState).toBe(this.list.innerHTML); + }); + + describe('if the list argument is a string', function () { + beforeEach(function () { + this.element = {}; + this.selector = '.selector'; + + spyOn(Document.prototype, 'querySelector').and.returnValue(this.element); + + this.dropdown = new DropDown(this.selector); + }); + + it('calls .querySelector with the selector string', function () { + expect(Document.prototype.querySelector).toHaveBeenCalledWith(this.selector); + }); + + it('sets the .list property element', function () { + expect(this.dropdown.list).toBe(this.element); + }); + }); + }); + + describe('getItems', function () { + beforeEach(function () { + this.list = { querySelectorAll: () => {} }; + this.dropdown = { list: this.list }; + this.nodeList = []; + + spyOn(this.list, 'querySelectorAll').and.returnValue(this.nodeList); + + this.getItems = DropDown.prototype.getItems.call(this.dropdown); + }); + + it('calls .querySelectorAll with a list item query', function () { + expect(this.list.querySelectorAll).toHaveBeenCalledWith('li'); + }); + + it('sets the .items property to the returned list items', function () { + expect(this.dropdown.items).toEqual(jasmine.any(Array)); + }); + + it('returns the .items', function () { + expect(this.getItems).toEqual(jasmine.any(Array)); + }); + }); + + describe('initTemplateString', function () { + beforeEach(function () { + this.items = [{ outerHTML: '' }, { outerHTML: '' }]; + this.dropdown = { items: this.items }; + + DropDown.prototype.initTemplateString.call(this.dropdown); + }); + + it('should set .templateString to the last items .outerHTML', function () { + expect(this.dropdown.templateString).toBe(this.items[1].outerHTML); + }); + + it('should not set .templateString to a non-last items .outerHTML', function () { + expect(this.dropdown.templateString).not.toBe(this.items[0].outerHTML); + }); + + describe('if .items is not set', function () { + beforeEach(function () { + this.dropdown = { getItems: () => {} }; + + spyOn(this.dropdown, 'getItems').and.returnValue([]); + + DropDown.prototype.initTemplateString.call(this.dropdown); + }); + + it('should call .getItems', function () { + expect(this.dropdown.getItems).toHaveBeenCalled(); + }); + }); + + describe('if items array is empty', function () { + beforeEach(function () { + this.dropdown = { items: [] }; + + DropDown.prototype.initTemplateString.call(this.dropdown); + }); + + it('should set .templateString to an empty string', function () { + expect(this.dropdown.templateString).toBe(''); + }); + }); + }); + + describe('clickEvent', function () { + beforeEach(function () { + this.list = { dispatchEvent: () => {} }; + this.dropdown = { hide: () => {}, list: this.list, addSelectedClass: () => {} }; + this.event = { preventDefault: () => {}, target: 'target' }; + this.customEvent = {}; + this.closestElement = {}; + + spyOn(this.dropdown, 'hide'); + spyOn(this.dropdown, 'addSelectedClass'); + spyOn(this.list, 'dispatchEvent'); + spyOn(this.event, 'preventDefault'); + spyOn(window, 'CustomEvent').and.returnValue(this.customEvent); + spyOn(utils, 'closest').and.returnValues(this.closestElement, undefined); + + DropDown.prototype.clickEvent.call(this.dropdown, this.event); + }); + + it('should call utils.closest', function () { + expect(utils.closest).toHaveBeenCalledWith(this.event.target, 'LI'); + }); + + it('should call addSelectedClass', function () { + expect(this.dropdown.addSelectedClass).toHaveBeenCalledWith(this.closestElement); + }) + + it('should call .preventDefault', function () { + expect(this.event.preventDefault).toHaveBeenCalled(); + }); + + it('should call .hide', function () { + expect(this.dropdown.hide).toHaveBeenCalled(); + }); + + it('should construct CustomEvent', function () { + expect(window.CustomEvent).toHaveBeenCalledWith('click.dl', jasmine.any(Object)); + }); + + it('should call .dispatchEvent with the customEvent', function () { + expect(this.list.dispatchEvent).toHaveBeenCalledWith(this.customEvent); + }); + + describe('if no selected element exists', function () { + beforeEach(function () { + this.event.preventDefault.calls.reset(); + this.clickEvent = DropDown.prototype.clickEvent.call(this.dropdown, this.event); + }); + + it('should return undefined', function () { + expect(this.clickEvent).toBe(undefined); + }); + + it('should return before .preventDefault is called', function () { + expect(this.event.preventDefault).not.toHaveBeenCalled(); + }); + }); + }); + + describe('addSelectedClass', function () { + beforeEach(function () { + this.items = Array(4).forEach((item, i) => { + this.items[i] = { classList: { add: () => {} } }; + spyOn(this.items[i].classList, 'add'); + }); + this.selected = { classList: { add: () => {} } }; + this.dropdown = { removeSelectedClasses: () => {} }; + + spyOn(this.dropdown, 'removeSelectedClasses'); + spyOn(this.selected.classList, 'add'); + + DropDown.prototype.addSelectedClass.call(this.dropdown, this.selected); + }); + + it('should call .removeSelectedClasses', function () { + expect(this.dropdown.removeSelectedClasses).toHaveBeenCalled(); + }); + + it('should call .classList.add', function () { + expect(this.selected.classList.add).toHaveBeenCalledWith(SELECTED_CLASS); + }); + }); + + describe('removeSelectedClasses', function () { + beforeEach(function () { + this.items = Array(4); + this.items.forEach((item, i) => { + this.items[i] = { classList: { add: () => {} } }; + spyOn(this.items[i].classList, 'add'); + }); + this.dropdown = { items: this.items }; + + DropDown.prototype.removeSelectedClasses.call(this.dropdown); + }); + + it('should call .classList.remove for all items', function () { + this.items.forEach((item, i) => { + expect(this.items[i].classList.add).toHaveBeenCalledWith(SELECTED_CLASS); + }); + }); + + describe('if .items is not set', function () { + beforeEach(function () { + this.dropdown = { getItems: () => {} }; + + spyOn(this.dropdown, 'getItems').and.returnValue([]); + + DropDown.prototype.removeSelectedClasses.call(this.dropdown); + }); + + it('should call .getItems', function () { + expect(this.dropdown.getItems).toHaveBeenCalled(); + }); + }); + }); + + describe('addEvents', function () { + beforeEach(function () { + this.list = { addEventListener: () => {} }; + this.dropdown = { list: this.list, clickEvent: () => {}, eventWrapper: {} }; + + spyOn(this.list, 'addEventListener'); + + DropDown.prototype.addEvents.call(this.dropdown); + }); + + it('should call .addEventListener', function () { + expect(this.list.addEventListener).toHaveBeenCalledWith('click', jasmine.any(Function)); + }); + }); + + describe('toggle', function () { + beforeEach(function () { + this.dropdown = { hidden: true, show: () => {}, hide: () => {} }; + + spyOn(this.dropdown, 'show'); + spyOn(this.dropdown, 'hide'); + + DropDown.prototype.toggle.call(this.dropdown); + }); + + it('should call .show if hidden is true', function () { + expect(this.dropdown.show).toHaveBeenCalled(); + }); + + describe('if hidden is false', function () { + beforeEach(function () { + this.dropdown = { hidden: false, show: () => {}, hide: () => {} }; + + spyOn(this.dropdown, 'show'); + spyOn(this.dropdown, 'hide'); + + DropDown.prototype.toggle.call(this.dropdown); + }); + + it('should call .show if hidden is true', function () { + expect(this.dropdown.hide).toHaveBeenCalled(); + }); + }); + }); + + describe('setData', function () { + beforeEach(function () { + this.dropdown = { render: () => {} }; + this.data = ['data']; + + spyOn(this.dropdown, 'render'); + + DropDown.prototype.setData.call(this.dropdown, this.data); + }); + + it('should set .data', function () { + expect(this.dropdown.data).toBe(this.data); + }); + + it('should call .render with the .data', function () { + expect(this.dropdown.render).toHaveBeenCalledWith(this.data); + }); + }); + + describe('addData', function () { + beforeEach(function () { + this.dropdown = { render: () => {}, data: ['data1'] }; + this.data = ['data2']; + + spyOn(this.dropdown, 'render'); + spyOn(Array.prototype, 'concat').and.callThrough(); + + DropDown.prototype.addData.call(this.dropdown, this.data); + }); + + it('should call .concat with data', function () { + expect(Array.prototype.concat).toHaveBeenCalledWith(this.data); + }); + + it('should set .data with concatination', function () { + expect(this.dropdown.data).toEqual(['data1', 'data2']); + }); + + it('should call .render with the .data', function () { + expect(this.dropdown.render).toHaveBeenCalledWith(['data1', 'data2']); + }); + + describe('if .data is undefined', function () { + beforeEach(function () { + this.dropdown = { render: () => {}, data: undefined }; + this.data = ['data2']; + + spyOn(this.dropdown, 'render'); + + DropDown.prototype.addData.call(this.dropdown, this.data); + }); + + it('should set .data with concatination', function () { + expect(this.dropdown.data).toEqual(['data2']); + }); + }); + }); + + describe('render', function () { + beforeEach(function () { + this.list = { querySelector: () => {} }; + this.dropdown = { renderChildren: () => {}, list: this.list }; + this.renderableList = {}; + this.data = [0, 1]; + + spyOn(this.dropdown, 'renderChildren').and.callFake(data => data); + spyOn(this.list, 'querySelector').and.returnValue(this.renderableList); + spyOn(this.data, 'map').and.callThrough(); + + DropDown.prototype.render.call(this.dropdown, this.data); + }); + + it('should call .map', function () { + expect(this.data.map).toHaveBeenCalledWith(jasmine.any(Function)); + }); + + it('should call .renderChildren for each data item', function() { + expect(this.dropdown.renderChildren.calls.count()).toBe(this.data.length); + }); + + it('sets the renderableList .innerHTML', function () { + expect(this.renderableList.innerHTML).toBe('01'); + }); + + describe('if no data argument is passed' , function () { + beforeEach(function () { + this.data.map.calls.reset(); + this.dropdown.renderChildren.calls.reset(); + + DropDown.prototype.render.call(this.dropdown, undefined); + }); + + it('should not call .map', function () { + expect(this.data.map).not.toHaveBeenCalled(); + }); + + it('should not call .renderChildren', function () { + expect(this.dropdown.renderChildren).not.toHaveBeenCalled(); + }); + }); + + describe('if no dynamic list is present', function () { + beforeEach(function () { + this.list = { querySelector: () => {} }; + this.dropdown = { renderChildren: () => {}, list: this.list }; + this.data = [0, 1]; + + spyOn(this.dropdown, 'renderChildren').and.callFake(data => data); + spyOn(this.list, 'querySelector'); + spyOn(this.data, 'map').and.callThrough(); + + DropDown.prototype.render.call(this.dropdown, this.data); + }); + + it('sets the .list .innerHTML', function () { + expect(this.list.innerHTML).toBe('01'); + }); + }); + }); + + describe('renderChildren', function () { + beforeEach(function () { + this.templateString = 'templateString'; + this.dropdown = { setImagesSrc: () => {}, templateString: this.templateString }; + this.data = { droplab_hidden: true }; + this.html = 'html'; + this.template = { firstChild: { outerHTML: 'outerHTML', style: {} } }; + + spyOn(utils, 't').and.returnValue(this.html); + spyOn(document, 'createElement').and.returnValue(this.template); + spyOn(this.dropdown, 'setImagesSrc'); + + this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data); + }); + + it('should call utils.t with .templateString and data', function () { + expect(utils.t).toHaveBeenCalledWith(this.templateString, this.data); + }); + + it('should call document.createElement', function () { + expect(document.createElement).toHaveBeenCalledWith('div'); + }); + + it('should set the templates .innerHTML to the HTML', function () { + expect(this.template.innerHTML).toBe(this.html); + }); + + it('should call .setImagesSrc with the template', function () { + expect(this.dropdown.setImagesSrc).toHaveBeenCalledWith(this.template); + }); + + it('should set the template display to none', function () { + expect(this.template.firstChild.style.display).toBe('none'); + }); + + it('should return the templates .firstChild.outerHTML', function () { + expect(this.renderChildren).toBe(this.template.firstChild.outerHTML); + }); + + describe('if droplab_hidden is false', function () { + beforeEach(function () { + this.data = { droplab_hidden: false }; + this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data); + }); + + it('should set the template display to block', function () { + expect(this.template.firstChild.style.display).toBe('block'); + }); + }); + }); + + describe('setImagesSrc', function () { + beforeEach(function () { + this.dropdown = {}; + this.template = { querySelectorAll: () => {} }; + + spyOn(this.template, 'querySelectorAll').and.returnValue([]); + + DropDown.prototype.setImagesSrc.call(this.dropdown, this.template); + }); + + it('should call .querySelectorAll', function () { + expect(this.template.querySelectorAll).toHaveBeenCalledWith('img[data-src]'); + }); + }); + + describe('show', function () { + beforeEach(function () { + this.list = { style: {} }; + this.dropdown = { list: this.list, hidden: true }; + + DropDown.prototype.show.call(this.dropdown); + }); + + it('it should set .list display to block', function () { + expect(this.list.style.display).toBe('block'); + }); + + it('it should set .hidden to false', function () { + expect(this.dropdown.hidden).toBe(false); + }); + + describe('if .hidden is false', function () { + beforeEach(function () { + this.list = { style: {} }; + this.dropdown = { list: this.list, hidden: false }; + + this.show = DropDown.prototype.show.call(this.dropdown); + }); + + it('should return undefined', function () { + expect(this.show).toEqual(undefined); + }); + + it('should not set .list display to block', function () { + expect(this.list.style.display).not.toEqual('block'); + }); + }); + }); + + describe('hide', function () { + beforeEach(function () { + this.list = { style: {} }; + this.dropdown = { list: this.list }; + + DropDown.prototype.hide.call(this.dropdown); + }); + + it('it should set .list display to none', function () { + expect(this.list.style.display).toBe('none'); + }); + + it('it should set .hidden to true', function () { + expect(this.dropdown.hidden).toBe(true); + }); + }); + + describe('toggle', function () { + beforeEach(function () { + this.hidden = true + this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} }; + + spyOn(this.dropdown, 'show'); + spyOn(this.dropdown, 'hide'); + + DropDown.prototype.toggle.call(this.dropdown); + }); + + it('should call .show', function () { + expect(this.dropdown.show).toHaveBeenCalled(); + }); + + describe('if .hidden is false', function () { + beforeEach(function () { + this.hidden = false + this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} }; + + spyOn(this.dropdown, 'show'); + spyOn(this.dropdown, 'hide'); + + DropDown.prototype.toggle.call(this.dropdown); + }); + + it('should call .hide', function () { + expect(this.dropdown.hide).toHaveBeenCalled(); + }); + }); + }); + + describe('destroy', function () { + beforeEach(function () { + this.list = { removeEventListener: () => {} }; + this.eventWrapper = { clickEvent: 'clickEvent' }; + this.dropdown = { list: this.list, hide: () => {}, eventWrapper: this.eventWrapper }; + + spyOn(this.list, 'removeEventListener'); + spyOn(this.dropdown, 'hide'); + + DropDown.prototype.destroy.call(this.dropdown); + }); + + it('it should call .hide', function () { + expect(this.dropdown.hide).toHaveBeenCalled(); + }); + + it('it should call .removeEventListener', function () { + expect(this.list.removeEventListener).toHaveBeenCalledWith('click', this.eventWrapper.clickEvent); + }); + }); +}); diff --git a/spec/javascripts/droplab/hook_spec.js b/spec/javascripts/droplab/hook_spec.js new file mode 100644 index 00000000000..8ebdcdd1404 --- /dev/null +++ b/spec/javascripts/droplab/hook_spec.js @@ -0,0 +1,82 @@ +/* eslint-disable */ + +import Hook from '~/droplab/hook'; +import * as dropdownSrc from '~/droplab/drop_down'; + +describe('Hook', function () { + describe('class constructor', function () { + beforeEach(function () { + this.trigger = { id: 'id' }; + this.list = {}; + this.plugins = {}; + this.config = {}; + this.dropdown = {}; + + spyOn(dropdownSrc, 'default').and.returnValue(this.dropdown); + + this.hook = new Hook(this.trigger, this.list, this.plugins, this.config); + }); + + it('should set .trigger', function () { + expect(this.hook.trigger).toBe(this.trigger); + }); + + it('should set .list', function () { + expect(this.hook.list).toBe(this.dropdown); + }); + + it('should call DropDown constructor', function () { + expect(dropdownSrc.default).toHaveBeenCalledWith(this.list); + }); + + it('should set .type', function () { + expect(this.hook.type).toBe('Hook'); + }); + + it('should set .event', function () { + expect(this.hook.event).toBe('click'); + }); + + it('should set .plugins', function () { + expect(this.hook.plugins).toBe(this.plugins); + }); + + it('should set .config', function () { + expect(this.hook.config).toBe(this.config); + }); + + it('should set .id', function () { + expect(this.hook.id).toBe(this.trigger.id); + }); + + describe('if config argument is undefined', function () { + beforeEach(function () { + this.config = undefined; + + this.hook = new Hook(this.trigger, this.list, this.plugins, this.config); + }); + + it('should set .config to an empty object', function () { + expect(this.hook.config).toEqual({}); + }); + }); + + describe('if plugins argument is undefined', function () { + beforeEach(function () { + this.plugins = undefined; + + this.hook = new Hook(this.trigger, this.list, this.plugins, this.config); + }); + + it('should set .plugins to an empty array', function () { + expect(this.hook.plugins).toEqual([]); + }); + }); + }); + + describe('addEvents', function () { + it('should exist', function () { + expect(Hook.prototype.hasOwnProperty('addEvents')).toBe(true); + }); + }); +}); diff --git a/spec/javascripts/droplab/plugins/input_setter_spec.js b/spec/javascripts/droplab/plugins/input_setter_spec.js new file mode 100644 index 00000000000..c9b7b2b23dc --- /dev/null +++ b/spec/javascripts/droplab/plugins/input_setter_spec.js @@ -0,0 +1,246 @@ +/* eslint-disable */ + +import InputSetter from '~/droplab/plugins/input_setter'; + +describe('InputSetter', function () { + describe('init', function () { + beforeEach(function () { + this.config = { InputSetter: {} }; + this.hook = { config: this.config }; + this.inputSetter = jasmine.createSpyObj('inputSetter', ['addEvents']); + + InputSetter.init.call(this.inputSetter, this.hook); + }); + + it('should set .hook', function () { + expect(this.inputSetter.hook).toBe(this.hook); + }); + + it('should set .config', function () { + expect(this.inputSetter.config).toBe(this.config.InputSetter); + }); + + it('should set .eventWrapper', function () { + expect(this.inputSetter.eventWrapper).toEqual({}); + }); + + it('should call .addEvents', function () { + expect(this.inputSetter.addEvents).toHaveBeenCalled(); + }); + + describe('if config.InputSetter is not set', function () { + beforeEach(function () { + this.config = { InputSetter: undefined }; + this.hook = { config: this.config }; + + InputSetter.init.call(this.inputSetter, this.hook); + }); + + it('should set .config to an empty object', function () { + expect(this.inputSetter.config).toEqual({}); + }); + + it('should set hook.config to an empty object', function () { + expect(this.hook.config.InputSetter).toEqual({}); + }); + }) + }); + + describe('addEvents', function () { + beforeEach(function () { + this.hook = { list: { list: jasmine.createSpyObj('list', ['addEventListener']) } }; + this.inputSetter = { eventWrapper: {}, hook: this.hook, setInputs: () => {} }; + + InputSetter.addEvents.call(this.inputSetter); + }); + + it('should set .eventWrapper.setInputs', function () { + expect(this.inputSetter.eventWrapper.setInputs).toEqual(jasmine.any(Function)); + }); + + it('should call .addEventListener', function () { + expect(this.hook.list.list.addEventListener) + .toHaveBeenCalledWith('click.dl', this.inputSetter.eventWrapper.setInputs); + }); + }); + + describe('removeEvents', function () { + beforeEach(function () { + this.hook = { list: { list: jasmine.createSpyObj('list', ['removeEventListener']) } }; + this.eventWrapper = jasmine.createSpyObj('eventWrapper', ['setInputs']); + this.inputSetter = { eventWrapper: this.eventWrapper, hook: this.hook }; + + InputSetter.removeEvents.call(this.inputSetter); + }); + + it('should call .removeEventListener', function () { + expect(this.hook.list.list.removeEventListener) + .toHaveBeenCalledWith('click.dl', this.eventWrapper.setInputs); + }); + }); + + describe('setInputs', function () { + beforeEach(function () { + this.event = { detail: { selected: {} } }; + this.config = [0, 1]; + this.inputSetter = { config: this.config, setInput: () => {} }; + + spyOn(this.inputSetter, 'setInput'); + + InputSetter.setInputs.call(this.inputSetter, this.event); + }); + + it('should call .setInput for each config element', function () { + const allArgs = this.inputSetter.setInput.calls.allArgs(); + + expect(allArgs.length).toEqual(2); + + allArgs.forEach((args, i) => { + expect(args[0]).toBe(this.config[i]); + expect(args[1]).toBe(this.event.detail.selected); + }); + }); + + describe('if config isnt an array', function () { + beforeEach(function () { + this.inputSetter = { config: {}, setInput: () => {} }; + + InputSetter.setInputs.call(this.inputSetter, this.event); + }); + + it('should set .config to an array with .config as the first element', function () { + expect(this.inputSetter.config).toEqual([{}]); + }); + }); + }); + + describe('setInput', function () { + beforeEach(function () { + this.selectedItem = { getAttribute: () => {} }; + this.input = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} }; + this.config = { valueAttribute: {}, input: this.input }; + this.inputSetter = { hook: { trigger: {} } }; + this.newValue = 'newValue'; + + spyOn(this.selectedItem, 'getAttribute').and.returnValue(this.newValue); + spyOn(this.input, 'hasAttribute').and.returnValue(false); + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should call .getAttribute', function () { + expect(this.selectedItem.getAttribute).toHaveBeenCalledWith(this.config.valueAttribute); + }); + + it('should call .hasAttribute', function () { + expect(this.input.hasAttribute).toHaveBeenCalledWith(undefined); + }); + + it('should set the value of the input', function () { + expect(this.input.value).toBe(this.newValue); + }); + + describe('if there is no newValue', function () { + beforeEach(function () { + this.newValue = ''; + this.inputSetter = { hook: { trigger: {} } }; + this.config = { valueAttribute: {}, input: this.input }; + this.input = { value: 'oldValue', tagName: 'INPUT' }; + this.selectedItem = { getAttribute: () => {} }; + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should not set the value of the input', function () { + expect(this.input.value).toBe('oldValue'); + }) + }); + + describe('if no config.input is provided', function () { + beforeEach(function () { + this.config = { valueAttribute: {} }; + this.trigger = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} }; + this.inputSetter = { hook: { trigger: this.trigger } }; + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should set the value of the hook.trigger', function () { + expect(this.trigger.value).toBe(this.newValue); + }); + }); + + describe('if the input tag is not INPUT', function () { + beforeEach(function () { + this.input = { textContent: 'oldValue', tagName: 'SPAN', hasAttribute: () => {} }; + this.config = { valueAttribute: {}, input: this.input }; + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should set the textContent of the input', function () { + expect(this.input.textContent).toBe(this.newValue); + }); + + describe('if there is no new value', function () { + beforeEach(function () { + this.selectedItem = { getAttribute: () => {} }; + this.input = { textContent: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} }; + this.config = { valueAttribute: {}, input: this.input }; + this.inputSetter = { hook: { trigger: {} } }; + this.newValue = 'newValue'; + + spyOn(this.selectedItem, 'getAttribute').and.returnValue(this.newValue); + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should not set the value of the input', function () { + expect(this.input.textContent).toBe('oldValue'); + }); + }); + }); + + describe('if there is an inputAttribute', function () { + beforeEach(function () { + this.selectedItem = { getAttribute: () => {} }; + this.input = { id: 'oldValue', hasAttribute: () => {}, setAttribute: () => {} }; + this.inputSetter = { hook: { trigger: {} } }; + this.newValue = 'newValue'; + this.inputAttribute = 'id'; + this.config = { + valueAttribute: {}, + input: this.input, + inputAttribute: this.inputAttribute, + }; + + spyOn(this.selectedItem, 'getAttribute').and.returnValue(this.newValue); + spyOn(this.input, 'hasAttribute').and.returnValue(true); + spyOn(this.input, 'setAttribute'); + + InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem); + }); + + it('should call setAttribute', function () { + expect(this.input.setAttribute).toHaveBeenCalledWith(this.inputAttribute, this.newValue); + }); + + it('should not set the value or textContent of the input', function () { + expect(this.input.value).not.toBe('newValue'); + expect(this.input.textContent).not.toBe('newValue'); + }); + }); + }); + + describe('destroy', function () { + beforeEach(function () { + this.inputSetter = jasmine.createSpyObj('inputSetter', ['removeEvents']); + + InputSetter.destroy.call(this.inputSetter); + }); + + it('should call .removeEvents', function () { + expect(this.inputSetter.removeEvents).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js index c16f77c53a2..2b1fe5e3eef 100644 --- a/spec/javascripts/filtered_search/dropdown_user_spec.js +++ b/spec/javascripts/filtered_search/dropdown_user_spec.js @@ -33,7 +33,7 @@ require('~/filtered_search/dropdown_user'); }); }); - describe('config droplabAjaxFilter\'s endpoint', () => { + describe('config AjaxFilter\'s endpoint', () => { beforeEach(() => { spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); @@ -45,13 +45,13 @@ require('~/filtered_search/dropdown_user'); }; const dropdown = new gl.DropdownUser(); - expect(dropdown.config.droplabAjaxFilter.endpoint).toBe('/autocomplete/users.json'); + expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json'); }); it('should return endpoint when relative_url_root is undefined', () => { const dropdown = new gl.DropdownUser(); - expect(dropdown.config.droplabAjaxFilter.endpoint).toBe('/autocomplete/users.json'); + expect(dropdown.config.AjaxFilter.endpoint).toBe('/autocomplete/users.json'); }); it('should return endpoint with relative url when available', () => { @@ -60,7 +60,7 @@ require('~/filtered_search/dropdown_user'); }; const dropdown = new gl.DropdownUser(); - expect(dropdown.config.droplabAjaxFilter.endpoint).toBe('/gitlab_directory/autocomplete/users.json'); + expect(dropdown.config.AjaxFilter.endpoint).toBe('/gitlab_directory/autocomplete/users.json'); }); afterEach(() => { diff --git a/yarn.lock b/yarn.lock index 9f2b8fe3d6e..8f0be2c50a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,8 +14,8 @@ accepts@1.3.3, accepts@~1.3.3: negotiator "0.6.1" acorn-dynamic-import@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.1.tgz#23f671eb6e650dab277fef477c321b1178a8cca2" + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" dependencies: acorn "^4.0.3" @@ -25,18 +25,18 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" -acorn@4.0.4, acorn@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" - acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.11, acorn@^4.0.3: +acorn@^4.0.11, acorn@^4.0.3, acorn@^4.0.4: version "4.0.11" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" @@ -45,9 +45,9 @@ ajv-keywords@^1.0.0, ajv-keywords@^1.1.1: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" -ajv@^4.7.0: - version "4.11.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.2.tgz#f166c3c11cbc6cb9dcc102a5bcfe5b72c95287e6" +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" @@ -94,8 +94,8 @@ append-transform@^0.4.0: default-require-extensions "^1.0.0" aproba@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.0.tgz#4d8f047a318604e18e3c06a0e52230d3d19f147b" + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" are-we-there-yet@~1.1.2: version "1.1.2" @@ -166,14 +166,14 @@ asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" -assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - assert@^1.1.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" @@ -184,17 +184,17 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async@0.2.x, async@~0.2.6: +async@0.2.x: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" -async@1.x, async@^1.4.0, async@^1.4.2, async@^1.5.2: +async@1.x, async@^1.4.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" async@^2.1.2, async@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4" + version "2.3.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" dependencies: lodash "^4.14.0" @@ -222,15 +222,15 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@^6.22.1, babel-core@^6.23.0: - version "6.23.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" +babel-core@^6.22.1, babel-core@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.0.tgz#8f36a0a77f5c155aed6f920b844d23ba56742a02" dependencies: babel-code-frame "^6.22.0" - babel-generator "^6.23.0" + babel-generator "^6.24.0" babel-helpers "^6.23.0" babel-messages "^6.23.0" - babel-register "^6.23.0" + babel-register "^6.24.0" babel-runtime "^6.22.0" babel-template "^6.23.0" babel-traverse "^6.23.1" @@ -246,9 +246,9 @@ babel-core@^6.22.1, babel-core@^6.23.0: slash "^1.0.0" source-map "^0.5.0" -babel-generator@^6.18.0, babel-generator@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.23.0.tgz#6b8edab956ef3116f79d8c84c5a3c05f32a74bc5" +babel-generator@^6.18.0, babel-generator@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" @@ -378,11 +378,11 @@ babel-helpers@^6.23.0: babel-template "^6.23.0" babel-loader@^6.2.10: - version "6.2.10" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.2.10.tgz#adefc2b242320cd5d15e65b31cea0e8b1b02d4b0" + version "6.4.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" dependencies: find-cache-dir "^0.1.1" - loader-utils "^0.2.11" + loader-utils "^0.2.16" mkdirp "^0.5.1" object-assign "^4.0.1" @@ -399,12 +399,12 @@ babel-plugin-check-es2015-constants@^6.22.0: babel-runtime "^6.22.0" babel-plugin-istanbul@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.0.0.tgz#36bde8fbef4837e5ff0366531a2beabd7b1ffa10" + version "4.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.1.tgz#c12de0fc6fe42adfb16be56f1ad11e4a9782eca9" dependencies: find-up "^2.1.0" - istanbul-lib-instrument "^1.4.2" - test-exclude "^4.0.0" + istanbul-lib-instrument "^1.6.2" + test-exclude "^4.0.3" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -745,11 +745,11 @@ babel-preset-stage-3@^6.22.0: babel-plugin-transform-exponentiation-operator "^6.22.0" babel-plugin-transform-object-rest-spread "^6.22.0" -babel-register@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.23.0.tgz#c9aa3d4cca94b51da34826c4a0f9e08145d74ff3" +babel-register@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.0.tgz#5e89f8463ba9970356d02eb07dabe3308b080cfd" dependencies: - babel-core "^6.23.0" + babel-core "^6.24.0" babel-runtime "^6.22.0" core-js "^2.4.0" home-or-tmp "^2.0.0" @@ -758,8 +758,8 @@ babel-register@^6.23.0: source-map-support "^0.4.2" babel-runtime@^6.18.0, babel-runtime@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611" + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: core-js "^2.4.0" regenerator-runtime "^0.10.0" @@ -798,8 +798,8 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23 to-fast-properties "^1.0.1" babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" + version "6.16.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" backo2@1.0.2: version "1.0.2" @@ -856,25 +856,25 @@ block-stream@*: inherits "~2.0.0" bluebird@^3.3.0: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + version "3.5.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" -body-parser@^1.12.4: - version "1.16.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.16.0.tgz#924a5e472c6229fb9d69b85a20d5f2532dec788b" +body-parser@^1.16.1: + version "1.17.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47" dependencies: bytes "2.4.0" content-type "~1.0.2" - debug "2.6.0" + debug "2.6.1" depd "~1.1.0" - http-errors "~1.5.1" + http-errors "~1.6.1" iconv-lite "0.4.15" on-finished "~2.3.0" - qs "6.2.1" + qs "6.4.0" raw-body "~2.2.0" type-is "~1.6.14" @@ -885,8 +885,8 @@ boom@2.x.x: hoek "2.x.x" bootstrap-sass@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.3.6.tgz#363b0d300e868d3e70134c1a742bb17288444fd1" + version "3.3.7" + resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz#6596c7ab40f6637393323ab0bc80d064fc630498" brace-expansion@^1.0.0: version "1.1.6" @@ -910,8 +910,8 @@ braces@^1.8.2: repeat-element "^1.1.2" brorand@^1.0.1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.0.7.tgz#6677fa5e4901bdbf9c9ec2a748e28dca407a9bfc" + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.0.6" @@ -947,8 +947,8 @@ browserify-rsa@^4.0.0: randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.0.tgz#10773910c3c206d5420a46aad8694f820b85968f" + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" dependencies: bn.js "^4.1.1" browserify-rsa "^4.0.0" @@ -1022,6 +1022,10 @@ caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" @@ -1145,10 +1149,10 @@ component-inherit@0.0.3: resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" compressible@~2.0.8: - version "2.0.9" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" + version "2.0.10" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.10.tgz#feda1c7f7617912732b29bf8cf26252a20b9eecd" dependencies: - mime-db ">= 1.24.0 < 2" + mime-db ">= 1.27.0 < 2" compression-webpack-plugin@^0.3.2: version "0.3.2" @@ -1182,7 +1186,7 @@ concat-stream@1.5.0: readable-stream "~2.0.0" typedarray "~0.0.5" -concat-stream@^1.4.6: +concat-stream@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1194,12 +1198,12 @@ connect-history-api-fallback@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169" -connect@^3.3.5: - version "3.5.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.5.0.tgz#b357525a0b4c1f50599cd983e1d9efeea9677198" +connect@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.0.tgz#f09a4f7dcd17324b663b725c815bdb1c4158a46e" dependencies: - debug "~2.2.0" - finalhandler "0.5.0" + debug "2.6.1" + finalhandler "1.0.0" parseurl "~1.3.1" utils-merge "1.0.0" @@ -1230,8 +1234,8 @@ content-type@~1.0.2: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" convert-source-map@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" cookie-signature@1.0.6: version "1.0.6" @@ -1302,14 +1306,14 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" d3@^3.5.11: - version "3.5.11" - resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.11.tgz#d130750eed0554db70e8432102f920a12407b69c" + version "3.5.17" + resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" -d@^0.1.1, d@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: - es5-ext "~0.10.2" + es5-ext "^0.10.9" dashdash@^1.12.0: version "1.14.1" @@ -1337,9 +1341,15 @@ debug@2.3.3: dependencies: ms "0.7.2" -debug@2.6.0, debug@^2.1.1, debug@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" +debug@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" + dependencies: + ms "0.7.2" + +debug@2.6.3, debug@^2.1.1, debug@^2.2.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" dependencies: ms "0.7.2" @@ -1387,7 +1397,7 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@~1.1.0: +depd@1.1.0, depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" @@ -1420,16 +1430,23 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" -doctrine@1.5.0, doctrine@^1.2.2: +doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" dependencies: esutils "^2.0.2" isarray "^1.0.0" +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + document-register-element@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/document-register-element/-/document-register-element-1.3.0.tgz#fb3babb523c74662be47be19c6bc33e71990d940" + version "1.4.1" + resolved "https://registry.yarnpkg.com/document-register-element/-/document-register-element-1.4.1.tgz#22b41e96fb86cccab2fa30f7d2a8d62ac7be8c57" dom-serialize@^2.2.0: version "2.2.1" @@ -1445,8 +1462,8 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" dropzone@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3" + version "4.3.0" + resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.3.0.tgz#48b0b8f2ad092872e4b535b672a7c3f1a1d67c91" duplexer@^0.1.1: version "0.1.1" @@ -1467,13 +1484,16 @@ ejs@^2.5.5: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88" elliptic@^6.0.0: - version "6.3.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" dependencies: bn.js "^4.4.0" brorand "^1.0.1" hash.js "^1.0.0" + hmac-drbg "^1.0.0" inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" emoji-unicode-version@^0.2.1: version "0.2.1" @@ -1487,9 +1507,9 @@ encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" -engine.io-client@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.2.tgz#c38767547f2a7d184f5752f6f0ad501006703766" +engine.io-client@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.3.tgz#1798ed93451246453d4c6f635d7a201fe940d5ab" dependencies: component-emitter "1.2.1" component-inherit "0.0.3" @@ -1500,7 +1520,7 @@ engine.io-client@1.8.2: parsejson "0.0.3" parseqs "0.0.5" parseuri "0.0.5" - ws "1.1.1" + ws "1.1.2" xmlhttprequest-ssl "1.5.3" yeast "0.1.2" @@ -1515,16 +1535,16 @@ engine.io-parser@1.3.2: has-binary "0.1.7" wtf-8 "1.0.0" -engine.io@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.2.tgz#6b59be730b348c0125b0a4589de1c355abcf7a7e" +engine.io@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4" dependencies: accepts "1.3.3" base64id "1.0.0" cookie "0.3.1" debug "2.3.3" engine.io-parser "1.3.2" - ws "1.1.1" + ws "1.1.2" enhanced-resolve@^3.0.0: version "3.1.0" @@ -1554,36 +1574,36 @@ errno@^0.1.3: prr "~0.0.0" error-ex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: is-arrayish "^0.2.1" -es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: - version "0.10.12" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.15" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" dependencies: es6-iterator "2" es6-symbol "~3.1" -es6-iterator@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" dependencies: - d "^0.1.1" - es5-ext "^0.10.7" - es6-symbol "3" + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" es6-map@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-set "~0.1.3" - es6-symbol "~3.1.0" - event-emitter "~0.3.4" + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" es6-promise@~3.0.2: version "3.0.2" @@ -1593,31 +1613,31 @@ es6-promise@~4.0.3: version "4.0.5" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42" -es6-set@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-symbol "3" - event-emitter "~0.3.4" + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" -es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" + d "1" + es5-ext "~0.10.14" es6-weak-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" dependencies: - d "^0.1.1" - es5-ext "^0.10.8" - es6-iterator "2" - es6-symbol "3" + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" escape-html@~1.0.3: version "1.0.3" @@ -1710,16 +1730,17 @@ eslint-plugin-jasmine@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.2.0.tgz#7135879383c39a667c721d302b9f20f0389543de" eslint@^3.10.1: - version "3.15.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.15.0.tgz#bdcc6a6c5ffe08160e7b93c066695362a91e30f2" + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" dependencies: babel-code-frame "^6.16.0" chalk "^1.1.3" - concat-stream "^1.4.6" + concat-stream "^1.5.2" debug "^2.1.1" - doctrine "^1.2.2" + doctrine "^2.0.0" escope "^3.6.0" espree "^3.4.0" + esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" @@ -1749,10 +1770,10 @@ eslint@^3.10.1: user-home "^2.0.0" espree@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d" + version "3.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2" dependencies: - acorn "4.0.4" + acorn "^5.0.1" acorn-jsx "^3.0.0" esprima@2.7.x, esprima@^2.7.1: @@ -1763,6 +1784,12 @@ esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" @@ -1774,7 +1801,7 @@ estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1786,20 +1813,20 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -etag@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" +etag@~1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" eve-raphael@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/eve-raphael/-/eve-raphael-0.5.0.tgz#17c754b792beef3fa6684d79cf5a47c63c4cda30" -event-emitter@~0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" dependencies: - d "~0.1.1" - es5-ext "~0.10.7" + d "1" + es5-ext "~0.10.14" eventemitter3@1.x.x: version "1.2.0" @@ -1809,7 +1836,7 @@ events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" -eventsource@~0.1.6: +eventsource@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" dependencies: @@ -1853,8 +1880,8 @@ expand-range@^1.8.1: fill-range "^2.1.0" express@^4.13.3, express@^4.14.1: - version "4.14.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.14.1.tgz#646c237f766f148c2120aff073817b9e4d7e0d33" + version "4.15.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.15.2.tgz#af107fc148504457f2dca9a6f2571d7129b97b35" dependencies: accepts "~1.3.3" array-flatten "1.1.1" @@ -1862,23 +1889,25 @@ express@^4.13.3, express@^4.14.1: content-type "~1.0.2" cookie "0.3.1" cookie-signature "1.0.6" - debug "~2.2.0" + debug "2.6.1" depd "~1.1.0" encodeurl "~1.0.1" escape-html "~1.0.3" - etag "~1.7.0" - finalhandler "0.5.1" - fresh "0.3.0" + etag "~1.8.0" + finalhandler "~1.0.0" + fresh "0.5.0" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" parseurl "~1.3.1" path-to-regexp "0.1.7" proxy-addr "~1.1.3" - qs "6.2.0" + qs "6.4.0" range-parser "~1.2.0" - send "0.14.2" - serve-static "~1.11.2" + send "0.15.1" + serve-static "1.12.1" + setprototypeof "1.0.3" + statuses "~1.3.1" type-is "~1.6.14" utils-merge "1.0.0" vary "~1.1.0" @@ -1960,8 +1989,8 @@ fileset@^2.0.2: minimatch "^3.0.3" filesize@^3.5.4: - version "3.5.4" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.4.tgz#742fc7fb6aef4ee3878682600c22f840731e1fda" + version "3.5.6" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.6.tgz#5fd98f3eac94ec9516ef8ed5782fad84a01a0a1a" fill-range@^2.1.0: version "2.2.3" @@ -1973,23 +2002,27 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" -finalhandler@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" +finalhandler@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.0.tgz#b5691c2c0912092f18ac23e9416bde5cd7dc6755" dependencies: - debug "~2.2.0" + debug "2.6.1" + encodeurl "~1.0.1" escape-html "~1.0.3" on-finished "~2.3.0" - statuses "~1.3.0" + parseurl "~1.3.1" + statuses "~1.3.1" unpipe "~1.0.0" -finalhandler@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.1.tgz#2c400d8d4530935bc232549c5fa385ec07de6fcd" +finalhandler@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.1.tgz#bcd15d1689c0e5ed729b6f7f541a6df984117db8" dependencies: - debug "~2.2.0" + debug "2.6.3" + encodeurl "~1.0.1" escape-html "~1.0.3" on-finished "~2.3.0" + parseurl "~1.3.1" statuses "~1.3.1" unpipe "~1.0.0" @@ -2027,15 +2060,15 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -for-in@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" for-own@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" dependencies: - for-in "^0.1.5" + for-in "^1.0.1" forever-agent@~0.6.1: version "0.6.1" @@ -2053,9 +2086,9 @@ forwarded@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" -fresh@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" +fresh@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" fs-extra@~1.0.0: version "1.0.0" @@ -2070,13 +2103,13 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" fsevents@^1.0.0: - version "1.0.17" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.17.tgz#8537f3f12272678765b4fd6528c0f1f66f8f4558" + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" dependencies: nan "^2.3.0" node-pre-gyp "^0.6.29" -fstream-ignore@~1.0.5: +fstream-ignore@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" dependencies: @@ -2084,9 +2117,9 @@ fstream-ignore@~1.0.5: inherits "2" minimatch "^3.0.0" -fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -2098,8 +2131,8 @@ function-bind@^1.0.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" gauge@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.2.tgz#15cecc31b02d05345a5d6b0e171cdb3ad2307774" + version "2.7.3" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -2108,7 +2141,6 @@ gauge@~2.7.1: signal-exit "^3.0.0" string-width "^1.0.1" strip-ansi "^3.0.1" - supports-color "^0.2.0" wide-align "^1.1.0" generate-function@^2.0.0: @@ -2166,8 +2198,8 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: path-is-absolute "^1.0.0" globals@^9.0.0, globals@^9.14.0: - version "9.14.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" + version "9.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" globby@^5.0.0: version "5.0.0" @@ -2208,6 +2240,10 @@ handlebars@^4.0.1, handlebars@^4.0.3: optionalDependencies: uglify-js "^2.6" +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" @@ -2217,6 +2253,13 @@ har-validator@~2.0.6: is-my-json-valid "^2.12.4" pinkie-promise "^2.0.0" +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -2247,7 +2290,7 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -hash.js@^1.0.0: +hash.js@^1.0.0, hash.js@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573" dependencies: @@ -2269,6 +2312,14 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hmac-drbg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.0.tgz#3db471f45aae4a994a0688322171f51b8b91bee5" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2281,8 +2332,8 @@ home-or-tmp@^2.0.0: os-tmpdir "^1.0.1" hosted-git-info@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" + version "2.4.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.1.tgz#4b0445e41c004a8bd1337773a4ff790ca40318c8" hpack.js@^2.1.6: version "2.1.6" @@ -2301,7 +2352,7 @@ http-deceiver@^1.2.4: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" -http-errors@~1.5.0, http-errors@~1.5.1: +http-errors@~1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" dependencies: @@ -2309,9 +2360,18 @@ http-errors@~1.5.0, http-errors@~1.5.1: setprototypeof "1.0.2" statuses ">= 1.3.1 < 2" -http-proxy-middleware@~0.17.1: - version "0.17.3" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.3.tgz#940382147149b856084f5534752d5b5a8168cd1d" +http-errors@~1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257" + dependencies: + depd "1.1.0" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-proxy-middleware@~0.17.4: + version "0.17.4" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" dependencies: http-proxy "^1.16.2" is-glob "^3.1.0" @@ -2346,8 +2406,8 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" ignore@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.2.tgz#1c51e1ef53bab6ddc15db4d9ac4ec139eceb3410" + version "3.2.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" immediate@~3.0.5: version "3.0.6" @@ -2399,8 +2459,8 @@ inquirer@^0.12.0: through "^2.3.6" interpret@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + version "1.0.2" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d" invariant@^2.2.0: version "2.2.2" @@ -2412,9 +2472,9 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" -ipaddr.js@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.2.0.tgz#8aba49c9192799585bdd643e0ccb50e8ae777ba4" +ipaddr.js@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" is-absolute@^0.2.3: version "0.2.6" @@ -2434,8 +2494,8 @@ is-binary-path@^1.0.0: binary-extensions "^1.0.0" is-buffer@^1.0.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" is-builtin-module@^1.0.0: version "1.0.0" @@ -2494,8 +2554,8 @@ is-glob@^3.1.0: is-extglob "^2.1.0" is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: - version "2.15.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" dependencies: generate-function "^2.0.0" generate-object-property "^1.1.0" @@ -2586,9 +2646,9 @@ isbinaryfile@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" -isexe@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" isobject@^2.0.0: version "2.1.0" @@ -2601,66 +2661,64 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" istanbul-api@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.1.tgz#d36e2f1560d1a43ce304c4ff7338182de61c8f73" + version "1.1.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.7.tgz#f6f37f09f8002b130f891c646b70ee4a8e7345ae" dependencies: async "^2.1.4" fileset "^2.0.2" - istanbul-lib-coverage "^1.0.0" - istanbul-lib-hook "^1.0.0" - istanbul-lib-instrument "^1.3.0" - istanbul-lib-report "^1.0.0-alpha.3" - istanbul-lib-source-maps "^1.1.0" - istanbul-reports "^1.0.0" + istanbul-lib-coverage "^1.0.2" + istanbul-lib-hook "^1.0.5" + istanbul-lib-instrument "^1.7.0" + istanbul-lib-report "^1.0.0" + istanbul-lib-source-maps "^1.1.1" + istanbul-reports "^1.0.2" js-yaml "^3.7.0" mkdirp "^0.5.1" once "^1.4.0" -istanbul-lib-coverage@^1.0.0, istanbul-lib-coverage@^1.0.0-alpha, istanbul-lib-coverage@^1.0.0-alpha.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.1.tgz#f263efb519c051c5f1f3343034fc40e7b43ff212" +istanbul-lib-coverage@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.2.tgz#87a0c015b6910651cb3b184814dfb339337e25e1" -istanbul-lib-hook@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.0.tgz#fc5367ee27f59268e8f060b0c7aaf051d9c425c5" +istanbul-lib-hook@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.5.tgz#6ca3d16d60c5f4082da39f7c5cd38ea8a772b88e" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.3.0, istanbul-lib-instrument@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.4.2.tgz#0e2fdfac93c1dabf2e31578637dc78a19089f43e" +istanbul-lib-instrument@^1.6.2, istanbul-lib-instrument@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.0.tgz#b8e0dc25709bb44e17336ab47b7bb5c97c23f659" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" babylon "^6.13.0" - istanbul-lib-coverage "^1.0.0" + istanbul-lib-coverage "^1.0.2" semver "^5.3.0" -istanbul-lib-report@^1.0.0-alpha.3: - version "1.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.0.0-alpha.3.tgz#32d5f6ec7f33ca3a602209e278b2e6ff143498af" +istanbul-lib-report@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.0.0.tgz#d83dac7f26566b521585569367fe84ccfc7aaecb" dependencies: - async "^1.4.2" - istanbul-lib-coverage "^1.0.0-alpha" + istanbul-lib-coverage "^1.0.2" mkdirp "^0.5.1" path-parse "^1.0.5" - rimraf "^2.4.3" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.1.0.tgz#9d429218f35b823560ea300a96ff0c3bbdab785f" +istanbul-lib-source-maps@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.1.1.tgz#f8c8c2e8f2160d1d91526d97e5bd63b2079af71c" dependencies: - istanbul-lib-coverage "^1.0.0-alpha.0" + istanbul-lib-coverage "^1.0.2" mkdirp "^0.5.1" rimraf "^2.4.4" source-map "^0.5.3" -istanbul-reports@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.0.1.tgz#9a17176bc4a6cbebdae52b2f15961d52fa623fbc" +istanbul-reports@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.0.2.tgz#4e8366abe6fa746cc1cd6633f108de12cc6ac6fa" dependencies: handlebars "^4.0.3" @@ -2698,33 +2756,33 @@ jodid25519@^1.0.0: jsbn "~0.1.0" jquery-ujs@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jquery-ujs/-/jquery-ujs-1.2.1.tgz#6ee75b1ef4e9ac95e7124f8d71f7d351f5548e92" + version "1.2.2" + resolved "https://registry.yarnpkg.com/jquery-ujs/-/jquery-ujs-1.2.2.tgz#6a8ef1020e6b6dda385b90a4bddc128c21c56397" dependencies: jquery ">=1.8.0" jquery@>=1.8.0, jquery@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-2.2.1.tgz#3c3e16854ad3d2ac44ac65021b17426d22ad803f" + version "2.2.4" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-2.2.4.tgz#2c89d6889b5eac522a7eea32c14521559c6cbf02" js-cookie@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.1.3.tgz#48071625217ac9ecfab8c343a13d42ec09ff0526" + version "2.1.4" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.1.4.tgz#da4ec503866f149d164cf25f579ef31015025d8d" js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" js-yaml@3.x, js-yaml@^3.5.1, js-yaml@^3.7.0: - version "3.8.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.1.tgz#782ba50200be7b9e5a8537001b7804db3ad02628" + version "3.8.3" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766" dependencies: argparse "^1.0.7" esprima "^3.1.1" jsbn@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" jsesc@^1.3.0: version "1.3.0" @@ -2775,9 +2833,10 @@ jsonpointer@^4.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" jsprim@^1.2.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" dependencies: + assert-plus "1.0.0" extsprintf "1.0.2" json-schema "0.2.3" verror "1.3.6" @@ -2797,8 +2856,8 @@ jszip@^3.1.3: readable-stream "~2.0.6" karma-coverage-istanbul-reporter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-0.2.0.tgz#5766263338adeb0026f7e4ac7a89a5f056c5642c" + version "0.2.3" + resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-0.2.3.tgz#11f1be9cfa93755a77bac39ab16e315a7100b5c5" dependencies: istanbul-api "^1.1.1" @@ -2807,14 +2866,14 @@ karma-jasmine@^1.1.0: resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.0.tgz#22e4c06bf9a182e5294d1f705e3733811b810acf" karma-mocha-reporter@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.2.tgz#876de9a287244e54a608591732a98e66611f6abe" + version "2.2.3" + resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.3.tgz#04fdda45a1d9697a73871c7472223c581701ab20" dependencies: chalk "1.1.3" karma-phantomjs-launcher@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.2.tgz#19e1041498fd75563ed86730a22c1fe579fa8fb1" + version "1.0.4" + resolved "https://registry.yarnpkg.com/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz#d23ca34801bda9863ad318e3bb4bd4062b13acd2" dependencies: lodash "^4.0.1" phantomjs-prebuilt "^2.1.7" @@ -2826,8 +2885,8 @@ karma-sourcemap-loader@^0.3.7: graceful-fs "^4.1.2" karma-webpack@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.2.tgz#bd38350af5645c9644090770939ebe7ce726f864" + version "2.0.3" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.3.tgz#39cebf5ca2580139b27f9ae69b78816b9c82fae6" dependencies: async "~0.9.0" loader-utils "^0.2.5" @@ -2836,15 +2895,15 @@ karma-webpack@^2.0.2: webpack-dev-middleware "^1.0.11" karma@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/karma/-/karma-1.4.1.tgz#41981a71d54237606b0a3ea8c58c90773f41650e" + version "1.5.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-1.5.0.tgz#9c4c14f0400bef2c04c8e8e6bff59371025cc009" dependencies: bluebird "^3.3.0" - body-parser "^1.12.4" + body-parser "^1.16.1" chokidar "^1.4.1" colors "^1.1.0" combine-lists "^1.0.0" - connect "^3.3.5" + connect "^3.6.0" core-js "^2.2.0" di "^0.0.1" dom-serialize "^2.2.0" @@ -2860,12 +2919,12 @@ karma@^1.4.1: optimist "^0.6.1" qjobs "^1.1.4" range-parser "^1.2.0" - rimraf "^2.3.3" + rimraf "^2.6.0" safe-buffer "^5.0.1" - socket.io "1.7.2" + socket.io "1.7.3" source-map "^0.5.3" - tmp "0.0.28" - useragent "^2.1.10" + tmp "0.0.31" + useragent "^2.1.12" kew@~0.7.0: version "0.7.0" @@ -2920,9 +2979,9 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5: - version "0.2.16" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d" +loader-utils@^0.2.16, loader-utils@^0.2.5: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: big.js "^3.1.3" emojis-list "^2.0.0" @@ -3084,15 +3143,15 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.24.0 < 2", mime-db@~1.26.0: - version "1.26.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" +"mime-db@>= 1.27.0 < 2", mime-db@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" -mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7: - version "2.1.14" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7: + version "2.1.15" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" dependencies: - mime-db "~1.26.0" + mime-db "~1.27.0" mime@1.3.4, mime@^1.3.4: version "1.3.4" @@ -3102,6 +3161,10 @@ minimalistic-assert@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + "minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" @@ -3122,19 +3185,19 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" moment@2.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82" + version "2.18.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" mousetrap@^1.4.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.4.6.tgz#eaca72e22e56d5b769b7555873b688c3332e390a" + version "1.6.1" + resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.1.tgz#2a085f5c751294c75e7e81f6ec2545b29cbf42d9" ms@0.7.1: version "0.7.1" @@ -3217,18 +3280,18 @@ node-libs-browser@^2.0.0: vm-browserify "0.0.4" node-pre-gyp@^0.6.29, node-pre-gyp@^0.6.4: - version "0.6.33" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" - dependencies: - mkdirp "~0.5.1" - nopt "~3.0.6" - npmlog "^4.0.1" - rc "~1.1.6" - request "^2.79.0" - rimraf "~2.5.4" - semver "~5.3.0" - tar "~2.2.1" - tar-pack "~3.3.0" + version "0.6.34" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + dependencies: + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "^2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" node-zopfli@^2.0.0: version "2.0.2" @@ -3239,15 +3302,22 @@ node-zopfli@^2.0.0: nan "^2.0.0" node-pre-gyp "^0.6.4" -nopt@3.x, nopt@~3.0.6: +nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" dependencies: abbrev "1" +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + normalize-package-data@^2.3.2: - version "2.3.5" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + version "2.3.6" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.6.tgz#498fa420c96401f787402ba21e600def9f981fff" dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -3255,10 +3325,12 @@ normalize-package-data@^2.3.2: validate-npm-package-license "^3.0.1" normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" -npmlog@^4.0.1: +npmlog@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" dependencies: @@ -3308,18 +3380,12 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@1.x, once@^1.3.0, once@^1.4.0: +once@1.x, once@^1.3.0, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" -once@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - dependencies: - wrappy "1" - onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -3377,10 +3443,17 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-limit@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" @@ -3400,8 +3473,8 @@ pako@~1.0.2: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.5.tgz#d2205dfe5b9da8af797e7c163db4d1f84e4600bc" parse-asn1@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.0.0.tgz#35060f6d5015d37628c770f4e091a0b5a278bc23" + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -3494,6 +3567,10 @@ pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + phantomjs-prebuilt@^2.1.7: version "2.1.14" resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz#d53d311fcfb7d1d08ddb24014558f1188c516da0" @@ -3577,11 +3654,11 @@ progress@^1.1.8, progress@~1.1.8: resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" proxy-addr@~1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.3.tgz#dc97502f5722e888467b3fa2297a7b1ff47df074" + version "1.1.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3" dependencies: forwarded "~0.1.0" - ipaddr.js "1.2.0" + ipaddr.js "1.3.0" prr@~0.0.0: version "0.0.0" @@ -3609,17 +3686,13 @@ qjobs@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" -qs@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" - -qs@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" +qs@6.4.0, qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" qs@~6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" querystring-es3@^0.2.0: version "0.2.1" @@ -3666,14 +3739,14 @@ raw-loader@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" -rc@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" +rc@^1.1.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" dependencies: deep-extend "~0.4.0" ini "~1.3.0" minimist "^1.2.0" - strip-json-comments "~1.0.4" + strip-json-comments "~2.0.1" read-pkg-up@^1.0.1: version "1.0.1" @@ -3690,9 +3763,9 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.0, readable-stream@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" dependencies: buffer-shims "^1.0.0" core-util-is "~1.0.0" @@ -3702,16 +3775,7 @@ read-pkg@^1.0.0: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@~1.0.2: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.0.0, readable-stream@~2.0.6: +readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@~2.0.0, readable-stream@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" dependencies: @@ -3722,17 +3786,14 @@ readable-stream@~2.0.0, readable-stream@~2.0.6: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@~2.1.4: - version "2.1.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" +readable-stream@~1.0.2: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: - buffer-shims "^1.0.0" core-util-is "~1.0.0" inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" + isarray "0.0.1" string_decoder "~0.10.x" - util-deprecate "~1.0.1" readdirp@^2.0.0: version "2.1.0" @@ -3762,8 +3823,8 @@ regenerate@^1.2.1: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" regenerator-runtime@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb" + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" regenerator-transform@0.9.8: version "0.9.8" @@ -3798,6 +3859,10 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" +remove-trailing-separator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" @@ -3822,7 +3887,34 @@ request-progress@~2.0.1: dependencies: throttleit "^1.0.0" -request@^2.79.0, request@~2.79.0: +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@~2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: @@ -3875,8 +3967,10 @@ resolve@1.1.x: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" resolve@^1.1.6, resolve@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.2.0.tgz#9589c3f2f6149d1417a40becc1663db6ec6bc26c" + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + dependencies: + path-parse "^1.0.5" restore-cursor@^1.0.1: version "1.0.1" @@ -3891,9 +3985,9 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@~2.5.1, rimraf@~2.5.4: - version "2.5.4" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" +rimraf@2, rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.6.0, rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: glob "^7.0.5" @@ -3923,7 +4017,7 @@ select2@3.5.2-browserify: version "3.5.2-browserify" resolved "https://registry.yarnpkg.com/select2/-/select2-3.5.2-browserify.tgz#dc4dafda38d67a734e8a97a46f0d3529ae05391d" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@~5.3.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -3931,18 +4025,18 @@ semver@~4.3.3: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" -send@0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.14.2.tgz#39b0438b3f510be5dc6f667a11f71689368cdeef" +send@0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.15.1.tgz#8a02354c26e6f5cca700065f5f0cdeba90ec7b5f" dependencies: - debug "~2.2.0" + debug "2.6.1" depd "~1.1.0" destroy "~1.0.4" encodeurl "~1.0.1" escape-html "~1.0.3" - etag "~1.7.0" - fresh "0.3.0" - http-errors "~1.5.1" + etag "~1.8.0" + fresh "0.5.0" + http-errors "~1.6.1" mime "1.3.4" ms "0.7.2" on-finished "~2.3.0" @@ -3961,14 +4055,14 @@ serve-index@^1.7.2: mime-types "~2.1.11" parseurl "~1.3.1" -serve-static@~1.11.2: - version "1.11.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.2.tgz#2cf9889bd4435a320cc36895c9aa57bd662e6ac7" +serve-static@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.1.tgz#7443a965e3ced647aceb5639fa06bf4d1bbe0039" dependencies: encodeurl "~1.0.1" escape-html "~1.0.3" parseurl "~1.3.1" - send "0.14.2" + send "0.15.1" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -3986,6 +4080,10 @@ setprototypeof@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + sha.js@^2.3.6: version "2.4.8" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f" @@ -3993,8 +4091,8 @@ sha.js@^2.3.6: inherits "^2.0.1" shelljs@^0.7.5: - version "0.7.6" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" + version "0.7.7" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -4025,15 +4123,15 @@ socket.io-adapter@0.5.0: debug "2.3.3" socket.io-parser "2.3.1" -socket.io-client@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.2.tgz#39fdb0c3dd450e321b7e40cfd83612ec533dd644" +socket.io-client@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377" dependencies: backo2 "1.0.2" component-bind "1.0.0" component-emitter "1.2.1" debug "2.3.3" - engine.io-client "1.8.2" + engine.io-client "1.8.3" has-binary "0.1.7" indexof "0.0.1" object-component "0.0.3" @@ -4050,24 +4148,24 @@ socket.io-parser@2.3.1: isarray "0.0.1" json3 "3.3.2" -socket.io@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.2.tgz#83bbbdf2e79263b378900da403e7843e05dc3b71" +socket.io@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b" dependencies: debug "2.3.3" - engine.io "1.8.2" + engine.io "1.8.3" has-binary "0.1.7" object-assign "4.1.0" socket.io-adapter "0.5.0" - socket.io-client "1.7.2" + socket.io-client "1.7.3" socket.io-parser "2.3.1" -sockjs-client@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.1.tgz#284843e9a9784d7c474b1571b3240fca9dda4bb0" +sockjs-client@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.2.tgz#f0212a8550e4c9468c8cceaeefd2e3493c033ad5" dependencies: debug "^2.2.0" - eventsource "~0.1.6" + eventsource "0.1.6" faye-websocket "~0.11.0" inherits "^2.0.1" json3 "^3.3.2" @@ -4080,15 +4178,19 @@ sockjs@0.3.18: faye-websocket "^0.10.0" uuid "^2.0.2" +source-list-map@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.1.tgz#1a33ac210ca144d1e561f906ebccab5669ff4cb4" + source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" source-map-support@^0.4.2: - version "0.4.11" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + version "0.4.14" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" dependencies: - source-map "^0.5.3" + source-map "^0.5.6" source-map@^0.1.41: version "0.1.43" @@ -4102,7 +4204,7 @@ source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1, source-map@~0.5.3: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -4151,8 +4253,8 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.2.tgz#d5a804ce22695515638e798dbe23273de070a5fa" + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -4169,7 +4271,7 @@ stats-webpack-plugin@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/stats-webpack-plugin/-/stats-webpack-plugin-0.4.3.tgz#b2f618202f28dd04ab47d7ecf54ab846137b7aea" -"statuses@>= 1.3.1 < 2", statuses@~1.3.0, statuses@~1.3.1: +"statuses@>= 1.3.1 < 2", statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" @@ -4181,12 +4283,12 @@ stream-browserify@^2.0.1: readable-stream "^2.0.2" stream-http@^2.3.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.6.3.tgz#4c3ddbf9635968ea2cfd4e48d43de5def2625ac3" + version "2.7.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.0.tgz#cec1f4e3b494bc4a81b451808970f8b20b4ed5f6" dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" - readable-stream "^2.1.0" + readable-stream "^2.2.6" to-arraybuffer "^1.0.0" xtend "^4.0.0" @@ -4229,18 +4331,10 @@ strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" -strip-json-comments@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -supports-color@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -4270,20 +4364,20 @@ tapable@^0.2.5, tapable@~0.2.5: version "0.2.6" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" -tar-pack@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" +tar-pack@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" dependencies: - debug "~2.2.0" - fstream "~1.0.10" - fstream-ignore "~1.0.5" - once "~1.3.3" - readable-stream "~2.1.4" - rimraf "~2.5.1" - tar "~2.2.1" - uid-number "~0.0.6" - -tar@~2.2.1: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: @@ -4291,9 +4385,9 @@ tar@~2.2.1: fstream "^1.0.2" inherits "2" -test-exclude@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.0.0.tgz#0ddc0100b8ae7e88b34eb4fd98a907e961991900" +test-exclude@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.0.3.tgz#86a13ce3effcc60e6c90403cf31a27a60ac6c4e7" dependencies: arrify "^1.0.1" micromatch "^2.3.11" @@ -4341,9 +4435,9 @@ timers-browserify@^2.0.2: dependencies: setimmediate "^1.0.4" -tmp@0.0.28, tmp@0.0.x: - version "0.0.28" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" +tmp@0.0.31, tmp@0.0.x: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" dependencies: os-tmpdir "~1.0.1" @@ -4381,6 +4475,12 @@ tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + tunnel-agent@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" @@ -4396,30 +4496,30 @@ type-check@~0.3.2: prelude-ls "~1.1.2" type-is@~1.6.14: - version "1.6.14" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + version "1.6.15" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" dependencies: media-typer "0.3.0" - mime-types "~2.1.13" + mime-types "~2.1.15" typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -uglify-js@^2.6, uglify-js@^2.7.5: - version "2.7.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" +uglify-js@^2.6, uglify-js@^2.8.5: + version "2.8.21" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.21.tgz#1733f669ae6f82fc90c7b25ec0f5c783ee375314" dependencies: - async "~0.2.6" source-map "~0.5.1" - uglify-to-browserify "~1.0.0" yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -uid-number@~0.0.6: +uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -4447,8 +4547,8 @@ url-parse@1.0.x: requires-port "1.0.x" url-parse@^1.1.1: - version "1.1.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.7.tgz#025cff999653a459ab34232147d89514cc87d74a" + version "1.1.8" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.8.tgz#7a65b3a8d57a1e86af6b4e2276e34774167c0156" dependencies: querystringify "0.0.x" requires-port "1.0.x" @@ -4466,9 +4566,9 @@ user-home@^2.0.0: dependencies: os-homedir "^1.0.0" -useragent@^2.1.10: - version "2.1.12" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.1.12.tgz#aa7da6cdc48bdc37ba86790871a7321d64edbaa2" +useragent@^2.1.12: + version "2.1.13" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.1.13.tgz#bba43e8aa24d5ceb83c2937473e102e21df74c10" dependencies: lru-cache "2.2.x" tmp "0.0.x" @@ -4503,8 +4603,8 @@ validate-npm-package-license@^3.0.1: spdx-expression-parse "~1.0.0" vary@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + version "1.1.1" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" verror@1.3.6: version "1.3.6" @@ -4531,12 +4631,12 @@ vue-resource@^0.9.3: resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-0.9.3.tgz#ab46e1c44ea219142dcc28ae4043b3b04c80959d" vue@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.2.4.tgz#d0a3a050a80a12356d7950ae5a7b3131048209cc" + version "2.2.6" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.2.6.tgz#451714b394dd6d4eae7b773c40c2034a59621aed" -watchpack@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.2.1.tgz#01efa80c5c29e5c56ba55d6f5470a35b6402f0b2" +watchpack@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" dependencies: async "^2.1.2" chokidar "^1.4.3" @@ -4549,8 +4649,8 @@ wbuf@^1.1.0, wbuf@^1.4.0: minimalistic-assert "^1.0.0" webpack-bundle-analyzer@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.3.0.tgz#0d05e96a43033f7cc57f6855b725782ba61e93a4" + version "2.3.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.3.1.tgz#d97f8aadbcce68fc865c5787741d8549359a25cd" dependencies: acorn "^4.0.11" chalk "^1.1.3" @@ -4564,8 +4664,8 @@ webpack-bundle-analyzer@^2.3.0: opener "^1.4.2" webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.0.tgz#7d5be2651e692fddfafd8aaed177c16ff51f0eb8" + version "1.10.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.1.tgz#c6b4cf428139cf1aefbe06a0c00fdb4f8da2f893" dependencies: memory-fs "~0.4.1" mime "^1.3.4" @@ -4573,8 +4673,8 @@ webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.9.0: range-parser "^1.0.3" webpack-dev-server@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.3.0.tgz#0437704bbd4d941a6e4c061eb3cc232ed7d06101" + version "2.4.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.4.2.tgz#cf595d6b40878452b6d2ad7229056b686f8a16be" dependencies: ansi-html "0.0.7" chokidar "^1.6.0" @@ -4582,28 +4682,35 @@ webpack-dev-server@^2.3.0: connect-history-api-fallback "^1.3.0" express "^4.13.3" html-entities "^1.2.0" - http-proxy-middleware "~0.17.1" + http-proxy-middleware "~0.17.4" opn "4.0.2" portfinder "^1.0.9" serve-index "^1.7.2" sockjs "0.3.18" - sockjs-client "1.1.1" + sockjs-client "1.1.2" spdy "^3.4.1" strip-ansi "^3.0.0" supports-color "^3.1.1" webpack-dev-middleware "^1.9.0" yargs "^6.0.0" -webpack-sources@^0.1.0, webpack-sources@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.4.tgz#ccc2c817e08e5fa393239412690bb481821393cd" +webpack-sources@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" dependencies: source-list-map "~0.1.7" source-map "~0.5.3" +webpack-sources@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" + dependencies: + source-list-map "^1.1.1" + source-map "~0.5.3" + webpack@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.2.1.tgz#7bb1d72ae2087dd1a4af526afec15eed17dda475" + version "2.3.3" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.3.3.tgz#eecc083c18fb7bf958ea4f40b57a6640c5a0cc78" dependencies: acorn "^4.0.4" acorn-dynamic-import "^2.0.0" @@ -4621,9 +4728,9 @@ webpack@^2.2.1: source-map "^0.5.3" supports-color "^3.1.0" tapable "~0.2.5" - uglify-js "^2.7.5" - watchpack "^1.2.0" - webpack-sources "^0.1.4" + uglify-js "^2.8.5" + watchpack "^1.3.1" + webpack-sources "^0.2.3" yargs "^6.0.0" websocket-driver@>=0.5.1: @@ -4641,10 +4748,10 @@ which-module@^1.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" which@^1.1.1, which@~1.2.10: - version "1.2.12" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" dependencies: - isexe "^1.1.1" + isexe "^2.0.0" wide-align@^1.1.0: version "1.1.0" @@ -4685,9 +4792,9 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018" +ws@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f" dependencies: options ">=0.0.5" ultron "1.0.x" -- cgit v1.2.1