choices.js
Advanced tools
Comparing version 6.0.1 to 6.0.2
{ | ||
"name": "choices.js", | ||
"version": "6.0.1", | ||
"version": "6.0.2", | ||
"description": "A vanilla JS customisable text input/select box plugin", | ||
@@ -15,3 +15,3 @@ "main": "./public/assets/scripts/choices.min.js", | ||
"cypress:open": "$(npm bin)/cypress open", | ||
"test": "run-p test:unit test:e2e", | ||
"test": "npm run test:unit && npm run test:e2e", | ||
"test:unit": "mocha --require ./config/jsdom.js --require @babel/register $(find src -name '*.test.js') --exit", | ||
@@ -18,0 +18,0 @@ "test:unit:watch": "npm run test:unit -- --watch --inspect=5556", |
@@ -32,3 +32,2 @@ import Fuse from 'fuse.js'; | ||
strToEl, | ||
extend, | ||
sortByScore, | ||
@@ -1791,3 +1790,3 @@ generateId, | ||
this.config.templates = extend(TEMPLATES, userTemplates); | ||
this.config.templates = merge(TEMPLATES, userTemplates); | ||
} | ||
@@ -1794,0 +1793,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { calcWidthOfInput, stripHTML } from '../lib/utils'; | ||
import { calcWidthOfInput, sanitise } from '../lib/utils'; | ||
@@ -6,3 +6,2 @@ export default class Input { | ||
Object.assign(this, { element, type, classNames, placeholderValue }); | ||
this.element = element; | ||
@@ -12,4 +11,2 @@ this.classNames = classNames; | ||
this.isDisabled = false; | ||
// Bind event listeners | ||
this._onPaste = this._onPaste.bind(this); | ||
@@ -26,7 +23,7 @@ this._onInput = this._onInput.bind(this); | ||
set value(value) { | ||
this.element.value = `${value}`; | ||
this.element.value = value; | ||
} | ||
get value() { | ||
return stripHTML(this.element.value); | ||
return sanitise(this.element.value); | ||
} | ||
@@ -140,3 +137,2 @@ | ||
const { target } = event; | ||
// Disable pasting into the input if option has been set | ||
if (target === this.element && this.preventPaste) { | ||
@@ -143,0 +139,0 @@ event.preventDefault(); |
import WrappedElement from './wrapped-element'; | ||
import { reduceToValues } from './../lib/utils'; | ||
@@ -11,7 +10,7 @@ export default class WrappedInput extends WrappedElement { | ||
set value(items) { | ||
const itemsFiltered = reduceToValues(items); | ||
const itemsFilteredString = itemsFiltered.join(this.delimiter); | ||
const itemValues = items.map(({ value }) => value); | ||
const joinedValues = itemValues.join(this.delimiter); | ||
this.element.setAttribute('value', itemsFilteredString); | ||
this.element.value = itemsFilteredString; | ||
this.element.setAttribute('value', joinedValues); | ||
this.element.value = joinedValues; | ||
} | ||
@@ -18,0 +17,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { stripHTML, sortByAlpha } from './lib/utils'; | ||
import { sanitise, sortByAlpha } from './lib/utils'; | ||
@@ -68,3 +68,3 @@ export const DEFAULT_CLASSNAMES = { | ||
customAddItemText: 'Only values matching specific conditions can be added', | ||
addItemText: value => `Press Enter to add <b>"${stripHTML(value)}"</b>`, | ||
addItemText: value => `Press Enter to add <b>"${sanitise(value)}"</b>`, | ||
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added`, | ||
@@ -71,0 +71,0 @@ itemComparer: (choice, item) => choice === item, |
@@ -1,8 +0,5 @@ | ||
/* eslint-disable */ | ||
export const getRandomNumber = (min, max) => | ||
Math.floor(Math.random() * (max - min) + min); | ||
export const getRandomNumber = function(min, max) { | ||
return Math.floor(Math.random() * (max - min) + min); | ||
}; | ||
export const generateChars = function(length) { | ||
export const generateChars = length => { | ||
let chars = ''; | ||
@@ -18,3 +15,3 @@ | ||
export const generateId = function(element, prefix) { | ||
export const generateId = (element, prefix) => { | ||
let id = | ||
@@ -30,52 +27,10 @@ element.id || | ||
export const getType = function(obj) { | ||
return Object.prototype.toString.call(obj).slice(8, -1); | ||
}; | ||
export const getType = obj => Object.prototype.toString.call(obj).slice(8, -1); | ||
export const isType = function(type, obj) { | ||
const clas = getType(obj); | ||
return obj !== undefined && obj !== null && clas === type; | ||
}; | ||
export const isType = (type, obj) => | ||
obj !== undefined && obj !== null && getType(obj) === type; | ||
export const isElement = (element) => { | ||
return element instanceof Element; | ||
}; | ||
export const isElement = element => element instanceof Element; | ||
export const extend = function() { | ||
const extended = {}; | ||
const length = arguments.length; | ||
/** | ||
* Merge one object into another | ||
* @param {Object} obj Object to merge into extended object | ||
*/ | ||
const merge = function(obj) { | ||
for (const prop in obj) { | ||
if (Object.prototype.hasOwnProperty.call(obj, prop)) { | ||
// If deep merge and property is an object, merge properties | ||
if (isType('Object', obj[prop])) { | ||
extended[prop] = extend(true, extended[prop], obj[prop]); | ||
} else { | ||
extended[prop] = obj[prop]; | ||
} | ||
} | ||
} | ||
}; | ||
// Loop through each passed argument | ||
for (let i = 0; i < length; i++) { | ||
// store argument at position i | ||
const obj = arguments[i]; | ||
// If we are in fact dealing with an object, merge it. | ||
if (isType('Object', obj)) { | ||
merge(obj); | ||
} | ||
} | ||
return extended; | ||
}; | ||
export const wrap = function(element, wrapper) { | ||
wrapper = wrapper || document.createElement('div'); | ||
export const wrap = (element, wrapper = document.createElement('div')) => { | ||
if (element.nextSibling) { | ||
@@ -89,8 +44,3 @@ element.parentNode.insertBefore(wrapper, element.nextSibling); | ||
export const findAncestor = function(el, cls) { | ||
while ((el = el.parentElement) && !el.classList.contains(cls)); | ||
return el; | ||
}; | ||
export const findAncestorByAttrName = function(el, attr) { | ||
export const findAncestorByAttrName = (el, attr) => { | ||
let target = el; | ||
@@ -110,3 +60,5 @@ | ||
export const getAdjacentEl = (startEl, className, direction = 1) => { | ||
if (!startEl || !className) return; | ||
if (!startEl || !className) { | ||
return; | ||
} | ||
@@ -123,3 +75,5 @@ const parent = startEl.parentNode.parentNode; | ||
export const isScrolledIntoView = (el, parent, direction = 1) => { | ||
if (!el) return; | ||
if (!el) { | ||
return; | ||
} | ||
@@ -140,4 +94,8 @@ let isVisible; | ||
export const stripHTML = html => | ||
html | ||
export const sanitise = value => { | ||
if (!isType('String', value)) { | ||
return value; | ||
} | ||
return value | ||
.replace(/&/g, '&') | ||
@@ -147,10 +105,10 @@ .replace(/>/g, '&rt;') | ||
.replace(/"/g, '"'); | ||
}; | ||
export const strToEl = (function() { | ||
export const strToEl = (() => { | ||
const tmpEl = document.createElement('div'); | ||
return function(str) { | ||
return str => { | ||
const cleanedInput = str.trim(); | ||
let r; | ||
tmpEl.innerHTML = cleanedInput; | ||
r = tmpEl.children[0]; | ||
const firldChild = tmpEl.children[0]; | ||
@@ -161,3 +119,3 @@ while (tmpEl.firstChild) { | ||
return r; | ||
return firldChild; | ||
}; | ||
@@ -175,3 +133,3 @@ })(); | ||
if (value) { | ||
const testEl = strToEl(`<span>${stripHTML(value)}</span>`); | ||
const testEl = strToEl(`<span>${sanitise(value)}</span>`); | ||
testEl.style.position = 'absolute'; | ||
@@ -215,4 +173,4 @@ testEl.style.padding = '0'; | ||
export const sortByAlpha = (a, b) => { | ||
const labelA = (a.label || a.value).toLowerCase(); | ||
const labelB = (b.label || b.value).toLowerCase(); | ||
const labelA = `${a.label || a.value}`.toLowerCase(); | ||
const labelB = `${b.label || b.value}`.toLowerCase(); | ||
@@ -254,11 +212,2 @@ if (labelA < labelB) { | ||
export const reduceToValues = (items, key = 'value') => { | ||
const values = items.reduce((prev, current) => { | ||
prev.push(current[key]); | ||
return prev; | ||
}, []); | ||
return values; | ||
}; | ||
export const fetchFromObject = (object, path) => { | ||
@@ -298,5 +247,3 @@ const index = path.indexOf('.'); | ||
return aKeys.filter((i) => { | ||
return bKeys.indexOf(i) < 0; | ||
}); | ||
} | ||
return aKeys.filter(i => bKeys.indexOf(i) < 0); | ||
}; |
import { expect } from 'chai'; | ||
import { stub } from 'sinon'; | ||
import { | ||
reduceToValues, | ||
getRandomNumber, | ||
@@ -11,3 +10,3 @@ generateChars, | ||
isElement, | ||
stripHTML, | ||
sanitise, | ||
sortByAlpha, | ||
@@ -22,50 +21,2 @@ sortByScore, | ||
describe('utils', () => { | ||
describe('reduceToValues', () => { | ||
const items = [ | ||
{ | ||
id: 1, | ||
choiceId: 1, | ||
groupId: -1, | ||
value: 'Item one', | ||
label: 'Item one', | ||
active: false, | ||
highlighted: false, | ||
customProperties: null, | ||
placeholder: false, | ||
keyCode: null, | ||
}, | ||
{ | ||
id: 2, | ||
choiceId: 2, | ||
groupId: -1, | ||
value: 'Item two', | ||
label: 'Item two', | ||
active: true, | ||
highlighted: false, | ||
customProperties: null, | ||
placeholder: false, | ||
keyCode: null, | ||
}, | ||
{ | ||
id: 3, | ||
choiceId: 3, | ||
groupId: -1, | ||
value: 'Item three', | ||
label: 'Item three', | ||
active: true, | ||
highlighted: true, | ||
customProperties: null, | ||
placeholder: false, | ||
keyCode: null, | ||
}, | ||
]; | ||
it('returns an array of item values', () => { | ||
const expectedResponse = [items[0].value, items[1].value, items[2].value]; | ||
const actualResponse = reduceToValues(items); | ||
expect(actualResponse).to.eql(expectedResponse); | ||
}); | ||
}); | ||
describe('getRandomNumber', () => { | ||
@@ -159,6 +110,6 @@ it('returns random number between range', () => { | ||
describe('stripHTML', () => { | ||
describe('sanitise', () => { | ||
it('strips HTML from value', () => { | ||
const value = '<script>somethingMalicious();</script>'; | ||
const output = stripHTML(value); | ||
const output = sanitise(value); | ||
expect(output).to.equal( | ||
@@ -253,21 +204,2 @@ '<script&rt;somethingMalicious();</script&rt;', | ||
describe('reduceToValues', () => { | ||
it('reduces an array of objects to an array of values using given key', () => { | ||
const values = [ | ||
{ name: 'The Strokes' }, | ||
{ name: 'Arctic Monkeys' }, | ||
{ name: 'Oasis' }, | ||
{ name: 'Tame Impala' }, | ||
]; | ||
const output = reduceToValues(values, 'name'); | ||
expect(output).to.eql([ | ||
'The Strokes', | ||
'Arctic Monkeys', | ||
'Oasis', | ||
'Tame Impala', | ||
]); | ||
}); | ||
}); | ||
describe('fetchFromObject', () => { | ||
@@ -274,0 +206,0 @@ it('fetches value from object using given path', () => { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
668896
63
15182