From 0a86eba50614591cb661c5b7ba3c2582dd66a6f4 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 12 May 2017 17:16:47 +0000 Subject: [PATCH] =?UTF-8?q?Removed=20all=20instances=20of=20Object.assign?= =?UTF-8?q?=20by=20using=20es6=20classes,=20also=20includes=20some=20?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/javascripts/droplab/drop_down.js | 128 +++++++++--------- app/assets/javascripts/droplab/drop_lab.js | 126 ++++++++--------- app/assets/javascripts/droplab/hook.js | 29 ++-- app/assets/javascripts/droplab/hook_button.js | 59 ++++---- app/assets/javascripts/droplab/hook_input.js | 68 +++++----- spec/javascripts/droplab/drop_down_spec.js | 53 ++------ spec/javascripts/droplab/hook_spec.js | 8 -- 7 files changed, 208 insertions(+), 263 deletions(-) diff --git a/app/assets/javascripts/droplab/drop_down.js b/app/assets/javascripts/droplab/drop_down.js index de3927d683c..70cd337fb8a 100644 --- a/app/assets/javascripts/droplab/drop_down.js +++ b/app/assets/javascripts/droplab/drop_down.js @@ -1,44 +1,42 @@ -/* eslint-disable */ - import utils from './utils'; import { SELECTED_CLASS, IGNORE_CLASS } from './constants'; -var DropDown = function(list) { - this.currentIndex = 0; - this.hidden = true; - this.list = typeof list === 'string' ? document.querySelector(list) : list; - this.items = []; +class DropDown { + constructor(list) { + this.currentIndex = 0; + this.hidden = true; + this.list = typeof list === 'string' ? document.querySelector(list) : list; + this.items = []; - this.eventWrapper = {}; + this.eventWrapper = {}; - this.getItems(); - this.initTemplateString(); - this.addEvents(); + this.getItems(); + this.initTemplateString(); + this.addEvents(); - this.initialState = list.innerHTML; -}; + this.initialState = list.innerHTML; + } -Object.assign(DropDown.prototype, { - getItems: function() { + getItems() { this.items = [].slice.call(this.list.querySelectorAll('li')); return this.items; - }, + } - initTemplateString: function() { - var items = this.items || this.getItems(); + initTemplateString() { + const items = this.items || this.getItems(); - var templateString = ''; + let templateString = ''; if (items.length > 0) templateString = items[items.length - 1].outerHTML; this.templateString = templateString; return this.templateString; - }, + } - clickEvent: function(e) { + clickEvent(e) { if (e.target.tagName === 'UL') return; if (e.target.classList.contains(IGNORE_CLASS)) return; - var selected = utils.closest(e.target, 'LI'); + const selected = utils.closest(e.target, 'LI'); if (!selected) return; this.addSelectedClass(selected); @@ -46,95 +44,95 @@ Object.assign(DropDown.prototype, { e.preventDefault(); this.hide(); - var listEvent = new CustomEvent('click.dl', { + const listEvent = new CustomEvent('click.dl', { detail: { list: this, - selected: selected, + selected, data: e.target.dataset, }, }); this.list.dispatchEvent(listEvent); - }, + } - addSelectedClass: function (selected) { + addSelectedClass(selected) { this.removeSelectedClasses(); selected.classList.add(SELECTED_CLASS); - }, + } - removeSelectedClasses: function () { + removeSelectedClasses() { const items = this.items || this.getItems(); items.forEach(item => item.classList.remove(SELECTED_CLASS)); - }, + } - addEvents: function() { - this.eventWrapper.clickEvent = this.clickEvent.bind(this) + addEvents() { + 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) { + setData(data) { this.data = data; this.render(data); - }, + } - addData: function(data) { + addData(data) { this.data = (this.data || []).concat(data); this.render(this.data); - }, + } - render: function(data) { + render(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.template(this.templateString, data); - var template = document.createElement('div'); + renderChildren(data) { + const html = utils.template(this.templateString, data); + const template = document.createElement('div'); template.innerHTML = html; - this.setImagesSrc(template); + DropDown.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() { + show() { if (!this.hidden) return; this.list.style.display = 'block'; this.currentIndex = 0; this.hidden = false; - }, + } - hide: function() { + hide() { if (this.hidden) return; this.list.style.display = 'none'; this.currentIndex = 0; this.hidden = true; - }, + } - toggle: function () { - this.hidden ? this.show() : this.hide(); - }, + toggle() { + if (this.hidden) return this.show(); - destroy: function() { + return this.hide(); + } + + destroy() { this.hide(); this.list.removeEventListener('click', this.eventWrapper.clickEvent); } -}); + + static setImagesSrc(template) { + const images = [...template.querySelectorAll('img[data-src]')]; + + images.forEach((image) => { + const img = image; + + img.src = img.getAttribute('data-src'); + img.removeAttribute('data-src'); + }); + } +} export default DropDown; diff --git a/app/assets/javascripts/droplab/drop_lab.js b/app/assets/javascripts/droplab/drop_lab.js index 6eb9f314af7..2a02ede72bf 100644 --- a/app/assets/javascripts/droplab/drop_lab.js +++ b/app/assets/javascripts/droplab/drop_lab.js @@ -1,99 +1,99 @@ -/* 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 = {}; +class DropLab { + constructor() { + this.ready = false; + this.hooks = []; + this.queuedData = []; + this.config = {}; - this.eventWrapper = {}; -}; + this.eventWrapper = {}; + } -Object.assign(DropLab.prototype, { - loadStatic: function(){ - var dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`)); + loadStatic() { + const dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`)); this.addHooks(dropdownTriggers); - }, + } - addData: function () { - var args = [].slice.apply(arguments); - this.applyArgs(args, '_addData'); - }, + addData(...args) { + this.applyArgs(args, 'processAddData'); + } - setData: function() { - var args = [].slice.apply(arguments); - this.applyArgs(args, '_setData'); - }, + setData(...args) { + this.applyArgs(args, 'processSetData'); + } - destroy: function() { + destroy() { this.hooks.forEach(hook => hook.destroy()); this.hooks = []; this.removeEvents(); - }, + } - applyArgs: function(args, methodName) { - if (this.ready) return this[methodName].apply(this, args); + applyArgs(args, methodName) { + if (this.ready) return this[methodName](...args); this.queuedData = this.queuedData || []; this.queuedData.push(args); - }, - _addData: function(trigger, data) { - this._processData(trigger, data, 'addData'); - }, + return this.ready; + } - _setData: function(trigger, data) { - this._processData(trigger, data, 'setData'); - }, + processAddData(trigger, data) { + this.processData(trigger, data, 'addData'); + } - _processData: function(trigger, data, methodName) { + processSetData(trigger, data) { + this.processData(trigger, data, 'setData'); + } + + processData(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) + addEvents() { + this.eventWrapper.documentClicked = this.documentClicked.bind(this); document.addEventListener('click', this.eventWrapper.documentClicked); - }, + } - documentClicked: function(e) { + documentClicked(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; + if (utils.isDropDownParts(thisTag, this.hooks)) return; + if (utils.isDropDownParts(e.target, this.hooks)) return; this.hooks.forEach(hook => hook.list.hide()); - }, + } - removeEvents: function(){ + removeEvents() { document.removeEventListener('click', this.eventWrapper.documentClicked); - }, - - changeHookList: function(trigger, list, plugins, config) { - const availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger; + } + changeHookList(trigger, list, plugins, config) { + const availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger; this.hooks.forEach((hook, i) => { - hook.list.list.dataset.dropdownActive = false; + const aHook = hook; - if (hook.trigger !== availableTrigger) return; + aHook.list.list.dataset.dropdownActive = false; - hook.destroy(); + if (aHook.trigger !== availableTrigger) return; + + aHook.destroy(); this.hooks.splice(i, 1); this.addHook(availableTrigger, list, plugins, config); }); - }, + } - addHook: function(hook, list, plugins, config) { + addHook(hook, list, plugins, config) { const availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook; let availableList; @@ -111,18 +111,18 @@ Object.assign(DropLab.prototype, { this.hooks.push(new HookObject(availableHook, availableList, plugins, config)); return this; - }, + } - addHooks: function(hooks, plugins, config) { + addHooks(hooks, plugins, config) { hooks.forEach(hook => this.addHook(hook, null, plugins, config)); return this; - }, + } - setConfig: function(obj){ + setConfig(obj) { this.config = obj; - }, + } - fireReady: function() { + fireReady() { const readyEvent = new CustomEvent('ready.dl', { detail: { dropdown: this, @@ -131,10 +131,14 @@ Object.assign(DropLab.prototype, { document.dispatchEvent(readyEvent); this.ready = true; - }, + } - init: function (hook, list, plugins, config) { - hook ? this.addHook(hook, list, plugins, config) : this.loadStatic(); + init(hook, list, plugins, config) { + if (hook) { + this.addHook(hook, list, plugins, config); + } else { + this.loadStatic(); + } this.addEvents(); @@ -146,7 +150,7 @@ Object.assign(DropLab.prototype, { this.queuedData = []; return this; - }, -}); + } +} export default DropLab; diff --git a/app/assets/javascripts/droplab/hook.js b/app/assets/javascripts/droplab/hook.js index 2f840083571..cf78165b0d8 100644 --- a/app/assets/javascripts/droplab/hook.js +++ b/app/assets/javascripts/droplab/hook.js @@ -1,22 +1,15 @@ -/* eslint-disable */ - import DropDown from './drop_down'; -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.id; -}; - -Object.assign(Hook.prototype, { - - addEvents: function(){}, - - constructor: Hook, -}); +class Hook { + constructor(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.id; + } +} export default Hook; diff --git a/app/assets/javascripts/droplab/hook_button.js b/app/assets/javascripts/droplab/hook_button.js index be8aead1303..af45eba74e7 100644 --- a/app/assets/javascripts/droplab/hook_button.js +++ b/app/assets/javascripts/droplab/hook_button.js @@ -1,65 +1,58 @@ -/* eslint-disable */ - import Hook from './hook'; -var HookButton = function(trigger, list, plugins, config) { - Hook.call(this, trigger, list, plugins, config); +class HookButton extends Hook { + constructor(trigger, list, plugins, config) { + super(trigger, list, plugins, config); - this.type = 'button'; - this.event = 'click'; + this.type = 'button'; + this.event = 'click'; - this.eventWrapper = {}; + this.eventWrapper = {}; - this.addEvents(); - this.addPlugins(); -}; + this.addEvents(); + this.addPlugins(); + } -HookButton.prototype = Object.create(Hook.prototype); - -Object.assign(HookButton.prototype, { - addPlugins: function() { + addPlugins() { this.plugins.forEach(plugin => plugin.init(this)); - }, + } - clicked: function(e){ - var buttonEvent = new CustomEvent('click.dl', { + clicked(e) { + const buttonEvent = new CustomEvent('click.dl', { detail: { hook: this, }, bubbles: true, - cancelable: true + cancelable: true, }); e.target.dispatchEvent(buttonEvent); this.list.toggle(); - }, + } - addEvents: function(){ + addEvents() { this.eventWrapper.clicked = this.clicked.bind(this); this.trigger.addEventListener('click', this.eventWrapper.clicked); - }, + } - removeEvents: function(){ + removeEvents() { this.trigger.removeEventListener('click', this.eventWrapper.clicked); - }, + } - restoreInitialState: function() { + restoreInitialState() { this.list.list.innerHTML = this.list.initialState; - }, + } - removePlugins: function() { + removePlugins() { this.plugins.forEach(plugin => plugin.destroy()); - }, + } - destroy: function() { + destroy() { 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 index 05082334045..19131a64f2c 100644 --- a/app/assets/javascripts/droplab/hook_input.js +++ b/app/assets/javascripts/droplab/hook_input.js @@ -1,25 +1,23 @@ -/* eslint-disable */ - import Hook from './hook'; -var HookInput = function(trigger, list, plugins, config) { - Hook.call(this, trigger, list, plugins, config); +class HookInput extends Hook { + constructor(trigger, list, plugins, config) { + super(trigger, list, plugins, config); - this.type = 'input'; - this.event = 'input'; + this.type = 'input'; + this.event = 'input'; - this.eventWrapper = {}; + this.eventWrapper = {}; - this.addEvents(); - this.addPlugins(); -}; + this.addEvents(); + this.addPlugins(); + } -Object.assign(HookInput.prototype, { - addPlugins: function() { + addPlugins() { this.plugins.forEach(plugin => plugin.init(this)); - }, + } - addEvents: function(){ + addEvents() { this.eventWrapper.mousedown = this.mousedown.bind(this); this.eventWrapper.input = this.input.bind(this); this.eventWrapper.keyup = this.keyup.bind(this); @@ -29,19 +27,19 @@ Object.assign(HookInput.prototype, { this.trigger.addEventListener('input', this.eventWrapper.input); this.trigger.addEventListener('keyup', this.eventWrapper.keyup); this.trigger.addEventListener('keydown', this.eventWrapper.keydown); - }, + } - removeEvents: function() { + removeEvents() { 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; + input(e) { + if (this.hasRemovedEvents) return; this.list.show(); @@ -51,12 +49,12 @@ Object.assign(HookInput.prototype, { text: e.target.value, }, bubbles: true, - cancelable: true + cancelable: true, }); e.target.dispatchEvent(inputEvent); - }, + } - mousedown: function(e) { + mousedown(e) { if (this.hasRemovedEvents) return; const mouseEvent = new CustomEvent('mousedown.dl', { @@ -68,21 +66,21 @@ Object.assign(HookInput.prototype, { cancelable: true, }); e.target.dispatchEvent(mouseEvent); - }, + } - keyup: function(e) { + keyup(e) { if (this.hasRemovedEvents) return; this.keyEvent(e, 'keyup.dl'); - }, + } - keydown: function(e) { + keydown(e) { if (this.hasRemovedEvents) return; this.keyEvent(e, 'keydown.dl'); - }, + } - keyEvent: function(e, eventName) { + keyEvent(e, eventName) { this.list.show(); const keyEvent = new CustomEvent(eventName, { @@ -96,17 +94,17 @@ Object.assign(HookInput.prototype, { cancelable: true, }); e.target.dispatchEvent(keyEvent); - }, + } - restoreInitialState: function() { + restoreInitialState() { this.list.list.innerHTML = this.list.initialState; - }, + } - removePlugins: function() { + removePlugins() { this.plugins.forEach(plugin => plugin.destroy()); - }, + } - destroy: function() { + destroy() { this.restoreInitialState(); this.removeEvents(); @@ -114,6 +112,6 @@ Object.assign(HookInput.prototype, { this.list.destroy(); } -}); +} export default HookInput; diff --git a/spec/javascripts/droplab/drop_down_spec.js b/spec/javascripts/droplab/drop_down_spec.js index e7786e8cc2c..2bbcebeeac0 100644 --- a/spec/javascripts/droplab/drop_down_spec.js +++ b/spec/javascripts/droplab/drop_down_spec.js @@ -1,5 +1,3 @@ -/* eslint-disable */ - import DropDown from '~/droplab/drop_down'; import utils from '~/droplab/utils'; import { SELECTED_CLASS, IGNORE_CLASS } from '~/droplab/constants'; @@ -17,7 +15,7 @@ describe('DropDown', function () { 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); @@ -152,7 +150,7 @@ describe('DropDown', function () { it('should call addSelectedClass', function () { expect(this.dropdown.addSelectedClass).toHaveBeenCalledWith(this.closestElement); - }) + }); it('should call .preventDefault', function () { expect(this.event.preventDefault).toHaveBeenCalled(); @@ -293,36 +291,6 @@ describe('DropDown', 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: () => {} }; @@ -399,7 +367,7 @@ describe('DropDown', function () { expect(this.data.map).toHaveBeenCalledWith(jasmine.any(Function)); }); - it('should call .renderChildren for each data item', function() { + it('should call .renderChildren for each data item', function () { expect(this.dropdown.renderChildren.calls.count()).toBe(this.data.length); }); @@ -407,7 +375,7 @@ describe('DropDown', function () { expect(this.renderableList.innerHTML).toBe('01'); }); - describe('if no data argument is passed' , function () { + describe('if no data argument is passed', function () { beforeEach(function () { this.data.map.calls.reset(); this.dropdown.renderChildren.calls.reset(); @@ -446,14 +414,14 @@ describe('DropDown', function () { describe('renderChildren', function () { beforeEach(function () { this.templateString = 'templateString'; - this.dropdown = { setImagesSrc: () => {}, templateString: this.templateString }; + this.dropdown = { templateString: this.templateString }; this.data = { droplab_hidden: true }; this.html = 'html'; this.template = { firstChild: { outerHTML: 'outerHTML', style: {} } }; spyOn(utils, 'template').and.returnValue(this.html); spyOn(document, 'createElement').and.returnValue(this.template); - spyOn(this.dropdown, 'setImagesSrc'); + spyOn(DropDown, 'setImagesSrc'); this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data); }); @@ -471,7 +439,7 @@ describe('DropDown', function () { }); it('should call .setImagesSrc with the template', function () { - expect(this.dropdown.setImagesSrc).toHaveBeenCalledWith(this.template); + expect(DropDown.setImagesSrc).toHaveBeenCalledWith(this.template); }); it('should set the template display to none', function () { @@ -496,12 +464,11 @@ describe('DropDown', function () { describe('setImagesSrc', function () { beforeEach(function () { - this.dropdown = {}; this.template = { querySelectorAll: () => {} }; spyOn(this.template, 'querySelectorAll').and.returnValue([]); - DropDown.prototype.setImagesSrc.call(this.dropdown, this.template); + DropDown.setImagesSrc(this.template); }); it('should call .querySelectorAll', function () { @@ -562,7 +529,7 @@ describe('DropDown', function () { describe('toggle', function () { beforeEach(function () { - this.hidden = true + this.hidden = true; this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} }; spyOn(this.dropdown, 'show'); @@ -577,7 +544,7 @@ describe('DropDown', function () { describe('if .hidden is false', function () { beforeEach(function () { - this.hidden = false + this.hidden = false; this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} }; spyOn(this.dropdown, 'show'); diff --git a/spec/javascripts/droplab/hook_spec.js b/spec/javascripts/droplab/hook_spec.js index 8ebdcdd1404..75bf5f3d611 100644 --- a/spec/javascripts/droplab/hook_spec.js +++ b/spec/javascripts/droplab/hook_spec.js @@ -1,5 +1,3 @@ -/* eslint-disable */ - import Hook from '~/droplab/hook'; import * as dropdownSrc from '~/droplab/drop_down'; @@ -73,10 +71,4 @@ describe('Hook', function () { }); }); }); - - describe('addEvents', function () { - it('should exist', function () { - expect(Hook.prototype.hasOwnProperty('addEvents')).toBe(true); - }); - }); });