From 1d9cd8e5027c6dd9df477201d0f42f340795692b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonny=20Str=C3=B6mberg?= Date: Sat, 21 Nov 2020 12:32:45 +0100 Subject: [PATCH] Prettier on everything --- __test__/add-get-remove.test.js | 296 +- __test__/buttons.test.js | 296 +- __test__/create.test.js | 267 +- __test__/defaults.test.js | 114 +- __test__/filter.test.js | 185 +- __test__/fixtures-fuzzysearch.js | 76 +- __test__/fixtures-pagination.js | 216 +- __test__/fixtures.js | 71 +- __test__/fuzzysearch.test.js | 114 +- __test__/item.test.js | 253 +- __test__/off.test.js | 71 +- __test__/on.test.js | 209 +- __test__/pagination.test.js | 480 ++-- __test__/parse.test.js | 192 +- __test__/re-index.test.js | 59 +- __test__/search-filter.test.js | 123 +- __test__/search.test.js | 289 +- __test__/show.test.js | 406 +-- __test__/sort.test.js | 703 ++--- __test__/trigger.test.js | 37 +- __test__/usage/main.js | 10 +- __test__/usage/require.js | 3871 ++++++++++++++------------- __test__/utils.classes.test.js | 73 +- __test__/utils.get-by-class.test.js | 38 +- package.json | 1 + prettier.config.js | 5 + src/add-async.js | 26 +- src/filter.js | 37 +- src/fuzzy-search.js | 77 +- src/index.js | 324 +-- src/item.js | 68 +- src/pagination.js | 119 +- src/parse.js | 53 +- src/search.js | 149 +- src/sort.js | 126 +- src/templater.js | 188 +- src/utils/classes.js | 100 +- src/utils/events.js | 26 +- src/utils/extend.js | 22 +- src/utils/fuzzy.js | 210 +- src/utils/get-attribute.js | 20 +- src/utils/get-by-class.js | 56 +- src/utils/index-of.js | 12 +- src/utils/to-array.js | 26 +- src/utils/to-string.js | 12 +- 45 files changed, 5130 insertions(+), 4976 deletions(-) create mode 100644 prettier.config.js diff --git a/__test__/add-get-remove.test.js b/__test__/add-get-remove.test.js index 09baa65f..3fdd2535 100644 --- a/__test__/add-get-remove.test.js +++ b/__test__/add-get-remove.test.js @@ -1,121 +1,193 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Add, get, remove', function() { +describe('Add, get, remove', function () { + var list - var list; + beforeAll(function () { + list = fixture.list(['name'], [{ name: 'Jonny' }]) + }) - beforeAll(function() { - list = fixture.list(['name'], [ { name: "Jonny" } ]); - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); + afterEach(function () { + list.clear() + list.add({ name: 'Jonny' }) + }) - afterEach(function() { - list.clear(); - list.add({ name: "Jonny" }); - }); + describe('Add', function () { + it('should add one item', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + }) + it('should add two items', function () { + list.add([{ name: 'Martina' }, { name: 'Angelica' }]) + expect(list.items.length).toEqual(3) + }) + it('should add async items', function (done) { + list.add( + [ + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + { name: 'Sven' }, + ], + function () { + expect(list.items.length).toEqual(91) + done() + } + ) + }) + it('should add async items to empty list', function (done) { + list.clear() + list.add([{ name: 'Sven' }], function () { + expect(list.items.length).toEqual(1) + done() + }) + }) + }) - describe('Add', function() { - it('should add one item', function() { - list.add({ name: 'Jonas' }); - expect(list.items.length).toEqual(2); - }); - it('should add two items', function() { - list.add([ - { name: 'Martina' }, - { name: 'Angelica' } - ]); - expect(list.items.length).toEqual(3); - }); - it('should add async items', function(done) { - list.add([ -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'}, -{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'},{name:'Sven'} - ], function() { - expect(list.items.length).toEqual(91); - done(); - }); - }); - it('should add async items to empty list', function(done) { - list.clear(); - list.add([ - { name: 'Sven' } - ], function() { - expect(list.items.length).toEqual(1); - done(); - }); - }); - }); + describe('Get', function () { + it('should return array with one item', function () { + var items = list.get('name', 'Jonny') + expect(items[0].values().name).toEqual('Jonny') + }) + it('should return empty array', function () { + var items = list.get('name', 'jonny') + expect(items.length).toBe(0) + }) + it('should return two items', function () { + list.add({ name: 'Jonny' }) + var items = list.get('name', 'Jonny') + expect(items.length).toEqual(2) + expect(items[0].values().name).toEqual('Jonny') + expect(items[1].values().name).toEqual('Jonny') + }) + }) - describe('Get', function() { - it('should return array with one item', function() { - var items = list.get('name', 'Jonny'); - expect(items[0].values().name).toEqual('Jonny'); - }); - it('should return empty array', function() { - var items = list.get('name', 'jonny'); - expect(items.length).toBe(0); - }); - it('should return two items', function() { - list.add({ name: 'Jonny' }); - var items = list.get('name', 'Jonny'); - expect(items.length).toEqual(2); - expect(items[0].values().name).toEqual('Jonny'); - expect(items[1].values().name).toEqual('Jonny'); - }); - }); + describe('Remove', function () { + it('should remove one item', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + var count = list.remove('name', 'Jonas') + expect(count).toEqual(1) + expect(list.items.length).toEqual(1) + }) + it('should not remove anything due to case sensitivity', function () { + var count = list.remove('name', 'jonny') + expect(count).toBe(0) + expect(list.items.length).toEqual(1) + }) - describe('Remove', function() { - it('should remove one item', function() { - list.add({ name: "Jonas" }); - expect(list.items.length).toEqual(2); - var count = list.remove('name', 'Jonas'); - expect(count).toEqual(1); - expect(list.items.length).toEqual(1); - }); - it('should not remove anything due to case sensitivity', function() { - var count = list.remove('name', 'jonny'); - expect(count).toBe(0); - expect(list.items.length).toEqual(1); - }); + it('should avoid node not found error', function () { + var item = list.get('name', 'Jonny')[0] + list.list.removeChild(item.elm) + var count = list.remove('name', 'Jonny') + expect(count).toBe(1) + expect(list.items.length).toEqual(0) + }) - it('should avoid node not found error', function() { - var item = list.get('name', 'Jonny')[0]; - list.list.removeChild(item.elm); - var count = list.remove('name', 'Jonny'); - expect(count).toBe(1); - expect(list.items.length).toEqual(0); - }); - - it('should remove eight items', function() { - list.add({ name: 'Jonny' }); - list.add({ name: 'Jonny' }); - list.add({ name: 'Sven' }); - list.add({ name: 'Jonny' }); - list.add({ name: 'Jonny' }); - list.add({ name: 'Jonny' }); - list.add({ name: 'Jonas' }); - list.add({ name: 'Jonny' }); - list.add({ name: 'Jonny' }); - expect(list.items.length).toEqual(10); - var count = list.remove('name', 'Jonny'); - expect(count).toEqual(8); - expect(list.items.length).toEqual(2); - }); - }); -}); + it('should remove eight items', function () { + list.add({ name: 'Jonny' }) + list.add({ name: 'Jonny' }) + list.add({ name: 'Sven' }) + list.add({ name: 'Jonny' }) + list.add({ name: 'Jonny' }) + list.add({ name: 'Jonny' }) + list.add({ name: 'Jonas' }) + list.add({ name: 'Jonny' }) + list.add({ name: 'Jonny' }) + expect(list.items.length).toEqual(10) + var count = list.remove('name', 'Jonny') + expect(count).toEqual(8) + expect(list.items.length).toEqual(2) + }) + }) +}) diff --git a/__test__/buttons.test.js b/__test__/buttons.test.js index 680afd44..2165579e 100644 --- a/__test__/buttons.test.js +++ b/__test__/buttons.test.js @@ -1,19 +1,19 @@ const $ = require('jquery'), - List = require('../src/index'); + List = require('../src/index') function fireKeyup(el) { if (document.createEvent) { - var evObj; + var evObj if (window.KeyEvent) { - evObj = document.createEvent('KeyEvents'); - evObj.initKeyEvent('keyup', true, true, window, false, false, false, false, 13, 0); + evObj = document.createEvent('KeyEvents') + evObj.initKeyEvent('keyup', true, true, window, false, false, false, false, 13, 0) } else { - evObj = document.createEvent('UIEvents'); - evObj.initUIEvent('keyup', true, true, window, 1); + evObj = document.createEvent('UIEvents') + evObj.initUIEvent('keyup', true, true, window, 1) } - el.dispatchEvent(evObj); - } else if( document.createEventObject ) { - el.fireEvent('onkeyup'); + el.dispatchEvent(evObj) + } else if (document.createEventObject) { + el.fireEvent('onkeyup') } else { // IE 5.0, seriously? :) } @@ -21,20 +21,21 @@ function fireKeyup(el) { // http://stackoverflow.com/questions/5658849/whats-the-equivalent-of-jquerys-trigger-method-without-jquery function fireClick(el) { - var evt; + var evt if (document.createEvent) { - evt = document.createEvent("MouseEvents"); - evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + evt = document.createEvent('MouseEvents') + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null) } - (evt) ? el.dispatchEvent(evt) : (el.click && el.click()); + evt ? el.dispatchEvent(evt) : el.click && el.click() } -describe('Button', function() { +describe('Button', function () { + var list - var list; - - beforeEach(function() { - $('body').append($('
\ + beforeEach(function () { + $('body').append( + $( + '
\ \ Sort name\ Sort name asc\ @@ -43,150 +44,151 @@ describe('Button', function() {
Jonny1986
\
Jocke1985
\
\ -
')); + ' + ) + ) list = new List('parse-list', { - valueNames: ['name', 'born'] - }); - }); + valueNames: ['name', 'born'], + }) + }) - afterEach(function() { - $('#parse-list').remove(); - }); + afterEach(function () { + $('#parse-list').remove() + }) - describe('Sort', function() { - it('should trigger sortStart', function(done) { - list.on('sortComplete', function() { - done(); - }); - fireClick($('#sort-name')[0]); - }); - it('should trigger sortComplete', function(done) { - list.on('sortComplete', function() { - done(); - }); - fireClick($('#sort-name')[0]); - }); + describe('Sort', function () { + it('should trigger sortStart', function (done) { + list.on('sortComplete', function () { + done() + }) + fireClick($('#sort-name')[0]) + }) + it('should trigger sortComplete', function (done) { + list.on('sortComplete', function () { + done() + }) + fireClick($('#sort-name')[0]) + }) - it('should switch sorting order when clicking multiple times', function(done) { - var sortRun = 0; - list.on('sortComplete', function() { - sortRun++; + it('should switch sorting order when clicking multiple times', function (done) { + var sortRun = 0 + list.on('sortComplete', function () { + sortRun++ if (sortRun == 1) { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - setTimeout(function() { - fireClick($('#sort-name')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + setTimeout(function () { + fireClick($('#sort-name')[0]) + }, 50) } else if (sortRun == 2) { - expect($('#sort-name').hasClass('asc')).toBe(false); - expect($('#sort-name').hasClass('desc')).toBe(true); - setTimeout(function() { - fireClick($('#sort-name')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(false) + expect($('#sort-name').hasClass('desc')).toBe(true) + setTimeout(function () { + fireClick($('#sort-name')[0]) + }, 50) } else if (sortRun == 3) { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - done(); + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + done() } - }); - expect($('#sort-name').hasClass('asc')).toBe(false); - expect($('#sort-name').hasClass('desc')).toBe(false); - fireClick($('#sort-name')[0]); - }); + }) + expect($('#sort-name').hasClass('asc')).toBe(false) + expect($('#sort-name').hasClass('desc')).toBe(false) + fireClick($('#sort-name')[0]) + }) - it('should sort with predefined order', function(done) { - var sortRun = 0; - list.on('sortComplete', function() { - sortRun++; + it('should sort with predefined order', function (done) { + var sortRun = 0 + list.on('sortComplete', function () { + sortRun++ if (sortRun == 1) { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - expect($('#sort-name-asc').hasClass('asc')).toBe(true); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(false); - setTimeout(function() { - fireClick($('#sort-name-asc')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + expect($('#sort-name-asc').hasClass('asc')).toBe(true) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(false) + setTimeout(function () { + fireClick($('#sort-name-asc')[0]) + }, 50) } else if (sortRun == 2) { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - expect($('#sort-name-asc').hasClass('asc')).toBe(true); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(false); - setTimeout(function() { - fireClick($('#sort-name-asc')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + expect($('#sort-name-asc').hasClass('asc')).toBe(true) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(false) + setTimeout(function () { + fireClick($('#sort-name-asc')[0]) + }, 50) } else if (sortRun == 3) { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - expect($('#sort-name-asc').hasClass('asc')).toBe(true); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(false); - setTimeout(function() { - fireClick($('#sort-name-desc')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + expect($('#sort-name-asc').hasClass('asc')).toBe(true) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(false) + setTimeout(function () { + fireClick($('#sort-name-desc')[0]) + }, 50) } else if (sortRun == 4) { - expect($('#sort-name').hasClass('asc')).toBe(false); - expect($('#sort-name').hasClass('desc')).toBe(true); - expect($('#sort-name-asc').hasClass('asc')).toBe(false); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(true); - setTimeout(function() { - fireClick($('#sort-name-desc')[0]); - }, 50); + expect($('#sort-name').hasClass('asc')).toBe(false) + expect($('#sort-name').hasClass('desc')).toBe(true) + expect($('#sort-name-asc').hasClass('asc')).toBe(false) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(true) + setTimeout(function () { + fireClick($('#sort-name-desc')[0]) + }, 50) } else if (sortRun == 5) { - expect($('#sort-name').hasClass('asc')).toBe(false); - expect($('#sort-name').hasClass('desc')).toBe(true); - expect($('#sort-name-asc').hasClass('asc')).toBe(false); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(true); - done(); + expect($('#sort-name').hasClass('asc')).toBe(false) + expect($('#sort-name').hasClass('desc')).toBe(true) + expect($('#sort-name-asc').hasClass('asc')).toBe(false) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(true) + done() } - }); - expect($('#sort-name').hasClass('asc')).toBe(false); - expect($('#sort-name').hasClass('desc')).toBe(false); - expect($('#sort-name-asc').hasClass('asc')).toBe(false); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(false); - fireClick($('#sort-name-asc')[0]); - }); - - it('buttons should change class when sorting programmatically', function(done) { - list.on('sortComplete', function() { - expect($('#sort-name').hasClass('asc')).toBe(true); - expect($('#sort-name').hasClass('desc')).toBe(false); - expect($('#sort-name-asc').hasClass('asc')).toBe(true); - expect($('#sort-name-asc').hasClass('desc')).toBe(false); - expect($('#sort-name-desc').hasClass('asc')).toBe(false); - expect($('#sort-name-desc').hasClass('desc')).toBe(false); - done(); - }); - list.sort('name', { order: "asc" }); - }); - }); + }) + expect($('#sort-name').hasClass('asc')).toBe(false) + expect($('#sort-name').hasClass('desc')).toBe(false) + expect($('#sort-name-asc').hasClass('asc')).toBe(false) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(false) + fireClick($('#sort-name-asc')[0]) + }) + it('buttons should change class when sorting programmatically', function (done) { + list.on('sortComplete', function () { + expect($('#sort-name').hasClass('asc')).toBe(true) + expect($('#sort-name').hasClass('desc')).toBe(false) + expect($('#sort-name-asc').hasClass('asc')).toBe(true) + expect($('#sort-name-asc').hasClass('desc')).toBe(false) + expect($('#sort-name-desc').hasClass('asc')).toBe(false) + expect($('#sort-name-desc').hasClass('desc')).toBe(false) + done() + }) + list.sort('name', { order: 'asc' }) + }) + }) - describe('Search', function() { - it('should trigger searchStart', function(done) { - list.on('searchStart', function() { - done(); - }); - $('#parse-list .search').val('jon'); - fireKeyup($('#parse-list .search')[0]); - }); - it('should trigger searchComplete', function(done) { - list.on('searchComplete', function() { - done(); - }); - $('#parse-list .search').val('jon'); - fireKeyup($('#parse-list .search')[0]); - }); - }); -}); + describe('Search', function () { + it('should trigger searchStart', function (done) { + list.on('searchStart', function () { + done() + }) + $('#parse-list .search').val('jon') + fireKeyup($('#parse-list .search')[0]) + }) + it('should trigger searchComplete', function (done) { + list.on('searchComplete', function () { + done() + }) + $('#parse-list .search').val('jon') + fireKeyup($('#parse-list .search')[0]) + }) + }) +}) diff --git a/__test__/create.test.js b/__test__/create.test.js index 6593b9d6..f25b6de2 100644 --- a/__test__/create.test.js +++ b/__test__/create.test.js @@ -1,154 +1,161 @@ const $ = require('jquery'), - List = require('../src/index'); + List = require('../src/index') -describe('Create', function() { - - describe('With HTML items', function() { - var listEl = $('
\ +describe('Create', function () { + describe('With HTML items', function () { + var listEl = $( + '
\
    \
  • Jonny
  • \
\ -
'); +
' + ) - $(document.body).append(listEl); + $(document.body).append(listEl) - var list = new List('list', { valueNames: ['name'] }); + var list = new List('list', { valueNames: ['name'] }) - it('should contain one item', function() { - expect(list.items.length).toEqual(1); - expect(listEl.find('li').length).toEqual(1); - }); + it('should contain one item', function () { + expect(list.items.length).toEqual(1) + expect(listEl.find('li').length).toEqual(1) + }) - it('should contain two items', function() { - list.add({ name: 'Jonas' }); - expect(list.items.length).toEqual(2); - expect(listEl.find('li').length).toEqual(2); - }); + it('should contain two items', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + expect(listEl.find('li').length).toEqual(2) + }) - listEl.remove(); - }); + listEl.remove() + }) - describe('Without items and with string template', function() { + describe('Without items and with string template', function () { var listEl = $('
\ \ -
'); - - $(document.body).append(listEl); - - var list = new List('list', { - valueNames: ['name'], - item: '
  • ' - }, [ - { name: 'Jonny' } - ]); - - it('should contain one item', function() { - expect(list.items.length).toEqual(1); - expect(listEl.find('li').length).toEqual(1); - }); - - it('should contain two items', function() { - list.add({ name: 'Jonas' }); - expect(list.items.length).toEqual(2); - expect(listEl.find('li').length).toEqual(2); - }); + ') - listEl.remove(); - }); + $(document.body).append(listEl) - describe('Without items and with string template for table', function() { + var list = new List( + 'list', + { + valueNames: ['name'], + item: '
  • ', + }, + [{ name: 'Jonny' }] + ) + + it('should contain one item', function () { + expect(list.items.length).toEqual(1) + expect(listEl.find('li').length).toEqual(1) + }) + + it('should contain two items', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + expect(listEl.find('li').length).toEqual(2) + }) + + listEl.remove() + }) + + describe('Without items and with string template for table', function () { var listEl = $('
    \
    \ -
    '); - - $(document.body).append(listEl); - - var list = new List('list', { - valueNames: ['name'], - item: '' - }, [ - { name: 'Jonny' } - ]); - - it('should contain one item', function() { - expect(list.items.length).toEqual(1); - expect(listEl.find('tr').length).toEqual(1); - }); - - it('should contain two items', function() { - list.add({ name: 'Jonas' }); - expect(list.items.length).toEqual(2); - expect(listEl.find('tr').length).toEqual(2); - }); + ') - listEl.remove(); - }); + $(document.body).append(listEl) - describe('without items and or template', function() { - - it('should not throw error on init', function() { + var list = new List( + 'list', + { + valueNames: ['name'], + item: '', + }, + [{ name: 'Jonny' }] + ) + + it('should contain one item', function () { + expect(list.items.length).toEqual(1) + expect(listEl.find('tr').length).toEqual(1) + }) + + it('should contain two items', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + expect(listEl.find('tr').length).toEqual(2) + }) + + listEl.remove() + }) + + describe('without items and or template', function () { + it('should not throw error on init', function () { var listEl = $('
    \ \ -
    '); - $(document.body).append(listEl); + ') + $(document.body).append(listEl) var list = new List('list', { - valueNames: ['name'] - }); + valueNames: ['name'], + }) - listEl.remove(); - }); + listEl.remove() + }) - it('should throw error when created items', function() { + it('should throw error when created items', function () { var listEl = $('
    \ \ -
    '); - $(document.body).append(listEl); + ') + $(document.body).append(listEl) var list = new List('list', { - valueNames: ['name'] - }); - expect(function() { - list.add({ name: 'Jonas' }); - }).toThrow(); - listEl.remove(); - }); - }); - - describe('Without items and with HTML template', function() { + valueNames: ['name'], + }) + expect(function () { + list.add({ name: 'Jonas' }) + }).toThrow() + listEl.remove() + }) + }) + + describe('Without items and with HTML template', function () { var listEl = $('
    \ \ -
    '); - - var templateEl = $('
  • '); + ') - $(document.body).append(listEl); - $(document.body).append(templateEl); + var templateEl = $('
  • ') - var list = new List('list', { - valueNames: ['name'], - item: 'template-item' - }, [ - { name: 'Jonny' } - ]); + $(document.body).append(listEl) + $(document.body).append(templateEl) - it('should contain one item', function() { - expect(list.items.length).toEqual(1); - expect(listEl.find('li').length).toEqual(1); - }); - - it('should contain two items', function() { - list.add({ name: 'Jonas' }); - expect(list.items.length).toEqual(2); - expect(listEl.find('li').length).toEqual(2); - }); - - listEl.remove(); - templateEl.remove(); - }); - - describe('Asyn index with existing list', function() { - var listEl = $('
    \ + var list = new List( + 'list', + { + valueNames: ['name'], + item: 'template-item', + }, + [{ name: 'Jonny' }] + ) + + it('should contain one item', function () { + expect(list.items.length).toEqual(1) + expect(listEl.find('li').length).toEqual(1) + }) + + it('should contain two items', function () { + list.add({ name: 'Jonas' }) + expect(list.items.length).toEqual(2) + expect(listEl.find('li').length).toEqual(2) + }) + + listEl.remove() + templateEl.remove() + }) + + describe('Asyn index with existing list', function () { + var listEl = $( + '
    \
      \
    • Jonny
    • Sven
    • \
    • Anna
    • Lisa
    • \ @@ -232,20 +239,20 @@ describe('Create', function() {
    • Imma
    • Hasse
    • \
    • Robert
    • Mona
    • \
    \ -
    '); +
    ' + ) - it('should contain one item', function(done) { - $(document.body).append(listEl); + it('should contain one item', function (done) { + $(document.body).append(listEl) var list = new List('list', { valueNames: ['name'], indexAsync: true, - parseComplete: function(list) { - expect(listEl.find('li').length).toEqual(162); - listEl.remove(); - done(); - } - }); - }); - }); - -}); + parseComplete: function (list) { + expect(listEl.find('li').length).toEqual(162) + listEl.remove() + done() + }, + }) + }) + }) +}) diff --git a/__test__/defaults.test.js b/__test__/defaults.test.js index 96e895c8..9633f64c 100644 --- a/__test__/defaults.test.js +++ b/__test__/defaults.test.js @@ -1,67 +1,67 @@ const $ = require('jquery'), - fixture = require('./fixtures'); + fixture = require('./fixtures') -describe('Defaults', function() { - var list; +describe('Defaults', function () { + var list - beforeAll(function() { - list = fixture.list(['name'], [ { name: 'Jonny' }]); - }); + beforeAll(function () { + list = fixture.list(['name'], [{ name: 'Jonny' }]) + }) - afterAll(function() { - fixture.removeList(); - }); + afterAll(function () { + fixture.removeList() + }) - it('should have all default attributes', function() { - expect(list.items).toBeInstanceOf(Array); - expect(list.visibleItems).toBeInstanceOf(Array); - expect(list.matchingItems).toBeInstanceOf(Array); + it('should have all default attributes', function () { + expect(list.items).toBeInstanceOf(Array) + expect(list.visibleItems).toBeInstanceOf(Array) + expect(list.matchingItems).toBeInstanceOf(Array) - expect(list.handlers.updated).toBeInstanceOf(Array); - expect(list.handlers.searchStart).toBeInstanceOf(Array); - expect(list.handlers.searchComplete).toBeInstanceOf(Array); - expect(list.handlers.sortStart).toBeInstanceOf(Array); - expect(list.handlers.sortComplete).toBeInstanceOf(Array); - expect(list.handlers.filterStart).toBeInstanceOf(Array); - expect(list.handlers.filterComplete).toBeInstanceOf(Array); + expect(list.handlers.updated).toBeInstanceOf(Array) + expect(list.handlers.searchStart).toBeInstanceOf(Array) + expect(list.handlers.searchComplete).toBeInstanceOf(Array) + expect(list.handlers.sortStart).toBeInstanceOf(Array) + expect(list.handlers.sortComplete).toBeInstanceOf(Array) + expect(list.handlers.filterStart).toBeInstanceOf(Array) + expect(list.handlers.filterComplete).toBeInstanceOf(Array) - expect(list.searched).toBe(false); - expect(list.filtered).toBe(false); - expect(list.i).toEqual(1); - expect(list.page).toEqual(10000); - expect(list.listClass).toEqual('list'); - expect(list.sortClass).toEqual('sort'); - expect(list.searchClass).toEqual('search'); - }); + expect(list.searched).toBe(false) + expect(list.filtered).toBe(false) + expect(list.i).toEqual(1) + expect(list.page).toEqual(10000) + expect(list.listClass).toEqual('list') + expect(list.sortClass).toEqual('sort') + expect(list.searchClass).toEqual('search') + }) - it('should have the right elements', function() { - expect(list.list).toEqual($('.list')[0]); - expect(list.listContainer).toEqual($('#list')[0]); - }); + it('should have the right elements', function () { + expect(list.list).toEqual($('.list')[0]) + expect(list.listContainer).toEqual($('#list')[0]) + }) - it('should have all default methods', function() { - expect(list.add).toBeInstanceOf(Function); - expect(list.remove).toBeInstanceOf(Function); - expect(list.get).toBeInstanceOf(Function); - expect(list.sort).toBeInstanceOf(Function); - expect(list.search).toBeInstanceOf(Function); - expect(list.clear).toBeInstanceOf(Function); - expect(list.filter).toBeInstanceOf(Function); - expect(list.size).toBeInstanceOf(Function); - expect(list.show).toBeInstanceOf(Function); - expect(list.update).toBeInstanceOf(Function); - expect(list.on).toBeInstanceOf(Function); - }); + it('should have all default methods', function () { + expect(list.add).toBeInstanceOf(Function) + expect(list.remove).toBeInstanceOf(Function) + expect(list.get).toBeInstanceOf(Function) + expect(list.sort).toBeInstanceOf(Function) + expect(list.search).toBeInstanceOf(Function) + expect(list.clear).toBeInstanceOf(Function) + expect(list.filter).toBeInstanceOf(Function) + expect(list.size).toBeInstanceOf(Function) + expect(list.show).toBeInstanceOf(Function) + expect(list.update).toBeInstanceOf(Function) + expect(list.on).toBeInstanceOf(Function) + }) - it('should have all helper methods', function() { - expect(list.utils.classes).toBeInstanceOf(Function); - expect(list.utils.getAttribute).toBeInstanceOf(Function); - expect(list.utils.getByClass).toBeInstanceOf(Function); - expect(list.utils.naturalSort).toBeInstanceOf(Function); - expect(list.utils.events.bind).toBeInstanceOf(Function); - expect(list.utils.events.unbind).toBeInstanceOf(Function); - expect(list.utils.extend).toBeInstanceOf(Function); - expect(list.utils.indexOf).toBeInstanceOf(Function); - expect(list.utils.toString).toBeInstanceOf(Function); - }); -}); + it('should have all helper methods', function () { + expect(list.utils.classes).toBeInstanceOf(Function) + expect(list.utils.getAttribute).toBeInstanceOf(Function) + expect(list.utils.getByClass).toBeInstanceOf(Function) + expect(list.utils.naturalSort).toBeInstanceOf(Function) + expect(list.utils.events.bind).toBeInstanceOf(Function) + expect(list.utils.events.unbind).toBeInstanceOf(Function) + expect(list.utils.extend).toBeInstanceOf(Function) + expect(list.utils.indexOf).toBeInstanceOf(Function) + expect(list.utils.toString).toBeInstanceOf(Function) + }) +}) diff --git a/__test__/filter.test.js b/__test__/filter.test.js index 2a4a3bef..37760e20 100644 --- a/__test__/filter.test.js +++ b/__test__/filter.test.js @@ -1,103 +1,102 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Filter', function() { +describe('Filter', function () { + var list, jonny, martina, angelica, sebastian, imma, hasse - var list, jonny, martina, angelica, sebastian, imma, hasse; + beforeAll(function () { + list = fixture.list(['name', 'born'], fixture.all) + jonny = list.get('name', 'Jonny Strömberg')[0] + martina = list.get('name', 'Martina Elm')[0] + angelica = list.get('name', 'Angelica Abraham')[0] + sebastian = list.get('name', 'Sebastian Höglund')[0] + imma = list.get('name', 'Imma Grafström')[0] + hasse = list.get('name', 'Hasse Strömberg')[0] + }) - beforeAll(function() { - list = fixture.list(['name', 'born'], fixture.all); - jonny = list.get('name', 'Jonny Strömberg')[0]; - martina = list.get('name', 'Martina Elm')[0]; - angelica = list.get('name', 'Angelica Abraham')[0]; - sebastian = list.get('name', 'Sebastian Höglund')[0]; - imma = list.get('name', 'Imma Grafström')[0]; - hasse = list.get('name', 'Hasse Strömberg')[0]; - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); + afterEach(function () { + list.filter() + list.show(1, 200) + }) - afterEach(function() { - list.filter(); - list.show(1, 200); - }); - - describe('Basics', function() { - it('should return everyone born after 1988', function() { - var result = list.filter(function(item) { - return (item.values().born > 1988); - }); - expect(result.length).toEqual(1); - expect(result[0]).toEqual(sebastian); - }); - it('should return everyone born 1986', function() { - var result = list.filter(function(item) { - return (item.values().born == 1986); - }); - expect(result.length).toEqual(3); + describe('Basics', function () { + it('should return everyone born after 1988', function () { + var result = list.filter(function (item) { + return item.values().born > 1988 + }) + expect(result.length).toEqual(1) + expect(result[0]).toEqual(sebastian) + }) + it('should return everyone born 1986', function () { + var result = list.filter(function (item) { + return item.values().born == 1986 + }) + expect(result.length).toEqual(3) for (var i = 0; i < result.length; i++) { - expect(result[i].values().born).toEqual('1986'); + expect(result[i].values().born).toEqual('1986') } - }); - }); + }) + }) - describe('Show and pages', function() { - it('should return the visible items', function() { - list.show(1,2); - var result = list.filter(function(item) { - return (item.values().born > 1985); - }); - expect(result).toEqual(list.visibleItems); - }); + describe('Show and pages', function () { + it('should return the visible items', function () { + list.show(1, 2) + var result = list.filter(function (item) { + return item.values().born > 1985 + }) + expect(result).toEqual(list.visibleItems) + }) - it('should return be 2 visible items and 3 matching', function() { - list.show(1,2); - var result = list.filter(function(item) { - return (item.values().born > 1985); - }); - expect(result.length).toEqual(2); - expect(list.visibleItems.length).toEqual(2); - expect(list.matchingItems.length).toEqual(4); - }); + it('should return be 2 visible items and 3 matching', function () { + list.show(1, 2) + var result = list.filter(function (item) { + return item.values().born > 1985 + }) + expect(result.length).toEqual(2) + expect(list.visibleItems.length).toEqual(2) + expect(list.matchingItems.length).toEqual(4) + }) - describe('Specific items', function() { - beforeEach(function() { - list.show(1,2); - var result = list.filter(function(item) { - return (item.values().born > 1985); - }); - }); - it('should match jonny', function() { - expect(jonny.matching()).toBe(true); - expect(jonny.filtered).toBe(true); - expect(jonny.visible()).toBe(true); - }); - it('should match martina', function() { - expect(martina.matching()).toBe(true); - expect(martina.filtered).toBe(true); - expect(martina.visible()).toBe(true); - }); - it('should match but not show angelica', function() { - expect(angelica.matching()).toBe(true); - expect(angelica.filtered).toBe(true); - expect(angelica.visible()).toBe(false); - }); - it('should match but not show sebastian', function() { - expect(sebastian.matching()).toBe(true); - expect(sebastian.filtered).toBe(true); - expect(sebastian.visible()).toBe(false); - }); - it('should not match imma', function() { - expect(imma.matching()).toBe(false); - expect(imma.filtered).toBe(false); - expect(imma.visible()).toBe(false); - }); - it('should not match hasse', function() { - expect(hasse.matching()).toBe(false); - expect(hasse.filtered).toBe(false); - expect(hasse.visible()).toBe(false); - }); - }); - }); -}); + describe('Specific items', function () { + beforeEach(function () { + list.show(1, 2) + var result = list.filter(function (item) { + return item.values().born > 1985 + }) + }) + it('should match jonny', function () { + expect(jonny.matching()).toBe(true) + expect(jonny.filtered).toBe(true) + expect(jonny.visible()).toBe(true) + }) + it('should match martina', function () { + expect(martina.matching()).toBe(true) + expect(martina.filtered).toBe(true) + expect(martina.visible()).toBe(true) + }) + it('should match but not show angelica', function () { + expect(angelica.matching()).toBe(true) + expect(angelica.filtered).toBe(true) + expect(angelica.visible()).toBe(false) + }) + it('should match but not show sebastian', function () { + expect(sebastian.matching()).toBe(true) + expect(sebastian.filtered).toBe(true) + expect(sebastian.visible()).toBe(false) + }) + it('should not match imma', function () { + expect(imma.matching()).toBe(false) + expect(imma.filtered).toBe(false) + expect(imma.visible()).toBe(false) + }) + it('should not match hasse', function () { + expect(hasse.matching()).toBe(false) + expect(hasse.filtered).toBe(false) + expect(hasse.visible()).toBe(false) + }) + }) + }) +}) diff --git a/__test__/fixtures-fuzzysearch.js b/__test__/fixtures-fuzzysearch.js index 3d2754c9..9cb95840 100644 --- a/__test__/fixtures-fuzzysearch.js +++ b/__test__/fixtures-fuzzysearch.js @@ -1,45 +1,45 @@ -const $ = require('jquery'); +const $ = require('jquery') var fixtureFuzzysearch = { - list: function(valueNames) { - var listHtml = $(''), - item = ""; + list: function (valueNames) { + var listHtml = $(''), + item = '' - item = "
  • "; - for (var i = 0; i < valueNames.length; i++) { - item += ''; - } - item += "
  • "; + item = '
  • ' + for (var i = 0; i < valueNames.length; i++) { + item += '' + } + item += '
  • ' - $(document.body).append(listHtml); + $(document.body).append(listHtml) - return item; - }, - removeList: function() { - $('#list-fuzzy-search').remove(); - }, - i1: { name: "Guybrush Threepwood" }, - i2: { name: "Manny Calavera" }, - i3: { name: "Bernard Bernoulli" }, - i4: { name: "LeChuck" }, - i5: { name: "Elaine Marley-Threepwood" }, - i6: { name: "Purple Tentacle" }, - i7: { name: "Adrian Ripburger" }, - i8: { name: "Bobbin Threadbare" }, - i9: { name: "Murray the Demonic Skull" }, - i10: { name: "Zak McKracken" } -}; + return item + }, + removeList: function () { + $('#list-fuzzy-search').remove() + }, + i1: { name: 'Guybrush Threepwood' }, + i2: { name: 'Manny Calavera' }, + i3: { name: 'Bernard Bernoulli' }, + i4: { name: 'LeChuck' }, + i5: { name: 'Elaine Marley-Threepwood' }, + i6: { name: 'Purple Tentacle' }, + i7: { name: 'Adrian Ripburger' }, + i8: { name: 'Bobbin Threadbare' }, + i9: { name: 'Murray the Demonic Skull' }, + i10: { name: 'Zak McKracken' }, +} fixtureFuzzysearch.all = [ - fixtureFuzzysearch.i1, - fixtureFuzzysearch.i2, - fixtureFuzzysearch.i3, - fixtureFuzzysearch.i4, - fixtureFuzzysearch.i5, - fixtureFuzzysearch.i6, - fixtureFuzzysearch.i7, - fixtureFuzzysearch.i8, - fixtureFuzzysearch.i9, - fixtureFuzzysearch.i10 -]; + fixtureFuzzysearch.i1, + fixtureFuzzysearch.i2, + fixtureFuzzysearch.i3, + fixtureFuzzysearch.i4, + fixtureFuzzysearch.i5, + fixtureFuzzysearch.i6, + fixtureFuzzysearch.i7, + fixtureFuzzysearch.i8, + fixtureFuzzysearch.i9, + fixtureFuzzysearch.i10, +] -module.exports = fixtureFuzzysearch; +module.exports = fixtureFuzzysearch diff --git a/__test__/fixtures-pagination.js b/__test__/fixtures-pagination.js index 46e6f418..dea045ea 100644 --- a/__test__/fixtures-pagination.js +++ b/__test__/fixtures-pagination.js @@ -1,115 +1,115 @@ -const $ = require('jquery'); +const $ = require('jquery') var fixturePagination = { - list: function(valueNames) { - var listHtml = $('
    '), - item = ""; + list: function (valueNames) { + var listHtml = $('
    '), + item = '' - item = "
  • "; - for (var i = 0; i < valueNames.length; i++) { - item += ''; - } - item += "
  • "; + item = '
  • ' + for (var i = 0; i < valueNames.length; i++) { + item += '' + } + item += '
  • ' - $(document.body).append(listHtml); + $(document.body).append(listHtml) - return item; - }, - removeList: function() { - $('#list-pagination').remove(); - }, - jonny: { - name: "Jonny Strömberg", - born: '1986' - }, - martina: { - name: "Martina Elm", - born: '1986' - }, - angelica: { - name: "Angelica Abraham", - born: '1986' - }, - sebastian: { - name: "Sebastian Höglund", - born: '1989' - }, - imma: { - name: "Imma Grafström", - born: '1953' - }, - hasse: { - name: "Hasse Strömberg", - born: '1955' - }, - fredrik: { - name: "Fredrik Martinsson", - born: '1987' - }, - jonas: { - name: "Jonas Arnklint", - born: '1987' - }, - egon: { - name: "Egon Östgren", - born: '1983' - }, - lars: { - name: "Lars Larsson", - born: '1992' - }, - bertil: { - name: "Bertil Cool", - born: '1943' - }, - ture: { - name: "Ture Tur", - born: '1965' - }, - anders: { - name: "Anders", - born: '1987' - }, - anna: { - name: "Anna", - born: '1987' - }, - matilda: { - name: "Matilda", - born: '1983' - }, - li: { - name: "Li", - born: '1992' - }, - asa: { - name: "Åsa", - born: '1943' - }, - gun: { - name: "Gun", - born: '1965' - } -}; + return item + }, + removeList: function () { + $('#list-pagination').remove() + }, + jonny: { + name: 'Jonny Strömberg', + born: '1986', + }, + martina: { + name: 'Martina Elm', + born: '1986', + }, + angelica: { + name: 'Angelica Abraham', + born: '1986', + }, + sebastian: { + name: 'Sebastian Höglund', + born: '1989', + }, + imma: { + name: 'Imma Grafström', + born: '1953', + }, + hasse: { + name: 'Hasse Strömberg', + born: '1955', + }, + fredrik: { + name: 'Fredrik Martinsson', + born: '1987', + }, + jonas: { + name: 'Jonas Arnklint', + born: '1987', + }, + egon: { + name: 'Egon Östgren', + born: '1983', + }, + lars: { + name: 'Lars Larsson', + born: '1992', + }, + bertil: { + name: 'Bertil Cool', + born: '1943', + }, + ture: { + name: 'Ture Tur', + born: '1965', + }, + anders: { + name: 'Anders', + born: '1987', + }, + anna: { + name: 'Anna', + born: '1987', + }, + matilda: { + name: 'Matilda', + born: '1983', + }, + li: { + name: 'Li', + born: '1992', + }, + asa: { + name: 'Åsa', + born: '1943', + }, + gun: { + name: 'Gun', + born: '1965', + }, +} fixturePagination.all = [ - fixturePagination.jonny, - fixturePagination.martina, - fixturePagination.angelica, - fixturePagination.sebastian, - fixturePagination.imma, - fixturePagination.hasse, - fixturePagination.fredrik, - fixturePagination.jonas, - fixturePagination.egon, - fixturePagination.lars, - fixturePagination.bertil, - fixturePagination.ture, - fixturePagination.anders, - fixturePagination.anna, - fixturePagination.matilda, - fixturePagination.li, - fixturePagination.asa, - fixturePagination.gun -]; + fixturePagination.jonny, + fixturePagination.martina, + fixturePagination.angelica, + fixturePagination.sebastian, + fixturePagination.imma, + fixturePagination.hasse, + fixturePagination.fredrik, + fixturePagination.jonas, + fixturePagination.egon, + fixturePagination.lars, + fixturePagination.bertil, + fixturePagination.ture, + fixturePagination.anders, + fixturePagination.anna, + fixturePagination.matilda, + fixturePagination.li, + fixturePagination.asa, + fixturePagination.gun, +] -module.exports = fixturePagination; +module.exports = fixturePagination diff --git a/__test__/fixtures.js b/__test__/fixtures.js index 716d4a22..083dae56 100644 --- a/__test__/fixtures.js +++ b/__test__/fixtures.js @@ -1,61 +1,58 @@ const $ = require('jquery'), - List = require('../src/index'); + List = require('../src/index') var fixture = { - list: function(valueNames, items) { + list: function (valueNames, items) { var listHtml = $('
    '), - item = ""; + item = '' - item = "
  • "; + item = '
  • ' for (var i = 0; i < valueNames.length; i++) { - item += ''; + item += '' } - item += "
  • "; + item += '' - $(document.body).append(listHtml); + $(document.body).append(listHtml) - items = items || []; + items = items || [] - return new List('list', { - valueNames: valueNames, - item: item - }, items); + return new List( + 'list', + { + valueNames: valueNames, + item: item, + }, + items + ) }, - removeList: function() { - $('#list').remove(); + removeList: function () { + $('#list').remove() }, jonny: { - name: "Jonny Strömberg", - born: '1986' + name: 'Jonny Strömberg', + born: '1986', }, martina: { - name: "Martina Elm", - born: '1986' + name: 'Martina Elm', + born: '1986', }, angelica: { - name: "Angelica Abraham", - born: '1986' + name: 'Angelica Abraham', + born: '1986', }, sebastian: { - name: "Sebastian Höglund", - born: '1989' + name: 'Sebastian Höglund', + born: '1989', }, imma: { - name: "Imma Grafström", - born: '1953' + name: 'Imma Grafström', + born: '1953', }, hasse: { - name: "Hasse Strömberg", - born: '1955' - } -}; -fixture.all = [ - fixture.jonny, - fixture.martina, - fixture.angelica, - fixture.sebastian, - fixture.imma, - fixture.hasse -]; + name: 'Hasse Strömberg', + born: '1955', + }, +} +fixture.all = [fixture.jonny, fixture.martina, fixture.angelica, fixture.sebastian, fixture.imma, fixture.hasse] -module.exports = fixture; +module.exports = fixture diff --git a/__test__/fuzzysearch.test.js b/__test__/fuzzysearch.test.js index 3cec165f..eea89f5d 100644 --- a/__test__/fuzzysearch.test.js +++ b/__test__/fuzzysearch.test.js @@ -1,78 +1,78 @@ const $ = require('jquery'), - fixtureFuzzysearch = require('./fixtures-fuzzysearch'), - List = require('../src/index'); + fixtureFuzzysearch = require('./fixtures-fuzzysearch'), + List = require('../src/index') function fireKeyup(el) { if (document.createEvent) { - var evObj; + var evObj if (window.KeyEvent) { - evObj = document.createEvent('KeyEvents'); - evObj.initKeyEvent('keyup', true, true, window, false, false, false, false, 13, 0); + evObj = document.createEvent('KeyEvents') + evObj.initKeyEvent('keyup', true, true, window, false, false, false, false, 13, 0) } else { - evObj = document.createEvent('UIEvents'); - evObj.initUIEvent('keyup', true, true, window, 1); + evObj = document.createEvent('UIEvents') + evObj.initUIEvent('keyup', true, true, window, 1) } - el.dispatchEvent(evObj); - } else if( document.createEventObject ) { - el.fireEvent('onkeyup'); + el.dispatchEvent(evObj) + } else if (document.createEventObject) { + el.fireEvent('onkeyup') } else { // IE 5.0, seriously? :) } } -describe('Fuzzy Search', function() { - var list, - itemHTML, - pagination; +describe('Fuzzy Search', function () { + var list, itemHTML, pagination - beforeEach(function() { + beforeEach(function () { itemHTML = fixtureFuzzysearch.list(['name', 'born']) - list = new List('list-fuzzy-search', { - valueNames: ['name', 'born'], - item: itemHTML - }, fixtureFuzzysearch.all); - }); + list = new List( + 'list-fuzzy-search', + { + valueNames: ['name', 'born'], + item: itemHTML, + }, + fixtureFuzzysearch.all + ) + }) - afterEach(function() { - fixtureFuzzysearch.removeList(); - }); + afterEach(function () { + fixtureFuzzysearch.removeList() + }) - it('should have default attribute', function() { - expect(list.fuzzySearch).toBeInstanceOf(Function); - }); + it('should have default attribute', function () { + expect(list.fuzzySearch).toBeInstanceOf(Function) + }) - it('should find result', function() { - list.fuzzySearch('guybrush'); - expect(list.matchingItems.length).toBe(1); - }); + it('should find result', function () { + list.fuzzySearch('guybrush') + expect(list.matchingItems.length).toBe(1) + }) - it('should find result', function() { - list.fuzzySearch('g thre'); - expect(list.matchingItems.length).toBe(1); - }); + it('should find result', function () { + list.fuzzySearch('g thre') + expect(list.matchingItems.length).toBe(1) + }) - it('should find result', function() { - list.fuzzySearch('thre'); - expect(list.matchingItems.length).toBe(4); - }); + it('should find result', function () { + list.fuzzySearch('thre') + expect(list.matchingItems.length).toBe(4) + }) - describe('Search field', function() { + describe('Search field', function () { + it('should trigger searchStart', function (done) { + list.on('searchStart', function () { + done() + }) + $('#list-fuzzy-search .fuzzy-search').val('angelica') + fireKeyup($('#list-fuzzy-search .fuzzy-search')[0]) + }) - it('should trigger searchStart', function(done) { - list.on('searchStart', function() { - done(); - }); - $('#list-fuzzy-search .fuzzy-search').val('angelica'); - fireKeyup($('#list-fuzzy-search .fuzzy-search')[0]); - }); - - it('should trigger searchComplete', function(done) { - list.on('searchComplete', function() { - done(); - }); - $('#list-fuzzy-search .fuzzy-search').val('angelica'); - fireKeyup($('#list-fuzzy-search .fuzzy-search')[0]); - }); - - }); -}); + it('should trigger searchComplete', function (done) { + list.on('searchComplete', function () { + done() + }) + $('#list-fuzzy-search .fuzzy-search').val('angelica') + fireKeyup($('#list-fuzzy-search .fuzzy-search')[0]) + }) + }) +}) diff --git a/__test__/item.test.js b/__test__/item.test.js index 665f1cbf..e1e6c464 100644 --- a/__test__/item.test.js +++ b/__test__/item.test.js @@ -1,149 +1,152 @@ const $ = require('jquery'), - fixture = require('./fixtures'); + fixture = require('./fixtures') -describe('Item', function() { +describe('Item', function () { + var list, item - var list, item; + beforeAll(function () { + list = fixture.list( + ['name', 'born', 'doin'], + [ + { + name: 'Jonny', + born: '1986', + doin: 'Living the dream', + }, + ] + ) + item = list.get('name', 'Jonny')[0] + }) - beforeAll(function() { - list = fixture.list(['name', 'born', 'doin'], [{ - name: "Jonny", - born: "1986", - doin: "Living the dream" - }]); - item = list.get('name', 'Jonny')[0]; - }); + beforeEach(function () { + list.search() + list.filter() + list.show(1, 200) + }) + afterAll(function () { + fixture.removeList() + }) - beforeEach(function() { - list.search(); - list.filter(); - list.show(1,200); - }); + describe('Defaults', function () { + it('should have all default attributes', function () { + expect(item.found).toBe(false) + expect(item.filtered).toBe(false) + }) - afterAll(function() { - fixture.removeList(); - }); + it('should have the right elements', function () { + expect(item.elm).toEqual($('#list li')[0]) + }) - describe('Defaults', function() { - it('should have all default attributes', function() { - expect(item.found).toBe(false); - expect(item.filtered).toBe(false); - }); + it('should have all default methods', function () { + expect(item.hide).toBeInstanceOf(Function) + expect(item.show).toBeInstanceOf(Function) + expect(item.values).toBeInstanceOf(Function) + expect(item.matching).toBeInstanceOf(Function) + expect(item.visible).toBeInstanceOf(Function) + }) + }) - it('should have the right elements', function() { - expect(item.elm).toEqual($('#list li')[0]); - }); - - it('should have all default methods', function() { - expect(item.hide).toBeInstanceOf(Function); - expect(item.show).toBeInstanceOf(Function); - expect(item.values).toBeInstanceOf(Function); - expect(item.matching).toBeInstanceOf(Function); - expect(item.visible).toBeInstanceOf(Function); - }); - }); - - describe('Values()', function() { - it('should have the right values', function() { + describe('Values()', function () { + it('should have the right values', function () { expect(item.values()).toEqual({ name: 'Jonny', born: '1986', - doin: 'Living the dream' - }); - }); - it('should be able to change one value', function() { - expect(item.values().name).toBe('Jonny'); - item.values({ name: 'Egon' }); - expect(item.values().name).toBe('Egon'); - }); - it('should be able to change many value', function() { + doin: 'Living the dream', + }) + }) + it('should be able to change one value', function () { + expect(item.values().name).toBe('Jonny') + item.values({ name: 'Egon' }) + expect(item.values().name).toBe('Egon') + }) + it('should be able to change many value', function () { expect(item.values()).toEqual({ name: 'Egon', born: '1986', - doin: 'Living the dream' - }); + doin: 'Living the dream', + }) item.values({ name: 'Sven', born: '1801', - doin: 'Is dead' - }); + doin: 'Is dead', + }) expect(item.values()).toEqual({ name: 'Sven', born: '1801', - doin: 'Is dead' - }); - }); - }); + doin: 'Is dead', + }) + }) + }) - describe('Hide, show, visible', function() { - it('should be hidden', function() { - expect($('#list li').length).toEqual(1); - item.hide(); - expect(item.visible()).toBe(false); - expect($('#list li').length).toEqual(0); - }); - it('should be visible', function() { - item.hide(); - expect($('#list li').length).toEqual(0); - item.show(); - expect(item.visible()).toBe(true); - expect($('#list li').length).toEqual(1); - }); - }); + describe('Hide, show, visible', function () { + it('should be hidden', function () { + expect($('#list li').length).toEqual(1) + item.hide() + expect(item.visible()).toBe(false) + expect($('#list li').length).toEqual(0) + }) + it('should be visible', function () { + item.hide() + expect($('#list li').length).toEqual(0) + item.show() + expect(item.visible()).toBe(true) + expect($('#list li').length).toEqual(1) + }) + }) - describe('Matching, found, filtered', function() { - describe('Searching', function() { - it('should not be visible, match, found or filtered', function() { - list.search('Fredrik'); - expect(item.matching()).toBe(false); - expect(item.found).toBe(false); - expect(item.filtered).toBe(false); - expect(item.visible()).toBe(false); - }); - it('should be visble, match and found but not filterd', function() { - var result = list.search('Sven'); - expect(item.matching()).toBe(true); - expect(item.found).toBe(true); - expect(item.filtered).toBe(false); - expect(item.visible()).toBe(true); - }); - it('reset: should be visible and matching but not found or filtered', function() { - list.search(); - expect(item.matching()).toBe(true); - expect(item.found).toBe(false); - expect(item.filtered).toBe(false); - expect(item.visible()).toBe(true); - }); - }); - describe('Filtering', function() { - it('should not be visble, match, found or filtered', function() { - list.filter(function(item) { - return (item.values().name == "Fredrik"); - }); - expect(item.matching()).toBe(false); - expect(item.found).toBe(false); - expect(item.filtered).toBe(false); - expect(item.visible()).toBe(false); - }); - it('should be visble, match and filtered but not found', function() { - list.filter(function(item) { - return (item.values().name == "Sven"); - }); - expect(item.matching()).toBe(true); - expect(item.found).toBe(false); - expect(item.filtered).toBe(true); - expect(item.visible()).toBe(true); - }); - it('reset: should be visble and match but not filtered or found', function() { - list.filter(); - expect(item.matching()).toBe(true); - expect(item.found).toBe(false); - expect(item.filtered).toBe(false); - expect(item.visible()).toBe(true); - }); - }); - }); + describe('Matching, found, filtered', function () { + describe('Searching', function () { + it('should not be visible, match, found or filtered', function () { + list.search('Fredrik') + expect(item.matching()).toBe(false) + expect(item.found).toBe(false) + expect(item.filtered).toBe(false) + expect(item.visible()).toBe(false) + }) + it('should be visble, match and found but not filterd', function () { + var result = list.search('Sven') + expect(item.matching()).toBe(true) + expect(item.found).toBe(true) + expect(item.filtered).toBe(false) + expect(item.visible()).toBe(true) + }) + it('reset: should be visible and matching but not found or filtered', function () { + list.search() + expect(item.matching()).toBe(true) + expect(item.found).toBe(false) + expect(item.filtered).toBe(false) + expect(item.visible()).toBe(true) + }) + }) + describe('Filtering', function () { + it('should not be visble, match, found or filtered', function () { + list.filter(function (item) { + return item.values().name == 'Fredrik' + }) + expect(item.matching()).toBe(false) + expect(item.found).toBe(false) + expect(item.filtered).toBe(false) + expect(item.visible()).toBe(false) + }) + it('should be visble, match and filtered but not found', function () { + list.filter(function (item) { + return item.values().name == 'Sven' + }) + expect(item.matching()).toBe(true) + expect(item.found).toBe(false) + expect(item.filtered).toBe(true) + expect(item.visible()).toBe(true) + }) + it('reset: should be visble and match but not filtered or found', function () { + list.filter() + expect(item.matching()).toBe(true) + expect(item.found).toBe(false) + expect(item.filtered).toBe(false) + expect(item.visible()).toBe(true) + }) + }) + }) - fixture.removeList(); -}); + fixture.removeList() +}) diff --git a/__test__/off.test.js b/__test__/off.test.js index c6109cf3..d0c2218c 100644 --- a/__test__/off.test.js +++ b/__test__/off.test.js @@ -1,41 +1,40 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Off', function() { +describe('Off', function () { + var list - var list; + beforeAll(function () { + list = fixture.list(['name', 'born'], fixture.all) + }) - beforeAll(function() { - list = fixture.list(['name', 'born'], fixture.all); - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); + describe('General', function () { + it('should be remove added handler', function (done) { + var updated = function (list) { + expect(list.handlers.updated.length).toEqual(1) + list.off('updated', updated) + expect(list.handlers.updated.length).toEqual(0) + done() + } + list.on('updated', updated) + list.search('jonny') + }) - describe('General', function() { - it('should be remove added handler', function(done) { - var updated = function(list) { - expect(list.handlers.updated.length).toEqual(1); - list.off('updated', updated); - expect(list.handlers.updated.length).toEqual(0); - done(); - }; - list.on('updated', updated); - list.search('jonny'); - }); - - it('should not remove unnamed handlers', function(done) { - var searchComplete = function(list) { - expect(list.handlers.searchComplete.length).toEqual(3); - list.off('searchComplete', function() {}); - list.off('searchComplete', searchComplete); - expect(list.handlers.searchComplete.length).toEqual(2); - done(); - }; - list.on('searchComplete', function() {}); - list.on('searchComplete', searchComplete); - list.on('searchComplete', function() {}); - list.search('jonny'); - }); - }); -}); + it('should not remove unnamed handlers', function (done) { + var searchComplete = function (list) { + expect(list.handlers.searchComplete.length).toEqual(3) + list.off('searchComplete', function () {}) + list.off('searchComplete', searchComplete) + expect(list.handlers.searchComplete.length).toEqual(2) + done() + } + list.on('searchComplete', function () {}) + list.on('searchComplete', searchComplete) + list.on('searchComplete', function () {}) + list.search('jonny') + }) + }) +}) diff --git a/__test__/on.test.js b/__test__/on.test.js index c576913e..4f887c63 100644 --- a/__test__/on.test.js +++ b/__test__/on.test.js @@ -1,125 +1,124 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('On', function() { +describe('On', function () { + var list - var list; + beforeEach(function () { + list = fixture.list(['name', 'born'], fixture.all) + }) - beforeEach(function() { - list = fixture.list(['name', 'born'], fixture.all); - }); + afterEach(function () { + fixture.removeList() + }) - afterEach(function() { - fixture.removeList(); - }); + describe('Updated', function () { + it('should be triggered after search', function (done) { + list.on('updated', function (list) { + done() + }) + list.search('jonny') + }) + it('should be triggered after sort', function (done) { + list.on('updated', function (list) { + done() + }) + list.sort('name') + }) + it('should be triggered after filter', function (done) { + list.on('updated', function (list) { + done() + }) + list.filter(function () { + return true + }) + }) + it('should be triggered after show', function (done) { + list.on('updated', function (list) { + done() + }) + list.show(1, 10) + }) - describe('Updated', function() { - it('should be triggered after search', function(done) { - list.on('updated', function(list) { - done(); - }); - list.search('jonny'); - }); - it('should be triggered after sort', function(done) { - list.on('updated', function(list) { - done(); - }); - list.sort('name'); - }); - it('should be triggered after filter', function(done) { - list.on('updated', function(list) { - done(); - }); - list.filter(function() { - return true; - }); - }); - it('should be triggered after show', function(done) { - list.on('updated', function(list) { - done(); - }); - list.show(1,10); - }); + it('should be triggered after add', function (done) { + list.on('updated', function (list) { + done() + }) + list.add({ name: 'Hej' }) + }) + it('should be triggered after remove', function (done) { + list.on('updated', function (list) { + done() + }) + list.remove('name', 'Jonny') + }) + }) - it('should be triggered after add', function(done) { - list.on('updated', function(list) { - done(); - }); - list.add({ name: 'Hej' }); - }); - it('should be triggered after remove', function(done) { - list.on('updated', function(list) { - done(); - }); - list.remove('name', 'Jonny'); - }); - }); - - describe('Multiple handlers', function() { - it('should be trigger both handlers', function(done) { + describe('Multiple handlers', function () { + it('should be trigger both handlers', function (done) { var done1 = false, done2 = false, - isDone = function() { + isDone = function () { if (done1 && done2) { - done(); + done() } - }; + } - list.on('updated', function(list) { - done1 = true; - isDone(); - }); - list.on('updated', function(list) { - done2 = true; - isDone(); - }); - list.search('jonny'); - }); - }); + list.on('updated', function (list) { + done1 = true + isDone() + }) + list.on('updated', function (list) { + done2 = true + isDone() + }) + list.search('jonny') + }) + }) - describe('Search', function() { - it('should be triggered before and after search', function(done) { - var done1 = false; - list.on('searchStart', function(list) { - done1 = true; - }); - list.on('searchComplete', function(list) { + describe('Search', function () { + it('should be triggered before and after search', function (done) { + var done1 = false + list.on('searchStart', function (list) { + done1 = true + }) + list.on('searchComplete', function (list) { if (done1) { - done(); + done() } - }); - list.search('jonny'); - }); - }); + }) + list.search('jonny') + }) + }) - describe('Sort', function() { - it('should be triggered before and after sort', function(done) { - var done1 = false; - list.on('sortStart', function(list) { - done1 = true; - }); - list.on('sortComplete', function(list) { + describe('Sort', function () { + it('should be triggered before and after sort', function (done) { + var done1 = false + list.on('sortStart', function (list) { + done1 = true + }) + list.on('sortComplete', function (list) { if (done1) { - done(); + done() } - }); - list.sort('name'); - }); - }); + }) + list.sort('name') + }) + }) - describe('Filter', function() { - it('should be triggered before and after filter', function(done) { - var done1 = false; - list.on('filterStart', function(list) { - done1 = true; - }); - list.on('filterComplete', function(list) { + describe('Filter', function () { + it('should be triggered before and after filter', function (done) { + var done1 = false + list.on('filterStart', function (list) { + done1 = true + }) + list.on('filterComplete', function (list) { if (done1) { - done(); + done() } - }); - list.filter(function() { - return true; - }); - }); - }); -}); + }) + list.filter(function () { + return true + }) + }) + }) +}) diff --git a/__test__/pagination.test.js b/__test__/pagination.test.js index 0c88831b..2e50b591 100644 --- a/__test__/pagination.test.js +++ b/__test__/pagination.test.js @@ -1,269 +1,271 @@ const $ = require('jquery'), - fixturePagination = require('./fixtures-pagination'), - List = require('../src/index'); + fixturePagination = require('./fixtures-pagination'), + List = require('../src/index') -describe('Pagination', function() { - describe('Default settings, innerWindow: 2, outerWindow: 0, left: 0, right: 0', function() { - var list, - itemHTML, - pagination; +describe('Pagination', function () { + describe('Default settings, innerWindow: 2, outerWindow: 0, left: 0, right: 0', function () { + var list, itemHTML, pagination - beforeAll(function() { + beforeAll(function () { itemHTML = fixturePagination.list(['name']) - list = new List('list-pagination', { - valueNames: ['name'], - item: itemHTML, - page: 2, - pagination: true - }, fixturePagination.all); + list = new List( + 'list-pagination', + { + valueNames: ['name'], + item: itemHTML, + page: 2, + pagination: true, + }, + fixturePagination.all + ) - pagination = $('.pagination'); - }); + pagination = $('.pagination') + }) - afterAll(function() { - fixturePagination.removeList(); - }); + afterAll(function () { + fixturePagination.removeList() + }) - it('should have default settings', function() { - expect(pagination.find('a').length).toEqual(4); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("3"); - expect(pagination.find('a').get(3).innerHTML).toEqual("..."); - expect(pagination.find('a').get(4)).toEqual(undefined); - }); + it('should have default settings', function () { + expect(pagination.find('a').length).toEqual(4) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('3') + expect(pagination.find('a').get(3).innerHTML).toEqual('...') + expect(pagination.find('a').get(4)).toEqual(undefined) + }) - it('should show same pages for show(7,2) and show(8,2)', function() { - list.show(7, 2); - expect(pagination.find('a').length).toEqual(7); - expect(pagination.find('a').get(0).innerHTML).toEqual("..."); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("3"); - expect(pagination.find('a').get(3).innerHTML).toEqual("4"); - expect(pagination.find('a').get(4).innerHTML).toEqual("5"); - expect(pagination.find('a').get(5).innerHTML).toEqual("6"); - expect(pagination.find('a').get(6).innerHTML).toEqual("..."); - expect(pagination.find('a').get(7)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should show same pages for show(7,2) and show(8,2)', function () { + list.show(7, 2) + expect(pagination.find('a').length).toEqual(7) + expect(pagination.find('a').get(0).innerHTML).toEqual('...') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('3') + expect(pagination.find('a').get(3).innerHTML).toEqual('4') + expect(pagination.find('a').get(4).innerHTML).toEqual('5') + expect(pagination.find('a').get(5).innerHTML).toEqual('6') + expect(pagination.find('a').get(6).innerHTML).toEqual('...') + expect(pagination.find('a').get(7)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - it('should show same pages for show(7,2) and show(8,2)', function() { - list.show(8, 2); - expect(pagination.find('a').length).toEqual(7); - expect(pagination.find('a').get(0).innerHTML).toEqual("..."); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("3"); - expect(pagination.find('a').get(3).innerHTML).toEqual("4"); - expect(pagination.find('a').get(4).innerHTML).toEqual("5"); - expect(pagination.find('a').get(5).innerHTML).toEqual("6"); - expect(pagination.find('a').get(6).innerHTML).toEqual("..."); - expect(pagination.find('a').get(7)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should show same pages for show(7,2) and show(8,2)', function () { + list.show(8, 2) + expect(pagination.find('a').length).toEqual(7) + expect(pagination.find('a').get(0).innerHTML).toEqual('...') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('3') + expect(pagination.find('a').get(3).innerHTML).toEqual('4') + expect(pagination.find('a').get(4).innerHTML).toEqual('5') + expect(pagination.find('a').get(5).innerHTML).toEqual('6') + expect(pagination.find('a').get(6).innerHTML).toEqual('...') + expect(pagination.find('a').get(7)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - it('should test show(14,2)', function() { - list.show(14, 2); - expect(pagination.find('a').length).toEqual(6); - expect(pagination.find('a').get(0).innerHTML).toEqual("..."); - expect(pagination.find('a').get(1).innerHTML).toEqual("5"); - expect(pagination.find('a').get(2).innerHTML).toEqual("6"); - expect(pagination.find('a').get(3).innerHTML).toEqual("7"); - expect(pagination.find('a').get(4).innerHTML).toEqual("8"); - expect(pagination.find('a').get(5).innerHTML).toEqual("9"); - expect(pagination.find('a').get(6)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should test show(14,2)', function () { + list.show(14, 2) + expect(pagination.find('a').length).toEqual(6) + expect(pagination.find('a').get(0).innerHTML).toEqual('...') + expect(pagination.find('a').get(1).innerHTML).toEqual('5') + expect(pagination.find('a').get(2).innerHTML).toEqual('6') + expect(pagination.find('a').get(3).innerHTML).toEqual('7') + expect(pagination.find('a').get(4).innerHTML).toEqual('8') + expect(pagination.find('a').get(5).innerHTML).toEqual('9') + expect(pagination.find('a').get(6)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - it('should show last page with show(17,2)', function() { - list.show(17, 2); - expect(pagination.find('a').length).toEqual(4); - expect(pagination.find('a').get(0).innerHTML).toEqual("..."); - expect(pagination.find('a').get(1).innerHTML).toEqual("7"); - expect(pagination.find('a').get(2).innerHTML).toEqual("8"); - expect(pagination.find('a').get(3).innerHTML).toEqual("9"); - expect(pagination.find('a').get(4)).toEqual(undefined); - expect($(pagination.find('li').get(1)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - }); + it('should show last page with show(17,2)', function () { + list.show(17, 2) + expect(pagination.find('a').length).toEqual(4) + expect(pagination.find('a').get(0).innerHTML).toEqual('...') + expect(pagination.find('a').get(1).innerHTML).toEqual('7') + expect(pagination.find('a').get(2).innerHTML).toEqual('8') + expect(pagination.find('a').get(3).innerHTML).toEqual('9') + expect(pagination.find('a').get(4)).toEqual(undefined) + expect($(pagination.find('li').get(1)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + }) - it('should handle page = 0', function() { - expect(list.listContainer.style.display).toBe(''); - list.show(0, 0); - expect(list.listContainer.style.display).toBe('none'); - list.show(1, 1); - expect(list.listContainer.style.display).toBe('block'); - }); - }); + it('should handle page = 0', function () { + expect(list.listContainer.style.display).toBe('') + list.show(0, 0) + expect(list.listContainer.style.display).toBe('none') + list.show(1, 1) + expect(list.listContainer.style.display).toBe('block') + }) + }) + describe('Custom settings, innerWindow: 1, outerWindow: 1, left: 0, right: 0', function () { + var list, itemHTML, pagination - describe('Custom settings, innerWindow: 1, outerWindow: 1, left: 0, right: 0', function() { - var list, - itemHTML, - pagination; - - beforeAll(function() { + beforeAll(function () { itemHTML = fixturePagination.list(['name']) - list = new List('list-pagination', { - valueNames: ['name'], - item: itemHTML, - page: 2, - pagination: { - innerWindow: 1, - outerWindow: 1 - } - }, fixturePagination.all); - - pagination = $('.pagination'); - }); + list = new List( + 'list-pagination', + { + valueNames: ['name'], + item: itemHTML, + page: 2, + pagination: { + innerWindow: 1, + outerWindow: 1, + }, + }, + fixturePagination.all + ) - afterAll(function() { - fixturePagination.removeList(); - }); + pagination = $('.pagination') + }) - it('should have default settings', function() { - expect(pagination.find('a').length).toEqual(4); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("..."); - expect(pagination.find('a').get(3).innerHTML).toEqual("9"); - expect(pagination.find('a').get(4)).toEqual(undefined); - }); + afterAll(function () { + fixturePagination.removeList() + }) - it('should test show(7,2)', function() { - list.show(7, 2); - expect(pagination.find('a').length).toEqual(7); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("..."); - expect(pagination.find('a').get(2).innerHTML).toEqual("3"); - expect(pagination.find('a').get(3).innerHTML).toEqual("4"); - expect(pagination.find('a').get(4).innerHTML).toEqual("5"); - expect(pagination.find('a').get(5).innerHTML).toEqual("..."); - expect(pagination.find('a').get(6).innerHTML).toEqual("9"); - expect(pagination.find('a').get(7)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should have default settings', function () { + expect(pagination.find('a').length).toEqual(4) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('...') + expect(pagination.find('a').get(3).innerHTML).toEqual('9') + expect(pagination.find('a').get(4)).toEqual(undefined) + }) - it('should test show(14,2)', function() { - list.show(14, 2); - expect(pagination.find('a').length).toEqual(6); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("..."); - expect(pagination.find('a').get(2).innerHTML).toEqual("6"); - expect(pagination.find('a').get(3).innerHTML).toEqual("7"); - expect(pagination.find('a').get(4).innerHTML).toEqual("8"); - expect(pagination.find('a').get(5).innerHTML).toEqual("9"); - expect(pagination.find('a').get(6)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should test show(7,2)', function () { + list.show(7, 2) + expect(pagination.find('a').length).toEqual(7) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('...') + expect(pagination.find('a').get(2).innerHTML).toEqual('3') + expect(pagination.find('a').get(3).innerHTML).toEqual('4') + expect(pagination.find('a').get(4).innerHTML).toEqual('5') + expect(pagination.find('a').get(5).innerHTML).toEqual('...') + expect(pagination.find('a').get(6).innerHTML).toEqual('9') + expect(pagination.find('a').get(7)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - it('should show last page with show(17,2)', function() { - list.show(17, 2); - expect(pagination.find('a').length).toEqual(4); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("..."); - expect(pagination.find('a').get(2).innerHTML).toEqual("8"); - expect(pagination.find('a').get(3).innerHTML).toEqual("9"); - expect(pagination.find('a').get(4)).toEqual(undefined); - expect($(pagination.find('li').get(1)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - }); + it('should test show(14,2)', function () { + list.show(14, 2) + expect(pagination.find('a').length).toEqual(6) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('...') + expect(pagination.find('a').get(2).innerHTML).toEqual('6') + expect(pagination.find('a').get(3).innerHTML).toEqual('7') + expect(pagination.find('a').get(4).innerHTML).toEqual('8') + expect(pagination.find('a').get(5).innerHTML).toEqual('9') + expect(pagination.find('a').get(6)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - }); + it('should show last page with show(17,2)', function () { + list.show(17, 2) + expect(pagination.find('a').length).toEqual(4) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('...') + expect(pagination.find('a').get(2).innerHTML).toEqual('8') + expect(pagination.find('a').get(3).innerHTML).toEqual('9') + expect(pagination.find('a').get(4)).toEqual(undefined) + expect($(pagination.find('li').get(1)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + }) + }) + describe('Custom settings, innerWindow: 1, outerWindow: 1, left: 2, right: 1', function () { + var list, itemHTML, pagination - describe('Custom settings, innerWindow: 1, outerWindow: 1, left: 2, right: 1', function() { - var list, - itemHTML, - pagination; - - beforeAll(function() { + beforeAll(function () { itemHTML = fixturePagination.list(['name']) - list = new List('list-pagination', { - valueNames: ['name'], - item: itemHTML, - page: 2, - pagination: { - innerWindow: 1, - outerWindow: 1, - left: 2, - right: 1 - } - }, fixturePagination.all); - - pagination = $('.pagination'); - }); + list = new List( + 'list-pagination', + { + valueNames: ['name'], + item: itemHTML, + page: 2, + pagination: { + innerWindow: 1, + outerWindow: 1, + left: 2, + right: 1, + }, + }, + fixturePagination.all + ) - afterAll(function() { - fixturePagination.removeList(); - }); + pagination = $('.pagination') + }) - it('should have default settings', function() { - expect(pagination.find('a').length).toEqual(4); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("..."); - expect(pagination.find('a').get(3).innerHTML).toEqual("9"); - expect(pagination.find('a').get(4)).toEqual(undefined); - }); + afterAll(function () { + fixturePagination.removeList() + }) - it('should test show(7,2)', function() { - list.show(7, 2); - expect(pagination.find('a').length).toEqual(7); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("3"); - expect(pagination.find('a').get(3).innerHTML).toEqual("4"); - expect(pagination.find('a').get(4).innerHTML).toEqual("5"); - expect(pagination.find('a').get(5).innerHTML).toEqual("..."); - expect(pagination.find('a').get(6).innerHTML).toEqual("9"); - expect(pagination.find('a').get(7)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false); - }); + it('should have default settings', function () { + expect(pagination.find('a').length).toEqual(4) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('...') + expect(pagination.find('a').get(3).innerHTML).toEqual('9') + expect(pagination.find('a').get(4)).toEqual(undefined) + }) - it('should test show(12,2)', function() { - list.show(12, 2); - expect(pagination.find('a').length).toEqual(8); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("..."); - expect(pagination.find('a').get(3).innerHTML).toEqual("5"); - expect(pagination.find('a').get(4).innerHTML).toEqual("6"); - expect(pagination.find('a').get(5).innerHTML).toEqual("7"); - expect(pagination.find('a').get(6).innerHTML).toEqual("..."); - expect(pagination.find('a').get(7).innerHTML).toEqual("9"); - expect(pagination.find('a').get(8)).toEqual(undefined); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(true); - expect($(pagination.find('li').get(5)).hasClass('active')).toEqual(false); - }); + it('should test show(7,2)', function () { + list.show(7, 2) + expect(pagination.find('a').length).toEqual(7) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('3') + expect(pagination.find('a').get(3).innerHTML).toEqual('4') + expect(pagination.find('a').get(4).innerHTML).toEqual('5') + expect(pagination.find('a').get(5).innerHTML).toEqual('...') + expect(pagination.find('a').get(6).innerHTML).toEqual('9') + expect(pagination.find('a').get(7)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(false) + }) - it('should show last page with show(17,2)', function() { - list.show(17, 2); - expect(pagination.find('a').length).toEqual(5); - expect(pagination.find('a').get(0).innerHTML).toEqual("1"); - expect(pagination.find('a').get(1).innerHTML).toEqual("2"); - expect(pagination.find('a').get(2).innerHTML).toEqual("..."); - expect(pagination.find('a').get(3).innerHTML).toEqual("8"); - expect(pagination.find('a').get(4).innerHTML).toEqual("9"); - expect(pagination.find('a').get(5)).toEqual(undefined); - expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(false); - expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(true); - }); + it('should test show(12,2)', function () { + list.show(12, 2) + expect(pagination.find('a').length).toEqual(8) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('...') + expect(pagination.find('a').get(3).innerHTML).toEqual('5') + expect(pagination.find('a').get(4).innerHTML).toEqual('6') + expect(pagination.find('a').get(5).innerHTML).toEqual('7') + expect(pagination.find('a').get(6).innerHTML).toEqual('...') + expect(pagination.find('a').get(7).innerHTML).toEqual('9') + expect(pagination.find('a').get(8)).toEqual(undefined) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(true) + expect($(pagination.find('li').get(5)).hasClass('active')).toEqual(false) + }) - }); -}); + it('should show last page with show(17,2)', function () { + list.show(17, 2) + expect(pagination.find('a').length).toEqual(5) + expect(pagination.find('a').get(0).innerHTML).toEqual('1') + expect(pagination.find('a').get(1).innerHTML).toEqual('2') + expect(pagination.find('a').get(2).innerHTML).toEqual('...') + expect(pagination.find('a').get(3).innerHTML).toEqual('8') + expect(pagination.find('a').get(4).innerHTML).toEqual('9') + expect(pagination.find('a').get(5)).toEqual(undefined) + expect($(pagination.find('li').get(2)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(3)).hasClass('active')).toEqual(false) + expect($(pagination.find('li').get(4)).hasClass('active')).toEqual(true) + }) + }) +}) diff --git a/__test__/parse.test.js b/__test__/parse.test.js index 60485542..4055050f 100644 --- a/__test__/parse.test.js +++ b/__test__/parse.test.js @@ -1,60 +1,64 @@ const $ = require('jquery'), - List = require('../src/index'); + List = require('../src/index') -describe('Parse', function() { - - describe('Parse class', function() { - var list; - beforeEach(function() { - $('body').append($('
    \ +describe('Parse', function () { + describe('Parse class', function () { + var list + beforeEach(function () { + $('body').append( + $( + '
    \
    \
    Jonny1986
    \
    Jocke1985
    \
    \ -
    ')); +
    ' + ) + ) list = new List('parse-list', { - valueNames: ['name', 'born'] - }); - }); - - afterEach(function() { - $('#parse-list').remove(); - }); + valueNames: ['name', 'born'], + }) + }) - it('should have two items', function() { - expect(list.items.length).toEqual(2); - expect(list.items[0].values().name).toEqual("Jonny"); - expect(list.items[1].values().name).toEqual("Jocke"); - }); - it('should add item to parsed list', function() { - list.add({ name: "Sven", born: 1950 }); - expect(list.items.length).toEqual(3); - expect(list.items[0].values().name).toEqual("Jonny"); - expect(list.items[1].values().name).toEqual("Jocke"); - expect(list.items[2].values().name).toEqual("Sven"); - expect(list.items[0].values().born).toEqual("1986"); - expect(list.items[2].values().born).toEqual(1950); - var el = $($('#parse-list').find('.list div')[2]); - expect(el.find('span').length).toEqual(2); - expect(el.find('span.name').text()).toEqual('Sven'); - expect(el.find('span.born').text()).toEqual('1950'); - }); - it('should parsed value always be string while added could be number', function() { - list.add({ name: "Sven", born: 1950 }); - expect(list.items[0].values().born).toEqual("1986"); - expect(list.items[0].values().born).not.toEqual(1986); - expect(list.items[2].values().born).not.toEqual("1950"); - expect(list.items[2].values().born).toEqual(1950); - }); - }); + afterEach(function () { + $('#parse-list').remove() + }) - describe('Parse data', function() { + it('should have two items', function () { + expect(list.items.length).toEqual(2) + expect(list.items[0].values().name).toEqual('Jonny') + expect(list.items[1].values().name).toEqual('Jocke') + }) + it('should add item to parsed list', function () { + list.add({ name: 'Sven', born: 1950 }) + expect(list.items.length).toEqual(3) + expect(list.items[0].values().name).toEqual('Jonny') + expect(list.items[1].values().name).toEqual('Jocke') + expect(list.items[2].values().name).toEqual('Sven') + expect(list.items[0].values().born).toEqual('1986') + expect(list.items[2].values().born).toEqual(1950) + var el = $($('#parse-list').find('.list div')[2]) + expect(el.find('span').length).toEqual(2) + expect(el.find('span.name').text()).toEqual('Sven') + expect(el.find('span.born').text()).toEqual('1950') + }) + it('should parsed value always be string while added could be number', function () { + list.add({ name: 'Sven', born: 1950 }) + expect(list.items[0].values().born).toEqual('1986') + expect(list.items[0].values().born).not.toEqual(1986) + expect(list.items[2].values().born).not.toEqual('1950') + expect(list.items[2].values().born).toEqual(1950) + }) + }) - var list; + describe('Parse data', function () { + var list - beforeEach(function() { - $('body').append($('
    \ + beforeEach(function () { + $('body').append( + $( + '
    \
    \
    \ Jonny\ @@ -69,54 +73,64 @@ describe('Parse', function() { \
    \
    \ -
    ')); +
    ' + ) + ) list = new List('parse-list', { valueNames: [ 'name', 'born', - { data: [ 'id' ] }, - { attr: 'src', name: 'image'}, - { attr: 'href', name: 'link'}, - { attr: 'value', name: 'foo'}, - { attr: 'data-timestamp', name: 'timestamp' } - ] - }); - }); + { data: ['id'] }, + { attr: 'src', name: 'image' }, + { attr: 'href', name: 'link' }, + { attr: 'value', name: 'foo' }, + { attr: 'data-timestamp', name: 'timestamp' }, + ], + }) + }) - afterEach(function() { - $('#parse-list').remove(); - }); + afterEach(function () { + $('#parse-list').remove() + }) - it('should get values from class, data, src, value and child els data-attribute', function() { - expect(list.items.length).toEqual(2); - var jonny = list.items[0].values(); - expect(jonny.name).toEqual("Jonny"); - expect(jonny.born).toEqual("1986"); - expect(jonny.id).toEqual("1"); - expect(jonny.image).toEqual("usage/boba.jpeg"); - expect(jonny.timestamp).toEqual("54321"); - expect(jonny.foo).toEqual("Bar"); - }); - it('should add item to list with class, data and src', function() { - list.add({ name: "Sven", born: 1950, id: 4, image: 'usage/rey.jpeg', link: 'localhost', timestamp: '1337', foo: 'hej' }); - expect(list.items.length).toEqual(3); - var sven = list.items[2].values(); - expect(sven.name).toEqual("Sven"); - expect(sven.born).toEqual(1950); - expect(sven.id).toEqual(4); - expect(sven.image).toEqual("usage/rey.jpeg"); - expect(sven.link).toEqual("localhost"); - expect(sven.timestamp).toEqual("1337"); - expect(sven.foo).toEqual("hej"); - var el = $($('#parse-list').find('.list div')[2]); - expect(el.data('id')).toEqual(4); - expect(el.find('.name').text()).toEqual('Sven'); - expect(el.find('.born').text()).toEqual('1950'); - expect(el.find('.image').attr('src')).toEqual('usage/rey.jpeg'); - expect(el.find('.link').attr('href')).toEqual('localhost'); - expect(el.find('.timestamp').data('timestamp')).toEqual(1337); - expect(el.find('.foo').val()).toEqual('hej'); - }); - }); -}); + it('should get values from class, data, src, value and child els data-attribute', function () { + expect(list.items.length).toEqual(2) + var jonny = list.items[0].values() + expect(jonny.name).toEqual('Jonny') + expect(jonny.born).toEqual('1986') + expect(jonny.id).toEqual('1') + expect(jonny.image).toEqual('usage/boba.jpeg') + expect(jonny.timestamp).toEqual('54321') + expect(jonny.foo).toEqual('Bar') + }) + it('should add item to list with class, data and src', function () { + list.add({ + name: 'Sven', + born: 1950, + id: 4, + image: 'usage/rey.jpeg', + link: 'localhost', + timestamp: '1337', + foo: 'hej', + }) + expect(list.items.length).toEqual(3) + var sven = list.items[2].values() + expect(sven.name).toEqual('Sven') + expect(sven.born).toEqual(1950) + expect(sven.id).toEqual(4) + expect(sven.image).toEqual('usage/rey.jpeg') + expect(sven.link).toEqual('localhost') + expect(sven.timestamp).toEqual('1337') + expect(sven.foo).toEqual('hej') + var el = $($('#parse-list').find('.list div')[2]) + expect(el.data('id')).toEqual(4) + expect(el.find('.name').text()).toEqual('Sven') + expect(el.find('.born').text()).toEqual('1950') + expect(el.find('.image').attr('src')).toEqual('usage/rey.jpeg') + expect(el.find('.link').attr('href')).toEqual('localhost') + expect(el.find('.timestamp').data('timestamp')).toEqual(1337) + expect(el.find('.foo').val()).toEqual('hej') + }) + }) +}) diff --git a/__test__/re-index.test.js b/__test__/re-index.test.js index 5727083f..6bed7c97 100644 --- a/__test__/re-index.test.js +++ b/__test__/re-index.test.js @@ -1,37 +1,36 @@ const $ = require('jquery'), - fixture = require('./fixtures'); + fixture = require('./fixtures') -describe('ReIndex', function() { +describe('ReIndex', function () { + var list, jonny, martina, angelica, sebastian, imma, hasse - var list, jonny, martina, angelica, sebastian, imma, hasse; + beforeAll(function () { + list = fixture.list(['name', 'born'], fixture.all) + }) - beforeAll(function() { - list = fixture.list(['name', 'born'], fixture.all); - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); - - afterEach(function() { - list.show(1, 200); - }); - it('should return everyone born after 1988', function() { + afterEach(function () { + list.show(1, 200) + }) + it('should return everyone born after 1988', function () { expect(list.toJSON()).toEqual([ - { name: "Jonny Strömberg", born: '1986' }, - { name: "Martina Elm", born: '1986' }, - { name: "Angelica Abraham", born: '1986' }, - { name: "Sebastian Höglund", born: '1989' }, - { name: "Imma Grafström", born: '1953' }, - { name: "Hasse Strömberg", born: '1955' } - ]); - var newHtml = '
  • Sven2013'; - newHtml = newHtml + '
  • Anna3043'; - $(list.list).html(newHtml); - list.reIndex(); + { name: 'Jonny Strömberg', born: '1986' }, + { name: 'Martina Elm', born: '1986' }, + { name: 'Angelica Abraham', born: '1986' }, + { name: 'Sebastian Höglund', born: '1989' }, + { name: 'Imma Grafström', born: '1953' }, + { name: 'Hasse Strömberg', born: '1955' }, + ]) + var newHtml = '
  • Sven2013' + newHtml = newHtml + '
  • Anna3043' + $(list.list).html(newHtml) + list.reIndex() expect(list.toJSON()).toEqual([ - { name: "Sven", born: '2013' }, - { name: "Anna", born: '3043' } - ]); - }); -}); + { name: 'Sven', born: '2013' }, + { name: 'Anna', born: '3043' }, + ]) + }) +}) diff --git a/__test__/search-filter.test.js b/__test__/search-filter.test.js index 3dc8f565..73e7264f 100644 --- a/__test__/search-filter.test.js +++ b/__test__/search-filter.test.js @@ -1,68 +1,67 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Search and filter', function() { +describe('Search and filter', function () { + var list, jonny, martina, angelica, sebastian, imma, hasse - var list, jonny, martina, angelica, sebastian, imma, hasse; + beforeAll(function () { + list = fixture.list(['name', 'born'], fixture.all) - beforeAll(function() { - list = fixture.list(['name', 'born'], fixture.all); + jonny = list.get('name', 'Jonny Strömberg')[0] + martina = list.get('name', 'Martina Elm')[0] + angelica = list.get('name', 'Angelica Abraham')[0] + sebastian = list.get('name', 'Sebastian Höglund')[0] + imma = list.get('name', 'Imma Grafström')[0] + hasse = list.get('name', 'Hasse Strömberg')[0] + }) - jonny = list.get('name', 'Jonny Strömberg')[0]; - martina = list.get('name', 'Martina Elm')[0]; - angelica = list.get('name', 'Angelica Abraham')[0]; - sebastian = list.get('name', 'Sebastian Höglund')[0]; - imma = list.get('name', 'Imma Grafström')[0]; - hasse = list.get('name', 'Hasse Strömberg')[0]; - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); + afterEach(function () { + list.search() + list.filter() + }) - afterEach(function() { - list.search(); - list.filter(); - }); - - describe('Search with filter', function() { - it('should find everyone born 1986', function() { - list.filter(function(item) { - return (item.values().born == '1986'); - }); - expect(list.matchingItems.length).toEqual(3); - expect(jonny.matching()).toBe(true); - expect(martina.matching()).toBe(true); - expect(angelica.matching()).toBe(true); - expect(sebastian.matching()).toBe(false); - expect(imma.matching()).toBe(false); - expect(hasse.matching()).toBe(false); - }); - it('should find everyone born 1986 and containes "ö"', function() { - list.filter(function(item) { - return (item.values().born == '1986'); - }); - list.search('ö'); - expect(list.matchingItems.length).toEqual(1); - expect(jonny.matching()).toBe(true); - expect(martina.matching()).toBe(false); - expect(angelica.matching()).toBe(false); - expect(sebastian.matching()).toBe(false); - expect(imma.matching()).toBe(false); - expect(hasse.matching()).toBe(false); - }); - it('should find everyone with a "ö"', function() { - list.filter(function(item) { - return (item.values().born == '1986'); - }); - list.search('ö'); - list.filter(); - expect(list.matchingItems.length).toEqual(4); - expect(jonny.matching()).toBe(true); - expect(martina.matching()).toBe(false); - expect(angelica.matching()).toBe(false); - expect(sebastian.matching()).toBe(true); - expect(imma.matching()).toBe(true); - expect(hasse.matching()).toBe(true); - }); - }); -}); + describe('Search with filter', function () { + it('should find everyone born 1986', function () { + list.filter(function (item) { + return item.values().born == '1986' + }) + expect(list.matchingItems.length).toEqual(3) + expect(jonny.matching()).toBe(true) + expect(martina.matching()).toBe(true) + expect(angelica.matching()).toBe(true) + expect(sebastian.matching()).toBe(false) + expect(imma.matching()).toBe(false) + expect(hasse.matching()).toBe(false) + }) + it('should find everyone born 1986 and containes "ö"', function () { + list.filter(function (item) { + return item.values().born == '1986' + }) + list.search('ö') + expect(list.matchingItems.length).toEqual(1) + expect(jonny.matching()).toBe(true) + expect(martina.matching()).toBe(false) + expect(angelica.matching()).toBe(false) + expect(sebastian.matching()).toBe(false) + expect(imma.matching()).toBe(false) + expect(hasse.matching()).toBe(false) + }) + it('should find everyone with a "ö"', function () { + list.filter(function (item) { + return item.values().born == '1986' + }) + list.search('ö') + list.filter() + expect(list.matchingItems.length).toEqual(4) + expect(jonny.matching()).toBe(true) + expect(martina.matching()).toBe(false) + expect(angelica.matching()).toBe(false) + expect(sebastian.matching()).toBe(true) + expect(imma.matching()).toBe(true) + expect(hasse.matching()).toBe(true) + }) + }) +}) diff --git a/__test__/search.test.js b/__test__/search.test.js index 6139b49a..b819be16 100644 --- a/__test__/search.test.js +++ b/__test__/search.test.js @@ -1,162 +1,159 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Search', function() { +describe('Search', function () { + var list, jonny, martina, angelica, sebastian, imma, hasse - var list, jonny, martina, angelica, sebastian, imma, hasse; + beforeEach(function () { + list = fixture.list(['name', 'born'], fixture.all) - beforeEach(function() { - list = fixture.list(['name', 'born'], fixture.all); + jonny = list.get('name', 'Jonny Strömberg')[0] + martina = list.get('name', 'Martina Elm')[0] + angelica = list.get('name', 'Angelica Abraham')[0] + sebastian = list.get('name', 'Sebastian Höglund')[0] + imma = list.get('name', 'Imma Grafström')[0] + hasse = list.get('name', 'Hasse Strömberg')[0] + }) - jonny = list.get('name', 'Jonny Strömberg')[0]; - martina = list.get('name', 'Martina Elm')[0]; - angelica = list.get('name', 'Angelica Abraham')[0]; - sebastian = list.get('name', 'Sebastian Höglund')[0]; - imma = list.get('name', 'Imma Grafström')[0]; - hasse = list.get('name', 'Hasse Strömberg')[0]; - }); + afterEach(function () { + fixture.removeList() + }) - afterEach(function() { - fixture.removeList(); - }); + describe('Case-sensitive', function () { + it('should not be case-sensitive', function () { + var result = list.search('jonny') + expect(result.length).toEqual(1) + expect(result[0]).toEqual(jonny) + }) + }) - describe('Case-sensitive', function() { - it('should not be case-sensitive', function() { - var result = list.search('jonny'); - expect(result.length).toEqual(1); - expect(result[0]).toEqual(jonny); - }); - }); + describe('Number of results', function () { + it('should find jonny, martina, angelice', function () { + var result = list.search('1986') + expect(result.length).toEqual(3) // 3!! + expect(jonny.matching()).toBe(true) + expect(martina.matching()).toBe(true) + expect(angelica.matching()).toBe(true) + expect(sebastian.matching()).toBe(false) + expect(imma.matching()).toBe(false) + expect(hasse.matching()).toBe(false) + }) + it('should find all with utf-8 char ö', function () { + var result = list.search('ö') + expect(result.length).toEqual(4) // 4!! + expect(jonny.matching()).toBe(true) + expect(martina.matching()).toBe(false) + expect(angelica.matching()).toBe(false) + expect(sebastian.matching()).toBe(true) + expect(imma.matching()).toBe(true) + expect(hasse.matching()).toBe(true) + }) + it('should not break with weird searches', function () { + expect(function () { + list.search(undefined) + }).not.toThrow() + expect(function () { + list.search(null) + }).not.toThrow() + expect(function () { + list.search(0) + }).not.toThrow() + expect(function () { + list.search(function () {}) + }).not.toThrow() + expect(function () { + list.search({ foo: 'bar' }) + }).not.toThrow() + }) + it('should not break with weird values', function () { + jonny.values({ name: undefined }) + martina.values({ name: null }) + angelica.values({ name: 0 }) + sebastian.values({ name: function () {} }) + imma.values({ name: { foo: 'bar' } }) - describe('Number of results', function() { - it('should find jonny, martina, angelice', function() { - var result = list.search('1986'); - expect(result.length).toEqual(3); // 3!! - expect(jonny.matching()).toBe(true); - expect(martina.matching()).toBe(true); - expect(angelica.matching()).toBe(true); - expect(sebastian.matching()).toBe(false); - expect(imma.matching()).toBe(false); - expect(hasse.matching()).toBe(false); - }); - it('should find all with utf-8 char ö', function() { - var result = list.search('ö'); - expect(result.length).toEqual(4); // 4!! - expect(jonny.matching()).toBe(true); - expect(martina.matching()).toBe(false); - expect(angelica.matching()).toBe(false); - expect(sebastian.matching()).toBe(true); - expect(imma.matching()).toBe(true); - expect(hasse.matching()).toBe(true); - }); - it('should not break with weird searches', function() { - expect(function() { - list.search(undefined); - }).not.toThrow(); - expect(function() { - list.search(null); - }).not.toThrow(); - expect(function() { - list.search(0); - }).not.toThrow(); - expect(function() { - list.search(function() {}); - }).not.toThrow(); - expect(function() { - list.search({ foo: "bar" }); - }).not.toThrow(); - }); - it('should not break with weird values', function() { - jonny.values({ name: undefined }); - martina.values({ name: null }); - angelica.values({ name: 0 }); - sebastian.values({ name: function() {} }); - imma.values({ name: { foo: "bar" } }); + expect(function () { + list.search('jonny') + }).not.toThrow() + expect(function () { + list.search(undefined) + }).not.toThrow() + expect(function () { + list.search(null) + }).not.toThrow() + expect(function () { + list.search(0) + }).not.toThrow() + expect(function () { + list.search(function () {}) + }).not.toThrow() + expect(function () { + list.search({ foo: 'bar' }) + }).not.toThrow() + }) + }) - expect(function() { - list.search("jonny"); - }).not.toThrow(); - expect(function() { - list.search(undefined); - }).not.toThrow(); - expect(function() { - list.search(null); - }).not.toThrow(); - expect(function() { - list.search(0); - }).not.toThrow(); - expect(function() { - list.search(function() {}); - }).not.toThrow(); - expect(function() { - list.search({ foo: "bar" }); - }).not.toThrow(); - }); - }); + describe('Default search columns', function () { + it('should find in the default match column', function () { + list.searchColumns = ['name'] + var result = list.search('jonny') + expect(result.length).toEqual(1) + expect(result[0]).toEqual(jonny) + }) + it('should not find in the default match column', function () { + list.searchColumns = ['born'] + var result = list.search('jonny') + expect(result.length).toEqual(0) + }) + }) + describe('Specfic columns', function () { + it('should find match in column', function () { + var result = list.search('jonny', ['name']) + expect(result.length).toEqual(1) + expect(result[0]).toEqual(jonny) + }) + it('should not find match in column', function () { + var result = list.search('jonny', ['born']) + expect(result.length).toEqual(0) + }) + it('should find match in column', function () { + var result = list.search('jonny', ['name']) + expect(result.length).toEqual(1) + expect(result[0]).toEqual(jonny) + }) + it('should not find match in column', function () { + var result = list.search('jonny', ['born']) + expect(result.length).toEqual(0) + }) + it('should work with columns that does not exist', function () { + var result = list.search('jonny', ['pet']) + expect(result.length).toEqual(0) + }) + it('should remove columnm option', function () { + var result = list.search('jonny', ['born']) + expect(result.length).toEqual(0) + result = list.search('jonny') + expect(result.length).toEqual(1) + }) + }) - describe('Default search columns', function() { - it('should find in the default match column', function() { - list.searchColumns = ['name']; - var result = list.search('jonny'); - expect(result.length).toEqual(1); - expect(result[0]).toEqual(jonny); - }); - it('should not find in the default match column', function() { - list.searchColumns = ['born']; - var result = list.search('jonny'); - expect(result.length).toEqual(0); - }); - }); - - - describe('Specfic columns', function() { - it('should find match in column', function() { - var result = list.search('jonny', [ 'name' ]); - expect(result.length).toEqual(1); - expect(result[0]).toEqual(jonny); - }); - it('should not find match in column', function() { - var result = list.search('jonny', [ 'born' ]); - expect(result.length).toEqual(0); - }); - it('should find match in column', function() { - var result = list.search('jonny', [ 'name' ]); - expect(result.length).toEqual(1); - expect(result[0]).toEqual(jonny); - }); - it('should not find match in column', function() { - var result = list.search('jonny', [ 'born' ]); - expect(result.length).toEqual(0); - }); - it('should work with columns that does not exist', function() { - var result = list.search('jonny', [ 'pet' ]); - expect(result.length).toEqual(0); - }); - it('should remove columnm option', function() { - var result = list.search('jonny', [ 'born' ]); - expect(result.length).toEqual(0); - result = list.search('jonny'); - expect(result.length).toEqual(1); - }); - }); - - describe('Custom search function', function() { - var customSearchFunction = function(searchString, columns) { + describe('Custom search function', function () { + var customSearchFunction = function (searchString, columns) { for (var k = 0, kl = list.items.length; k < kl; k++) { if (list.items[k].values().born > 1985) { - list.items[k].found = true; + list.items[k].found = true } } - }; - it('should use custom function in third argument', function() { - var result = list.search('jonny', [ 'name' ], customSearchFunction); - expect(result.length).toEqual(4); - }); - it('should use custom function in second argument', function() { - var result = list.search('jonny', customSearchFunction); - expect(result.length).toEqual(4); - }); - }); + } + it('should use custom function in third argument', function () { + var result = list.search('jonny', ['name'], customSearchFunction) + expect(result.length).toEqual(4) + }) + it('should use custom function in second argument', function () { + var result = list.search('jonny', customSearchFunction) + expect(result.length).toEqual(4) + }) + }) // // describe('Special characters', function() { // it('should escape and handle special characters', function() { @@ -175,4 +172,4 @@ describe('Search', function() { // expect(result.length).toEqual(1); // }); // }); -}); +}) diff --git a/__test__/show.test.js b/__test__/show.test.js index f39a0195..60fa41cb 100644 --- a/__test__/show.test.js +++ b/__test__/show.test.js @@ -1,210 +1,212 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Show', function() { +describe('Show', function () { + var list, a, b, c, d, e, f - var list, a, b, c, d, e, f; + beforeAll(function () { + list = fixture.list( + ['id', 'id2'], + [ + { id: '1', id2: 'a' }, + { id: '2', id2: 'a' }, + { id: '3', id2: 'b' }, + { id: '4', id2: 'b' }, + { id: '5', id2: 'bc' }, + { id: '6', id2: 'bc' }, + ] + ) + a = list.get('id', '1')[0] + b = list.get('id', '2')[0] + c = list.get('id', '3')[0] + d = list.get('id', '4')[0] + e = list.get('id', '5')[0] + f = list.get('id', '6')[0] + }) - beforeAll(function() { - list = fixture.list(['id', 'id2'], [ - { id: "1", id2: "a" }, - { id: "2", id2: "a" }, - { id: "3", id2: "b" }, - { id: "4", id2: "b" }, - { id: "5", id2: "bc" }, - { id: "6", id2: "bc" } - ]); - a = list.get('id', '1')[0]; - b = list.get('id', '2')[0]; - c = list.get('id', '3')[0]; - d = list.get('id', '4')[0]; - e = list.get('id', '5')[0]; - f = list.get('id', '6')[0]; - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); + afterEach(function () { + list.filter() + list.show(1, 200) + }) - afterEach(function() { - list.filter(); - list.show(1, 200); - }); + describe('Basics', function () { + it('should be 1, 2', function () { + list.show(1, 2) + expect(list.visibleItems.length).toEqual(2) + expect(a.visible()).toBe(true) + expect(b.visible()).toBe(true) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(false) + }) + it('should show item 6', function () { + list.show(6, 2) + expect(list.visibleItems.length).toEqual(1) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(true) + }) + it('should show item 1, 2, 3, 4, 5, 6', function () { + list.show(1, 200) + expect(list.visibleItems.length).toEqual(6) + expect(a.visible()).toBe(true) + expect(b.visible()).toBe(true) + expect(c.visible()).toBe(true) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(true) + }) + it('should show item 3, 4, 5', function () { + list.show(3, 3) + expect(list.visibleItems.length).toEqual(3) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(true) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(false) + }) + it('should show item 5, 6', function () { + list.show(5, 3) + expect(list.visibleItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(true) + }) + }) - describe('Basics', function() { - it('should be 1, 2', function() { - list.show(1,2); - expect(list.visibleItems.length).toEqual(2); - expect(a.visible()).toBe(true); - expect(b.visible()).toBe(true); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(false); - }); - it('should show item 6', function() { - list.show(6,2); - expect(list.visibleItems.length).toEqual(1); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(true); - }); - it('should show item 1, 2, 3, 4, 5, 6', function() { - list.show(1,200); - expect(list.visibleItems.length).toEqual(6); - expect(a.visible()).toBe(true); - expect(b.visible()).toBe(true); - expect(c.visible()).toBe(true); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(true); - }); - it('should show item 3, 4, 5', function() { - list.show(3,3); - expect(list.visibleItems.length).toEqual(3); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(true); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(false); - }); - it('should show item 5, 6', function() { - list.show(5,3); - expect(list.visibleItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(true); - }); - }); + describe('Search', function () { + afterEach(function () { + list.search() + }) + it('should show 3, 4', function () { + list.search('b') + list.show(1, 2) + expect(list.visibleItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(true) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(false) + }) + it('should show item 3,4,5,6', function () { + list.search('b') + list.show(1, 4) + expect(list.visibleItems.length).toEqual(4) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(true) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(true) + }) + it('should not show any items but match two', function () { + list.search('a') + list.show(3, 2) + expect(list.visibleItems.length).toEqual(0) + expect(list.matchingItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(false) + }) + }) - describe('Search', function() { - afterEach(function() { - list.search(); - }); - it('should show 3, 4', function() { - list.search('b'); - list.show(1,2); - expect(list.visibleItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(true); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(false); - }); - it('should show item 3,4,5,6', function() { - list.search('b'); - list.show(1,4); - expect(list.visibleItems.length).toEqual(4); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(true); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(true); - }); - it('should not show any items but match two', function() { - list.search('a'); - list.show(3,2); - expect(list.visibleItems.length).toEqual(0); - expect(list.matchingItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(false); - }); - }); + describe('Filter', function () { + afterEach(function () { + list.filter() + }) + it('should show 3, 4', function () { + list.filter(function (item) { + return item.values().id2 == 'b' + }) + list.show(1, 2) + expect(list.visibleItems.length).toEqual(2) + expect(list.matchingItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(true) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(false) + }) + it('should show item 3,4,5,6', function () { + list.filter(function (item) { + return item.values().id2 == 'bc' + }) + list.show(1, 4) + expect(list.visibleItems.length).toEqual(2) + expect(list.matchingItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(true) + }) + it('should not show any items but match two', function () { + list.filter(function (item) { + return item.values().id2 == 'b' + }) + list.show(3, 2) + expect(list.visibleItems.length).toEqual(0) + expect(list.matchingItems.length).toEqual(2) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(false) + expect(f.visible()).toBe(false) + }) + }) - describe('Filter', function() { - afterEach(function() { - list.filter(); - }); - it('should show 3, 4', function() { - list.filter(function(item) { - return (item.values().id2 == 'b'); - }); - list.show(1,2); - expect(list.visibleItems.length).toEqual(2); - expect(list.matchingItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(true); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(false); - }); - it('should show item 3,4,5,6', function() { - list.filter(function(item) { - return (item.values().id2 == 'bc'); - }); - list.show(1,4); - expect(list.visibleItems.length).toEqual(2); - expect(list.matchingItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(true); - }); - it('should not show any items but match two', function() { - list.filter(function(item) { - return (item.values().id2 == 'b'); - }); - list.show(3,2); - expect(list.visibleItems.length).toEqual(0); - expect(list.matchingItems.length).toEqual(2); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(false); - expect(f.visible()).toBe(false); - }); - }); - - describe('Filter and search', function() { - afterEach(function() { - list.filter(); - }); - it('should show 4, 5', function() { - list.show(1,2); - list.filter(function(item) { - return (item.values().id > '3'); - }); - list.search('b'); - expect(list.visibleItems.length).toEqual(2); - expect(list.matchingItems.length).toEqual(3); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(true); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(false); - }); - it('should show 5, 6', function() { - list.show(1,2); - list.filter(function(item) { - return (item.values().id > '3'); - }); - list.search('b'); - list.show(2,2); - expect(list.visibleItems.length).toEqual(2); - expect(list.matchingItems.length).toEqual(3); - expect(a.visible()).toBe(false); - expect(b.visible()).toBe(false); - expect(c.visible()).toBe(false); - expect(d.visible()).toBe(false); - expect(e.visible()).toBe(true); - expect(f.visible()).toBe(true); - }); - }); -}); + describe('Filter and search', function () { + afterEach(function () { + list.filter() + }) + it('should show 4, 5', function () { + list.show(1, 2) + list.filter(function (item) { + return item.values().id > '3' + }) + list.search('b') + expect(list.visibleItems.length).toEqual(2) + expect(list.matchingItems.length).toEqual(3) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(true) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(false) + }) + it('should show 5, 6', function () { + list.show(1, 2) + list.filter(function (item) { + return item.values().id > '3' + }) + list.search('b') + list.show(2, 2) + expect(list.visibleItems.length).toEqual(2) + expect(list.matchingItems.length).toEqual(3) + expect(a.visible()).toBe(false) + expect(b.visible()).toBe(false) + expect(c.visible()).toBe(false) + expect(d.visible()).toBe(false) + expect(e.visible()).toBe(true) + expect(f.visible()).toBe(true) + }) + }) +}) diff --git a/__test__/sort.test.js b/__test__/sort.test.js index 6e4babdd..c30503f8 100644 --- a/__test__/sort.test.js +++ b/__test__/sort.test.js @@ -1,367 +1,376 @@ const $ = require('jquery'), - fixture = require('./fixtures'); + fixture = require('./fixtures') -describe('Sort', function() { +describe('Sort', function () { + var list, i1, i2, i3, i4, i5, i6 - var list, i1, i2, i3, i4, i5, i6; + beforeEach(function () { + list = fixture.list( + ['id'], + [ + { id: '1', val: '' }, + { id: '2', val: '' }, + { id: '3', val: '' }, + { id: '4', val: '' }, + { id: '5', val: '' }, + { id: '6', val: '' }, + ] + ) + i1 = list.get('id', '1')[0] + i2 = list.get('id', '2')[0] + i3 = list.get('id', '3')[0] + i4 = list.get('id', '4')[0] + i5 = list.get('id', '5')[0] + i6 = list.get('id', '6')[0] + }) - beforeEach(function() { - list = fixture.list(['id'], [ - { id: "1", val: "" }, - { id: "2", val: "" }, - { id: "3", val: "" }, - { id: "4", val: "" }, - { id: "5", val: "" }, - { id: "6", val: "" } - ]); - i1 = list.get('id', '1')[0]; - i2 = list.get('id', '2')[0]; - i3 = list.get('id', '3')[0]; - i4 = list.get('id', '4')[0]; - i5 = list.get('id', '5')[0]; - i6 = list.get('id', '6')[0]; - }); + afterEach(function () { + fixture.removeList() + }) - afterEach(function() { - fixture.removeList(); - }); + describe('Basics', function () { + it('should sort letters asc', function () { + i1.values({ val: 'b' }) + i2.values({ val: 'a' }) + i3.values({ val: 'c' }) + i4.values({ val: 'z' }) + i5.values({ val: 's' }) + i6.values({ val: 'y' }) + list.sort('val') + expect(list.items[0].values().val).toBe('a') + expect(list.items[1].values().val).toBe('b') + expect(list.items[2].values().val).toBe('c') + expect(list.items[3].values().val).toBe('s') + expect(list.items[4].values().val).toBe('y') + expect(list.items[5].values().val).toBe('z') + }) + it('should sort letters desc', function () { + i1.values({ val: 'b' }) + i2.values({ val: 'a' }) + i3.values({ val: 'c' }) + i4.values({ val: 'z' }) + i5.values({ val: 's' }) + i6.values({ val: 'y' }) + list.sort('val', { order: 'desc' }) + expect(list.items[0].values().val).toBe('z') + expect(list.items[1].values().val).toBe('y') + expect(list.items[2].values().val).toBe('s') + expect(list.items[3].values().val).toBe('c') + expect(list.items[4].values().val).toBe('b') + expect(list.items[5].values().val).toBe('a') + }) + it('should sort åäö desc', function () { + list.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVXYZÅÄÖabcdefghijklmnopqrstuvxyzåäö' + i1.values({ val: 'a' }) + i2.values({ val: 'å' }) + i3.values({ val: 'ä' }) + i4.values({ val: 'ö' }) + i5.values({ val: 'o' }) + i6.values({ val: 's' }) + list.sort('val', { order: 'desc' }) + expect(list.items[0].values().val).toBe('ö') + expect(list.items[1].values().val).toBe('ä') + expect(list.items[2].values().val).toBe('å') + expect(list.items[3].values().val).toBe('s') + expect(list.items[4].values().val).toBe('o') + expect(list.items[5].values().val).toBe('a') + }) + it('should sort åäö asc', function () { + list.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVXYZÅÄÖabcdefghijklmnopqrstuvxyzåäö' + i1.values({ val: 'a' }) + i2.values({ val: 'å' }) + i3.values({ val: 'ä' }) + i4.values({ val: 'ö' }) + i5.values({ val: 'o' }) + i6.values({ val: 's' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('a') + expect(list.items[1].values().val).toBe('o') + expect(list.items[2].values().val).toBe('s') + expect(list.items[3].values().val).toBe('å') + expect(list.items[4].values().val).toBe('ä') + expect(list.items[5].values().val).toBe('ö') + }) + it('should sort åäö desc case insensitive', function () { + list.alphabet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZzÅåÄäÖö' + i1.values({ val: 'a' }) + i2.values({ val: 'Å' }) + i3.values({ val: 'ä' }) + i4.values({ val: 'Ö' }) + i5.values({ val: 'o' }) + i6.values({ val: 'S' }) + list.sort('val', { order: 'desc' }) + expect(list.items[0].values().val).toBe('Ö') + expect(list.items[1].values().val).toBe('ä') + expect(list.items[2].values().val).toBe('Å') + expect(list.items[3].values().val).toBe('S') + expect(list.items[4].values().val).toBe('o') + expect(list.items[5].values().val).toBe('a') + }) + it('should sort åäö asc case insensitive', function () { + list.alphabet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZzÅåÄäÖö' + i1.values({ val: 'A' }) + i2.values({ val: 'å' }) + i3.values({ val: 'Ä' }) + i4.values({ val: 'ö' }) + i5.values({ val: 'O' }) + i6.values({ val: 's' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('A') + expect(list.items[1].values().val).toBe('O') + expect(list.items[2].values().val).toBe('s') + expect(list.items[3].values().val).toBe('å') + expect(list.items[4].values().val).toBe('Ä') + expect(list.items[5].values().val).toBe('ö') + }) + it('should handle case-insensitive by default', function () { + i1.values({ val: 'e' }) + i2.values({ val: 'b' }) + i4.values({ val: 'F' }) + i3.values({ val: 'D' }) + i5.values({ val: 'A' }) + i6.values({ val: 'C' }) + list.sort('val') + expect(list.items[0].values().val).toBe('A') + expect(list.items[1].values().val).toBe('b') + expect(list.items[2].values().val).toBe('C') + expect(list.items[3].values().val).toBe('D') + expect(list.items[4].values().val).toBe('e') + expect(list.items[5].values().val).toBe('F') + }) + it('should disable insensitive', function () { + i1.values({ val: 'e' }) + i2.values({ val: 'b' }) + i4.values({ val: 'F' }) + i3.values({ val: 'D' }) + i5.values({ val: 'A' }) + i6.values({ val: 'C' }) + list.sort('val', { insensitive: false }) + expect(list.items[0].values().val).toBe('A') + expect(list.items[1].values().val).toBe('C') + expect(list.items[2].values().val).toBe('D') + expect(list.items[3].values().val).toBe('F') + expect(list.items[4].values().val).toBe('b') + expect(list.items[5].values().val).toBe('e') + }) + it('should sort dates', function () { + i1.values({ val: '2008-12-10' }) + i2.values({ val: '2008-11-10' }) + i3.values({ val: '2007-11-10' }) + i4.values({ val: '2009-12-10' }) + i5.values({ val: '2007-01-4' }) + i6.values({ val: '2006-12-10' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('2006-12-10') + expect(list.items[1].values().val).toBe('2007-01-4') + expect(list.items[2].values().val).toBe('2007-11-10') + expect(list.items[3].values().val).toBe('2008-11-10') + expect(list.items[4].values().val).toBe('2008-12-10') + expect(list.items[5].values().val).toBe('2009-12-10') + }) + it('should sort file names (a bit wrong)', function () { + i1.values({ val: 'car.mov' }) + i2.values({ val: '01alpha.sgi' }) + i3.values({ val: '001alpha.sgi' }) + i4.values({ val: 'my.string_41299.tif' }) + i5.values({ val: '0003.zip' }) + i6.values({ val: '0002.asp' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('01alpha.sgi') + expect(list.items[1].values().val).toBe('001alpha.sgi') + expect(list.items[2].values().val).toBe('0002.asp') + expect(list.items[3].values().val).toBe('0003.zip') + expect(list.items[4].values().val).toBe('car.mov') + expect(list.items[5].values().val).toBe('my.string_41299.tif') + }) + it('should show order of sorted floates (a bit wrong)', function () { + i1.values({ val: '10.0401' }) + i2.values({ val: '10.022' }) + i3.values({ val: '10.021999' }) + i4.values({ val: '11.231' }) + i5.values({ val: '0003.123' }) + i6.values({ val: '09.2123' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('0003.123') + expect(list.items[1].values().val).toBe('09.2123') + expect(list.items[2].values().val).toBe('10.022') + expect(list.items[3].values().val).toBe('10.0401') + expect(list.items[4].values().val).toBe('10.021999') + expect(list.items[5].values().val).toBe('11.231') + }) + it('should sort IP addresses', function () { + i1.values({ val: '192.168.1.1' }) + i2.values({ val: '192.168.0.100' }) + i3.values({ val: '192.168.0.1' }) + i4.values({ val: '192.168.1.3' }) + i5.values({ val: '127.0.0.1' }) + i6.values({ val: '192.168.1.2' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('127.0.0.1') + expect(list.items[1].values().val).toBe('192.168.0.1') + expect(list.items[2].values().val).toBe('192.168.0.100') + expect(list.items[3].values().val).toBe('192.168.1.1') + expect(list.items[4].values().val).toBe('192.168.1.2') + expect(list.items[5].values().val).toBe('192.168.1.3') + }) + it('should not break with weird values', function () { + i1.values({ val: undefined }) + i2.values({ val: null }) + i3.values({ val: 0 }) + i4.values({ val: function () {} }) + i5.values({ val: { foo: 'bar' } }) - describe('Basics', function() { - it('should sort letters asc', function() { - i1.values({ val: "b" }); - i2.values({ val: "a" }); - i3.values({ val: "c" }); - i4.values({ val: "z" }); - i5.values({ val: "s" }); - i6.values({ val: "y" }); - list.sort('val'); - expect(list.items[0].values().val).toBe("a"); - expect(list.items[1].values().val).toBe("b"); - expect(list.items[2].values().val).toBe("c"); - expect(list.items[3].values().val).toBe("s"); - expect(list.items[4].values().val).toBe("y"); - expect(list.items[5].values().val).toBe("z"); - }); - it('should sort letters desc', function() { - i1.values({ val: "b" }); - i2.values({ val: "a" }); - i3.values({ val: "c" }); - i4.values({ val: "z" }); - i5.values({ val: "s" }); - i6.values({ val: "y" }); - list.sort('val', { order: "desc" }); - expect(list.items[0].values().val).toBe("z"); - expect(list.items[1].values().val).toBe("y"); - expect(list.items[2].values().val).toBe("s"); - expect(list.items[3].values().val).toBe("c"); - expect(list.items[4].values().val).toBe("b"); - expect(list.items[5].values().val).toBe("a"); - }); - it('should sort åäö desc', function() { - list.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVXYZÅÄÖabcdefghijklmnopqrstuvxyzåäö'; - i1.values({ val: "a" }); - i2.values({ val: "å" }); - i3.values({ val: "ä" }); - i4.values({ val: "ö" }); - i5.values({ val: "o" }); - i6.values({ val: "s" }); - list.sort('val', { order: "desc" }); - expect(list.items[0].values().val).toBe("ö"); - expect(list.items[1].values().val).toBe("ä"); - expect(list.items[2].values().val).toBe("å"); - expect(list.items[3].values().val).toBe("s"); - expect(list.items[4].values().val).toBe("o"); - expect(list.items[5].values().val).toBe("a"); - }); - it('should sort åäö asc', function() { - list.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVXYZÅÄÖabcdefghijklmnopqrstuvxyzåäö'; - i1.values({ val: "a" }); - i2.values({ val: "å" }); - i3.values({ val: "ä" }); - i4.values({ val: "ö" }); - i5.values({ val: "o" }); - i6.values({ val: "s" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("a"); - expect(list.items[1].values().val).toBe("o"); - expect(list.items[2].values().val).toBe("s"); - expect(list.items[3].values().val).toBe("å"); - expect(list.items[4].values().val).toBe("ä"); - expect(list.items[5].values().val).toBe("ö"); - }); - it('should sort åäö desc case insensitive', function() { - list.alphabet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZzÅåÄäÖö'; - i1.values({ val: "a" }); - i2.values({ val: "Å" }); - i3.values({ val: "ä" }); - i4.values({ val: "Ö" }); - i5.values({ val: "o" }); - i6.values({ val: "S" }); - list.sort('val', { order: "desc" }); - expect(list.items[0].values().val).toBe("Ö"); - expect(list.items[1].values().val).toBe("ä"); - expect(list.items[2].values().val).toBe("Å"); - expect(list.items[3].values().val).toBe("S"); - expect(list.items[4].values().val).toBe("o"); - expect(list.items[5].values().val).toBe("a"); - }); - it('should sort åäö asc case insensitive', function() { - list.alphabet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZzÅåÄäÖö'; - i1.values({ val: "A" }); - i2.values({ val: "å" }); - i3.values({ val: "Ä" }); - i4.values({ val: "ö" }); - i5.values({ val: "O" }); - i6.values({ val: "s" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("A"); - expect(list.items[1].values().val).toBe("O"); - expect(list.items[2].values().val).toBe("s"); - expect(list.items[3].values().val).toBe("å"); - expect(list.items[4].values().val).toBe("Ä"); - expect(list.items[5].values().val).toBe("ö"); - }); - it('should handle case-insensitive by default', function() { - i1.values({ val: "e" }); - i2.values({ val: "b" }); - i4.values({ val: "F" }); - i3.values({ val: "D" }); - i5.values({ val: "A" }); - i6.values({ val: "C" }); - list.sort('val'); - expect(list.items[0].values().val).toBe("A"); - expect(list.items[1].values().val).toBe("b"); - expect(list.items[2].values().val).toBe("C"); - expect(list.items[3].values().val).toBe("D"); - expect(list.items[4].values().val).toBe("e"); - expect(list.items[5].values().val).toBe("F"); - }); - it('should disable insensitive', function() { - i1.values({ val: "e" }); - i2.values({ val: "b" }); - i4.values({ val: "F" }); - i3.values({ val: "D" }); - i5.values({ val: "A" }); - i6.values({ val: "C" }); - list.sort('val', { insensitive: false }); - expect(list.items[0].values().val).toBe("A"); - expect(list.items[1].values().val).toBe("C"); - expect(list.items[2].values().val).toBe("D"); - expect(list.items[3].values().val).toBe("F"); - expect(list.items[4].values().val).toBe("b"); - expect(list.items[5].values().val).toBe("e"); - }); - it('should sort dates', function() { - i1.values({ val: "2008-12-10" }); - i2.values({ val: "2008-11-10" }); - i3.values({ val: "2007-11-10" }); - i4.values({ val: "2009-12-10" }); - i5.values({ val: "2007-01-4" }); - i6.values({ val: "2006-12-10" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("2006-12-10"); - expect(list.items[1].values().val).toBe("2007-01-4"); - expect(list.items[2].values().val).toBe("2007-11-10"); - expect(list.items[3].values().val).toBe("2008-11-10"); - expect(list.items[4].values().val).toBe("2008-12-10"); - expect(list.items[5].values().val).toBe("2009-12-10"); - }); - it('should sort file names (a bit wrong)', function() { - i1.values({ val: "car.mov" }); - i2.values({ val: "01alpha.sgi" }); - i3.values({ val: "001alpha.sgi" }); - i4.values({ val: "my.string_41299.tif" }); - i5.values({ val: "0003.zip" }); - i6.values({ val: "0002.asp" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("01alpha.sgi"); - expect(list.items[1].values().val).toBe("001alpha.sgi"); - expect(list.items[2].values().val).toBe("0002.asp"); - expect(list.items[3].values().val).toBe("0003.zip"); - expect(list.items[4].values().val).toBe("car.mov"); - expect(list.items[5].values().val).toBe("my.string_41299.tif"); - }); - it('should show order of sorted floates (a bit wrong)', function() { - i1.values({ val: "10.0401" }); - i2.values({ val: "10.022" }); - i3.values({ val: "10.021999" }); - i4.values({ val: "11.231" }); - i5.values({ val: "0003.123" }); - i6.values({ val: "09.2123" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("0003.123"); - expect(list.items[1].values().val).toBe("09.2123"); - expect(list.items[2].values().val).toBe("10.022"); - expect(list.items[3].values().val).toBe("10.0401"); - expect(list.items[4].values().val).toBe("10.021999"); - expect(list.items[5].values().val).toBe("11.231"); - }); - it('should sort IP addresses', function() { - i1.values({ val: "192.168.1.1" }); - i2.values({ val: "192.168.0.100" }); - i3.values({ val: "192.168.0.1" }); - i4.values({ val: "192.168.1.3" }); - i5.values({ val: "127.0.0.1" }); - i6.values({ val: "192.168.1.2" }); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe("127.0.0.1"); - expect(list.items[1].values().val).toBe("192.168.0.1"); - expect(list.items[2].values().val).toBe("192.168.0.100"); - expect(list.items[3].values().val).toBe("192.168.1.1"); - expect(list.items[4].values().val).toBe("192.168.1.2"); - expect(list.items[5].values().val).toBe("192.168.1.3"); - }); - it('should not break with weird values', function() { - i1.values({ val: undefined }); - i2.values({ val: null }); - i3.values({ val: 0 }); - i4.values({ val: function() {} }); - i5.values({ val: { foo: "bar" } }); + expect(function () { + list.sort('val') + }).not.toThrow() + }) + it('should handle values from issue 387', function () { + i1.values({ val: 'Test' }) + i2.values({ val: 'Test1Test2' }) + i3.values({ val: 'Bill-To Phone1 Extension' }) + i4.values({ val: 'z' }) + i5.values({ val: 's' }) + i6.values({ val: 'y' }) + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('Bill-To Phone1 Extension') + expect(list.items[1].values().val).toBe('s') + expect(list.items[2].values().val).toBe('Test') + expect(list.items[3].values().val).toBe('Test1Test2') + expect(list.items[4].values().val).toBe('y') + expect(list.items[5].values().val).toBe('z') + }) - expect(function() { - list.sort('val'); - }).not.toThrow(); - }); - it('should handle values from issue 387', function() { - i1.values({ val: 'Test' }); - i2.values({ val: 'Test1Test2' }); - i3.values({ val: 'Bill-To Phone1 Extension' }); - i4.values({ val: "z" }); - i5.values({ val: "s" }); - i6.values({ val: "y" }); - list.sort('val', { order: 'asc' }); - expect(list.items[0].values().val).toBe('Bill-To Phone1 Extension'); - expect(list.items[1].values().val).toBe('s'); - expect(list.items[2].values().val).toBe('Test'); - expect(list.items[3].values().val).toBe('Test1Test2'); - expect(list.items[4].values().val).toBe('y'); - expect(list.items[5].values().val).toBe('z'); - }); - - xit('should show how random values are sorted', function() { - list.add({ id: '7', val: "" }); - list.add({ id: '8', val: "" }); - list.add({ id: '9', val: "" }); - list.add({ id: '10', val: "" }); - list.add({ id: '11', val: "" }); - list.add({ id: '12', val: "" }); + xit('should show how random values are sorted', function () { + list.add({ id: '7', val: '' }) + list.add({ id: '8', val: '' }) + list.add({ id: '9', val: '' }) + list.add({ id: '10', val: '' }) + list.add({ id: '11', val: '' }) + list.add({ id: '12', val: '' }) var i7 = list.get('id', '7')[0], i8 = list.get('id', '8')[0], i9 = list.get('id', '9')[0], i10 = list.get('id', '10')[0], i11 = list.get('id', '11')[0], - i12 = list.get('id', '12')[0]; - - i1.values({ val: undefined }); - i2.values({ val: "" }); - i3.values({ val: null }); - i4.values({ val: "a" }); - i5.values({ val: "0" }); - i6.values({ val: true }); - i7.values({ val: 0 }); - i8.values({ val: "z" }); - i9.values({ val: "!" }); - i10.values({ val: "?" }); - i11.values({ val: 100 }); - i12.values({ val: false }); + i12 = list.get('id', '12')[0] - list.sort('val', { order: "asc" }); - list.sort('val', { order: "desc" }); - list.sort('val', { order: "asc" }); + i1.values({ val: undefined }) + i2.values({ val: '' }) + i3.values({ val: null }) + i4.values({ val: 'a' }) + i5.values({ val: '0' }) + i6.values({ val: true }) + i7.values({ val: 0 }) + i8.values({ val: 'z' }) + i9.values({ val: '!' }) + i10.values({ val: '?' }) + i11.values({ val: 100 }) + i12.values({ val: false }) - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe("!"); - expect(list.items[2].values().val).toBe(0); - expect(list.items[3].values().val).toBe("0"); - expect(list.items[4].values().val).toBe(100); - expect(list.items[5].values().val).toBe("?"); - expect(list.items[6].values().val).toBe("a"); - expect(list.items[7].values().val).toBe(false); - expect(list.items[8].values().val).toBe(null); - expect(list.items[9].values().val).toBe(true); - expect(list.items[10].values().val).toBe(undefined); - expect(list.items[11].values().val).toBe("z"); - }); + list.sort('val', { order: 'asc' }) + list.sort('val', { order: 'desc' }) + list.sort('val', { order: 'asc' }) - it('should handle not longer (since 1.4.0) space and zero the same for desc and asc', function() { - list.clear(); - list.add({ val: "" }); - list.add({ val: "0" }); - list.add({ val: 0 }); + expect(list.items[0].values().val).toBe('') + expect(list.items[1].values().val).toBe('!') + expect(list.items[2].values().val).toBe(0) + expect(list.items[3].values().val).toBe('0') + expect(list.items[4].values().val).toBe(100) + expect(list.items[5].values().val).toBe('?') + expect(list.items[6].values().val).toBe('a') + expect(list.items[7].values().val).toBe(false) + expect(list.items[8].values().val).toBe(null) + expect(list.items[9].values().val).toBe(true) + expect(list.items[10].values().val).toBe(undefined) + expect(list.items[11].values().val).toBe('z') + }) - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe("0"); - expect(list.items[2].values().val).toBe(0); - list.sort('val', { order: "desc" }); - expect(list.items[0].values().val).toBe("0"); - expect(list.items[1].values().val).toBe(0); - expect(list.items[2].values().val).toBe(""); - list.sort('val', { order: "asc" }); - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe("0"); - expect(list.items[2].values().val).toBe(0); - }); + it('should handle not longer (since 1.4.0) space and zero the same for desc and asc', function () { + list.clear() + list.add({ val: '' }) + list.add({ val: '0' }) + list.add({ val: 0 }) - }); + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('') + expect(list.items[1].values().val).toBe('0') + expect(list.items[2].values().val).toBe(0) + list.sort('val', { order: 'desc' }) + expect(list.items[0].values().val).toBe('0') + expect(list.items[1].values().val).toBe(0) + expect(list.items[2].values().val).toBe('') + list.sort('val', { order: 'asc' }) + expect(list.items[0].values().val).toBe('') + expect(list.items[1].values().val).toBe('0') + expect(list.items[2].values().val).toBe(0) + }) + }) - describe('Custom sort function', function() { - it('should use custom sort option', function() { - i1.values({ val: "" }); - i2.values({ val: "" }); - i3.values({ val: "" }); - i4.values({ val: "" }); - i5.values({ val: "" }); - i6.values({ val: "" }); + describe('Custom sort function', function () { + it('should use custom sort option', function () { + i1.values({ val: "" }) + i2.values({ val: "" }) + i3.values({ val: "" }) + i4.values({ val: "" }) + i5.values({ val: "" }) + i6.values({ val: "" }) list.sort('val', { - sortFunction: function(itemA, itemB, options) { - return list.utils.naturalSort($(itemA.values()[options.valueName]).val(), $(itemB.values()[options.valueName]).val()); - } - }); - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe(""); - expect(list.items[2].values().val).toBe(""); - expect(list.items[3].values().val).toBe(""); - expect(list.items[4].values().val).toBe(""); - expect(list.items[5].values().val).toBe(""); - }); - it('should use default custom sort function', function() { - list.sortFunction = function(itemA, itemB, options) { - return list.utils.naturalSort($(itemA.values()[options.valueName]).val(), $(itemB.values()[options.valueName]).val()); - }; - i1.values({ val: "" }); - i2.values({ val: "" }); - i3.values({ val: "" }); - i4.values({ val: "" }); - i5.values({ val: "" }); - i6.values({ val: "" }); - list.sort('val'); - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe(""); - expect(list.items[2].values().val).toBe(""); - expect(list.items[3].values().val).toBe(""); - expect(list.items[4].values().val).toBe(""); - expect(list.items[5].values().val).toBe(""); - }); - it('should use default custom sort function with order desc', function() { - list.sortFunction = function(itemA, itemB, options) { - return list.utils.naturalSort($(itemA.values()[options.valueName]).val(), $(itemB.values()[options.valueName]).val()); - }; - i1.values({ val: "" }); - i2.values({ val: "" }); - i3.values({ val: "" }); - i4.values({ val: "" }); - i5.values({ val: "" }); - i6.values({ val: "" }); - list.sort('val', { order: "desc"}); - expect(list.items[0].values().val).toBe(""); - expect(list.items[1].values().val).toBe(""); - expect(list.items[2].values().val).toBe(""); - expect(list.items[3].values().val).toBe(""); - expect(list.items[4].values().val).toBe(""); - expect(list.items[5].values().val).toBe(""); - }); - }); - -}); + sortFunction: function (itemA, itemB, options) { + return list.utils.naturalSort( + $(itemA.values()[options.valueName]).val(), + $(itemB.values()[options.valueName]).val() + ) + }, + }) + expect(list.items[0].values().val).toBe("") + expect(list.items[1].values().val).toBe("") + expect(list.items[2].values().val).toBe("") + expect(list.items[3].values().val).toBe("") + expect(list.items[4].values().val).toBe("") + expect(list.items[5].values().val).toBe("") + }) + it('should use default custom sort function', function () { + list.sortFunction = function (itemA, itemB, options) { + return list.utils.naturalSort( + $(itemA.values()[options.valueName]).val(), + $(itemB.values()[options.valueName]).val() + ) + } + i1.values({ val: "" }) + i2.values({ val: "" }) + i3.values({ val: "" }) + i4.values({ val: "" }) + i5.values({ val: "" }) + i6.values({ val: "" }) + list.sort('val') + expect(list.items[0].values().val).toBe("") + expect(list.items[1].values().val).toBe("") + expect(list.items[2].values().val).toBe("") + expect(list.items[3].values().val).toBe("") + expect(list.items[4].values().val).toBe("") + expect(list.items[5].values().val).toBe("") + }) + it('should use default custom sort function with order desc', function () { + list.sortFunction = function (itemA, itemB, options) { + return list.utils.naturalSort( + $(itemA.values()[options.valueName]).val(), + $(itemB.values()[options.valueName]).val() + ) + } + i1.values({ val: "" }) + i2.values({ val: "" }) + i3.values({ val: "" }) + i4.values({ val: "" }) + i5.values({ val: "" }) + i6.values({ val: "" }) + list.sort('val', { order: 'desc' }) + expect(list.items[0].values().val).toBe("") + expect(list.items[1].values().val).toBe("") + expect(list.items[2].values().val).toBe("") + expect(list.items[3].values().val).toBe("") + expect(list.items[4].values().val).toBe("") + expect(list.items[5].values().val).toBe("") + }) + }) +}) diff --git a/__test__/trigger.test.js b/__test__/trigger.test.js index 4e92a31c..9c0077a7 100644 --- a/__test__/trigger.test.js +++ b/__test__/trigger.test.js @@ -1,23 +1,22 @@ -const fixture = require('./fixtures'); +const fixture = require('./fixtures') -describe('Trigger', function() { +describe('Trigger', function () { + var list - var list; + beforeAll(function () { + list = fixture.list(['name', 'born'], fixture.all) + }) - beforeAll(function() { - list = fixture.list(['name', 'born'], fixture.all); - }); + afterAll(function () { + fixture.removeList() + }) - afterAll(function() { - fixture.removeList(); - }); - - describe('General', function() { - it('should be triggered by searchComplete', function(done) { - list.on('searchComplete', function() { - done(); - }); - list.trigger('searchComplete'); - }); - }); -}); + describe('General', function () { + it('should be triggered by searchComplete', function (done) { + list.on('searchComplete', function () { + done() + }) + list.trigger('searchComplete') + }) + }) +}) diff --git a/__test__/usage/main.js b/__test__/usage/main.js index 63cc377b..5ff9002e 100644 --- a/__test__/usage/main.js +++ b/__test__/usage/main.js @@ -1,6 +1,6 @@ -require(['../../dist/list', '../../dist/list.min'], function(List, ListMin) { +require(['../../dist/list', '../../dist/list.min'], function (List, ListMin) { var options = { - valueNames: [ 'name', 'born' ] - }; - var userList = new List('users', options); -}); + valueNames: ['name', 'born'], + } + var userList = new List('users', options) +}) diff --git a/__test__/usage/require.js b/__test__/usage/require.js index d50f25fe..7360434e 100644 --- a/__test__/usage/require.js +++ b/__test__/usage/require.js @@ -8,2076 +8,2135 @@ /*jslint regexp: true, nomen: true, sloppy: true */ /*global window, navigator, document, importScripts, setTimeout, opera */ -var requirejs, require, define; -(function (global) { - var req, s, head, baseElement, dataMain, src, - interactiveScript, currentlyAddingScript, mainScript, subPath, - version = '2.1.17', - commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - jsSuffixRegExp = /\.js$/, - currDirRegExp = /^\.\//, - op = Object.prototype, - ostring = op.toString, - hasOwn = op.hasOwnProperty, - ap = Array.prototype, - apsp = ap.splice, - isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), - isWebWorker = !isBrowser && typeof importScripts !== 'undefined', - //PS3 indicates loaded and complete, but need to wait for complete - //specifically. Sequence is 'loading', 'loaded', execution, - // then 'complete'. The UA check is unfortunate, but not sure how - //to feature test w/o causing perf issues. - readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? - /^complete$/ : /^(complete|loaded)$/, - defContextName = '_', - //Oh the tragedy, detecting opera. See the usage of isOpera for reason. - isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', - contexts = {}, - cfg = {}, - globalDefQueue = [], - useInteractive = false; - - function isFunction(it) { - return ostring.call(it) === '[object Function]'; +var requirejs, require, define +;(function (global) { + var req, + s, + head, + baseElement, + dataMain, + src, + interactiveScript, + currentlyAddingScript, + mainScript, + subPath, + version = '2.1.17', + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm, + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, + jsSuffixRegExp = /\.js$/, + currDirRegExp = /^\.\//, + op = Object.prototype, + ostring = op.toString, + hasOwn = op.hasOwnProperty, + ap = Array.prototype, + apsp = ap.splice, + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is 'loading', 'loaded', execution, + // then 'complete'. The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, + defContextName = '_', + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', + contexts = {}, + cfg = {}, + globalDefQueue = [], + useInteractive = false + + function isFunction(it) { + return ostring.call(it) === '[object Function]' + } + + function isArray(it) { + return ostring.call(it) === '[object Array]' + } + + /** + * Helper function for iterating over an array. If the func returns + * a true value, it will break out of the loop. + */ + function each(ary, func) { + if (ary) { + var i + for (i = 0; i < ary.length; i += 1) { + if (ary[i] && func(ary[i], i, ary)) { + break + } + } } - - function isArray(it) { - return ostring.call(it) === '[object Array]'; + } + + /** + * Helper function for iterating over an array backwards. If the func + * returns a true value, it will break out of the loop. + */ + function eachReverse(ary, func) { + if (ary) { + var i + for (i = ary.length - 1; i > -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break + } + } } - - /** - * Helper function for iterating over an array. If the func returns - * a true value, it will break out of the loop. - */ - function each(ary, func) { - if (ary) { - var i; - for (i = 0; i < ary.length; i += 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } - } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop) + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop] + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break } + } } - - /** - * Helper function for iterating over an array backwards. If the func - * returns a true value, it will break out of the loop. - */ - function eachReverse(ary, func) { - if (ary) { - var i; - for (i = ary.length - 1; i > -1; i -= 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if ( + deepStringMixin && + typeof value === 'object' && + value && + !isArray(value) && + !isFunction(value) && + !(value instanceof RegExp) + ) { + if (!target[prop]) { + target[prop] = {} } + mixin(target[prop], value, force, deepStringMixin) + } else { + target[prop] = value + } } + }) } - - function hasProp(obj, prop) { - return hasOwn.call(obj, prop); + return target + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments) } + } + + function scripts() { + return document.getElementsByTagName('script') + } + + function defaultOnError(err) { + throw err + } - function getOwn(obj, prop) { - return hasProp(obj, prop) && obj[prop]; + //Allow getting a global that is expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value } + var g = global + each(value.split('.'), function (part) { + g = g[part] + }) + return g + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id) + e.requireType = id + e.requireModules = requireModules + if (err) { + e.originalError = err + } + return e + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite an existing requirejs instance. + return + } + cfg = requirejs + requirejs = undefined + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require + require = undefined + } + + function newContext(contextName) { + var inCheckLoaded, + Module, + context, + handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + bundles: {}, + pkgs: {}, + shim: {}, + config: {}, + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + bundlesMap = {}, + requireCounter = 1, + unnormalizedCounter = 1 /** - * Cycles over properties in an object and calls a function for each - * property value. If the function returns a truthy value, then the - * iteration is stopped. + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. */ - function eachProp(obj, func) { - var prop; - for (prop in obj) { - if (hasProp(obj, prop)) { - if (func(obj[prop], prop)) { - break; - } - } + function trimDots(ary) { + var i, part + for (i = 0; i < ary.length; i++) { + part = ary[i] + if (part === '.') { + ary.splice(i, 1) + i -= 1 + } else if (part === '..') { + // If at the start, or previous value is still .., + // keep them so that when converted to a path it may + // still work when converted to a path, even though + // as an ID it is less than ideal. In larger point + // releases, may be better to just kick out an error. + if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { + continue + } else if (i > 0) { + ary.splice(i - 1, 2) + i -= 2 + } } + } } /** - * Simple function to mix in properties from source into target, - * but only if target does not already have a property of the same name. + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name */ - function mixin(target, source, force, deepStringMixin) { - if (source) { - eachProp(source, function (value, prop) { - if (force || !hasProp(target, prop)) { - if (deepStringMixin && typeof value === 'object' && value && - !isArray(value) && !isFunction(value) && - !(value instanceof RegExp)) { - - if (!target[prop]) { - target[prop] = {}; - } - mixin(target[prop], value, force, deepStringMixin); - } else { - target[prop] = value; - } + function normalize(name, baseName, applyMap) { + var pkgMain, + mapValue, + nameParts, + i, + j, + nameSegment, + lastIndex, + foundMap, + foundI, + foundStarMap, + starI, + normalizedBaseParts, + baseParts = baseName && baseName.split('/'), + map = config.map, + starMap = map && map['*'] + + //Adjust any relative paths. + if (name) { + name = name.split('/') + lastIndex = name.length - 1 + + // If wanting node ID compatibility, strip .js from end + // of IDs. Have to do this here, and not in nameToUrl + // because node allows either .js or non .js to map + // to same file. + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '') + } + + // Starts with a '.' so need the baseName + if (name[0].charAt(0) === '.' && baseParts) { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1) + name = normalizedBaseParts.concat(name) + } + + trimDots(name) + name = name.join('/') + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/') + + outerLoop: for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/') + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')) + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment) + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue + foundI = i + break outerLoop } - }); + } + } + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment) + starI = i + } } - return target; - } - //Similar to Function.prototype.bind, but the 'this' object is specified - //first, since it is easier to read/figure out what 'this' will be. - function bind(obj, fn) { - return function () { - return fn.apply(obj, arguments); - }; + if (!foundMap && foundStarMap) { + foundMap = foundStarMap + foundI = starI + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap) + name = nameParts.join('/') + } + } + + // If the name points to a package's name, use + // the package main instead. + pkgMain = getOwn(config.pkgs, name) + + return pkgMain ? pkgMain : name } - function scripts() { - return document.getElementsByTagName('script'); + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if ( + scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName + ) { + scriptNode.parentNode.removeChild(scriptNode) + return true + } + }) + } } - function defaultOnError(err) { - throw err; + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id) + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift() + context.require.undef(id) + + //Custom require that does not do map translation, since + //ID is "absolute", already mapped/resolved. + context.makeRequire(null, { + skipMap: true, + })([id]) + + return true + } } - //Allow getting a global that is expressed in - //dot notation, like 'a.b.c'. - function getGlobal(value) { - if (!value) { - return value; - } - var g = global; - each(value.split('.'), function (part) { - g = g[part]; - }); - return g; + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1 + if (index > -1) { + prefix = name.substring(0, index) + name = name.substring(index + 1, name.length) + } + return [prefix, name] } /** - * Constructs an error with a pointer to an URL with more information. - * @param {String} id the error ID that maps to an ID on a web page. - * @param {String} message human readable error. - * @param {Error} [err] the original error, if there is one. + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. * - * @returns {Error} + * @returns {Object} */ - function makeError(id, msg, err, requireModules) { - var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); - e.requireType = id; - e.requireModules = requireModules; - if (err) { - e.originalError = err; + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, + pluginModule, + suffix, + nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = '' + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false + name = '_@r' + (requireCounter += 1) + } + + nameParts = splitPrefix(name) + prefix = nameParts[0] + name = nameParts[1] + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap) + pluginModule = getOwn(defined, prefix) + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap) + }) + } else { + // If nested plugin references, then do not try to + // normalize, as it will not normalize correctly. This + // places a restriction on resourceIds, and the longer + // term solution is not to normalize until plugins are + // loaded and all normalizations to allow for async + // loading of a loader plugin. But for now, fixes the + // common uses. Details in #1131 + normalizedName = name.indexOf('!') === -1 ? normalize(name, parentName, applyMap) : name + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap) + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName) + prefix = nameParts[0] + normalizedName = nameParts[1] + isNormalized = true + + url = context.nameToUrl(normalizedName) } - return e; + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? '_unnormalized' + (unnormalizedCounter += 1) : '' + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? prefix + '!' + normalizedName : normalizedName) + suffix, + } } - if (typeof define !== 'undefined') { - //If a define is already in play via another AMD loader, - //do not overwrite. - return; - } + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id) - if (typeof requirejs !== 'undefined') { - if (isFunction(requirejs)) { - //Do not overwrite an existing requirejs instance. - return; - } - cfg = requirejs; - requirejs = undefined; - } + if (!mod) { + mod = registry[id] = new context.Module(depMap) + } - //Allow for a require config object - if (typeof require !== 'undefined' && !isFunction(require)) { - //assume it is a config object. - cfg = require; - require = undefined; + return mod } - function newContext(contextName) { - var inCheckLoaded, Module, context, handlers, - checkLoadedTimeoutId, - config = { - //Defaults. Do not set a default for map - //config to speed up normalize(), which - //will run faster if there is no default. - waitSeconds: 7, - baseUrl: './', - paths: {}, - bundles: {}, - pkgs: {}, - shim: {}, - config: {} - }, - registry = {}, - //registry of just enabled modules, to speed - //cycle breaking code when lots of modules - //are registered, but not activated. - enabledRegistry = {}, - undefEvents = {}, - defQueue = [], - defined = {}, - urlFetched = {}, - bundlesMap = {}, - requireCounter = 1, - unnormalizedCounter = 1; - - /** - * Trims the . and .. from an array of path segments. - * It will keep a leading path segment if a .. will become - * the first path segment, to help with module name lookups, - * which act like paths, but can be remapped. But the end result, - * all paths that use this function should look normalized. - * NOTE: this method MODIFIES the input array. - * @param {Array} ary the array of path segments. - */ - function trimDots(ary) { - var i, part; - for (i = 0; i < ary.length; i++) { - part = ary[i]; - if (part === '.') { - ary.splice(i, 1); - i -= 1; - } else if (part === '..') { - // If at the start, or previous value is still .., - // keep them so that when converted to a path it may - // still work when converted to a path, even though - // as an ID it is less than ideal. In larger point - // releases, may be better to just kick out an error. - if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { - continue; - } else if (i > 0) { - ary.splice(i - 1, 2); - i -= 2; - } - } - } - } - - /** - * Given a relative module name, like ./something, normalize it to - * a real name that can be mapped to a path. - * @param {String} name the relative name - * @param {String} baseName a real name that the name arg is relative - * to. - * @param {Boolean} applyMap apply the map config to the value. Should - * only be done if this normalization is for a dependency ID. - * @returns {String} normalized name - */ - function normalize(name, baseName, applyMap) { - var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, - foundMap, foundI, foundStarMap, starI, normalizedBaseParts, - baseParts = (baseName && baseName.split('/')), - map = config.map, - starMap = map && map['*']; - - //Adjust any relative paths. - if (name) { - name = name.split('/'); - lastIndex = name.length - 1; - - // If wanting node ID compatibility, strip .js from end - // of IDs. Have to do this here, and not in nameToUrl - // because node allows either .js or non .js to map - // to same file. - if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { - name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); - } - - // Starts with a '.' so need the baseName - if (name[0].charAt(0) === '.' && baseParts) { - //Convert baseName to array, and lop off the last part, - //so that . matches that 'directory' and not name of the baseName's - //module. For instance, baseName of 'one/two/three', maps to - //'one/two/three.js', but we want the directory, 'one/two' for - //this normalization. - normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); - name = normalizedBaseParts.concat(name); - } - - trimDots(name); - name = name.join('/'); - } - - //Apply map config if available. - if (applyMap && map && (baseParts || starMap)) { - nameParts = name.split('/'); - - outerLoop: for (i = nameParts.length; i > 0; i -= 1) { - nameSegment = nameParts.slice(0, i).join('/'); - - if (baseParts) { - //Find the longest baseName segment match in the config. - //So, do joins on the biggest to smallest lengths of baseParts. - for (j = baseParts.length; j > 0; j -= 1) { - mapValue = getOwn(map, baseParts.slice(0, j).join('/')); - - //baseName segment has config, find if it has one for - //this name. - if (mapValue) { - mapValue = getOwn(mapValue, nameSegment); - if (mapValue) { - //Match, update name to the new value. - foundMap = mapValue; - foundI = i; - break outerLoop; - } - } - } - } - - //Check for a star map match, but just hold on to it, - //if there is a shorter segment match later in a matching - //config, then favor over this star map. - if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { - foundStarMap = getOwn(starMap, nameSegment); - starI = i; - } - } - - if (!foundMap && foundStarMap) { - foundMap = foundStarMap; - foundI = starI; - } - - if (foundMap) { - nameParts.splice(0, foundI, foundMap); - name = nameParts.join('/'); - } - } - - // If the name points to a package's name, use - // the package main instead. - pkgMain = getOwn(config.pkgs, name); + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id) - return pkgMain ? pkgMain : name; + if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]) } - - function removeScript(name) { - if (isBrowser) { - each(scripts(), function (scriptNode) { - if (scriptNode.getAttribute('data-requiremodule') === name && - scriptNode.getAttribute('data-requirecontext') === context.contextName) { - scriptNode.parentNode.removeChild(scriptNode); - return true; - } - }); - } + } else { + mod = getModule(depMap) + if (mod.error && name === 'error') { + fn(mod.error) + } else { + mod.on(name, fn) } + } + } - function hasPathFallback(id) { - var pathConfig = getOwn(config.paths, id); - if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { - //Pop off the first array value, since it failed, and - //retry - pathConfig.shift(); - context.require.undef(id); - - //Custom require that does not do map translation, since - //ID is "absolute", already mapped/resolved. - context.makeRequire(null, { - skipMap: true - })([id]); - - return true; + function onError(err, errback) { + var ids = err.requireModules, + notified = false + + if (errback) { + errback(err) + } else { + each(ids, function (id) { + var mod = getOwn(registry, id) + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err + if (mod.events.error) { + notified = true + mod.emit('error', err) } - } + } + }) - //Turns a plugin!resource to [plugin, resource] - //with the plugin being undefined if the name - //did not have a plugin prefix. - function splitPrefix(name) { - var prefix, - index = name ? name.indexOf('!') : -1; - if (index > -1) { - prefix = name.substring(0, index); - name = name.substring(index + 1, name.length); - } - return [prefix, name]; + if (!notified) { + req.onError(err) } + } + } - /** - * Creates a module mapping that includes plugin prefix, module - * name, and path. If parentModuleMap is provided it will - * also normalize the name via require.normalize() - * - * @param {String} name the module name - * @param {String} [parentModuleMap] parent module map - * for the module name, used to resolve relative names. - * @param {Boolean} isNormalized: is the ID already normalized. - * This is true if this call is done for a define() module ID. - * @param {Boolean} applyMap: apply the map config to the ID. - * Should only be true if this map is for a dependency. - * - * @returns {Object} - */ - function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { - var url, pluginModule, suffix, nameParts, - prefix = null, - parentName = parentModuleMap ? parentModuleMap.name : null, - originalName = name, - isDefine = true, - normalizedName = ''; - - //If no name, then it means it is a require call, generate an - //internal name. - if (!name) { - isDefine = false; - name = '_@r' + (requireCounter += 1); - } - - nameParts = splitPrefix(name); - prefix = nameParts[0]; - name = nameParts[1]; - - if (prefix) { - prefix = normalize(prefix, parentName, applyMap); - pluginModule = getOwn(defined, prefix); - } - - //Account for relative paths if there is a base name. - if (name) { - if (prefix) { - if (pluginModule && pluginModule.normalize) { - //Plugin is loaded, use its normalize method. - normalizedName = pluginModule.normalize(name, function (name) { - return normalize(name, parentName, applyMap); - }); - } else { - // If nested plugin references, then do not try to - // normalize, as it will not normalize correctly. This - // places a restriction on resourceIds, and the longer - // term solution is not to normalize until plugins are - // loaded and all normalizations to allow for async - // loading of a loader plugin. But for now, fixes the - // common uses. Details in #1131 - normalizedName = name.indexOf('!') === -1 ? - normalize(name, parentName, applyMap) : - name; - } - } else { - //A regular module. - normalizedName = normalize(name, parentName, applyMap); - - //Normalized name may be a plugin ID due to map config - //application in normalize. The map config values must - //already be normalized, so do not need to redo that part. - nameParts = splitPrefix(normalizedName); - prefix = nameParts[0]; - normalizedName = nameParts[1]; - isNormalized = true; - - url = context.nameToUrl(normalizedName); - } - } + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, [defQueue.length, 0].concat(globalDefQueue)) + globalDefQueue = [] + } + } - //If the id is a plugin id that cannot be determined if it needs - //normalization, stamp it with a unique ID so two matching relative - //ids that may conflict can be separate. - suffix = prefix && !pluginModule && !isNormalized ? - '_unnormalized' + (unnormalizedCounter += 1) : - ''; - - return { - prefix: prefix, - name: normalizedName, - parentMap: parentModuleMap, - unnormalized: !!suffix, - url: url, - originalName: originalName, - isDefine: isDefine, - id: (prefix ? - prefix + '!' + normalizedName : - normalizedName) + suffix - }; + handlers = { + require: function (mod) { + if (mod.require) { + return mod.require + } else { + return (mod.require = context.makeRequire(mod.map)) } - - function getModule(depMap) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (!mod) { - mod = registry[id] = new context.Module(depMap); - } - - return mod; + }, + exports: function (mod) { + mod.usingExports = true + if (mod.map.isDefine) { + if (mod.exports) { + return (defined[mod.map.id] = mod.exports) + } else { + return (mod.exports = defined[mod.map.id] = {}) + } } - - function on(depMap, name, fn) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (hasProp(defined, id) && - (!mod || mod.defineEmitComplete)) { - if (name === 'defined') { - fn(defined[id]); - } - } else { - mod = getModule(depMap); - if (mod.error && name === 'error') { - fn(mod.error); - } else { - mod.on(name, fn); - } - } + }, + module: function (mod) { + if (mod.module) { + return mod.module + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return getOwn(config.config, mod.map.id) || {} + }, + exports: mod.exports || (mod.exports = {}), + }) } + }, + } - function onError(err, errback) { - var ids = err.requireModules, - notified = false; + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id] + delete enabledRegistry[id] + } - if (errback) { - errback(err); + function breakCycle(mod, traced, processed) { + var id = mod.map.id + + if (mod.error) { + mod.emit('error', mod.error) + } else { + traced[id] = true + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId) + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]) + mod.check() //pass false? } else { - each(ids, function (id) { - var mod = getOwn(registry, id); - if (mod) { - //Set error on module, so it skips timeout checks. - mod.error = err; - if (mod.events.error) { - notified = true; - mod.emit('error', err); - } - } - }); - - if (!notified) { - req.onError(err); - } + breakCycle(dep, traced, processed) } - } + } + }) + processed[id] = true + } + } - /** - * Internal method to transfer globalQueue items to this context's - * defQueue. - */ - function takeGlobalQueue() { - //Push all the globalDefQueue items into the context's defQueue - if (globalDefQueue.length) { - //Array splice in the values since the context code has a - //local var ref to defQueue, so cannot just reassign the one - //on context. - apsp.apply(defQueue, - [defQueue.length, 0].concat(globalDefQueue)); - globalDefQueue = []; - } + function checkLoaded() { + var err, + usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && context.startTime + waitInterval < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return + } + + inCheckLoaded = true + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + var map = mod.map, + modId = map.id + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return } - handlers = { - 'require': function (mod) { - if (mod.require) { - return mod.require; - } else { - return (mod.require = context.makeRequire(mod.map)); - } - }, - 'exports': function (mod) { - mod.usingExports = true; - if (mod.map.isDefine) { - if (mod.exports) { - return (defined[mod.map.id] = mod.exports); - } else { - return (mod.exports = defined[mod.map.id] = {}); - } - } - }, - 'module': function (mod) { - if (mod.module) { - return mod.module; - } else { - return (mod.module = { - id: mod.map.id, - uri: mod.map.url, - config: function () { - return getOwn(config.config, mod.map.id) || {}; - }, - exports: mod.exports || (mod.exports = {}) - }); - } - } - }; - - function cleanRegistry(id) { - //Clean up machinery used for waiting modules. - delete registry[id]; - delete enabledRegistry[id]; + if (!map.isDefine) { + reqCalls.push(mod) } - function breakCycle(mod, traced, processed) { - var id = mod.map.id; - - if (mod.error) { - mod.emit('error', mod.error); + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true + stillLoading = true } else { - traced[id] = true; - each(mod.depMaps, function (depMap, i) { - var depId = depMap.id, - dep = getOwn(registry, depId); - - //Only force things that have not completed - //being defined, so still in the registry, - //and only if it has not been matched up - //in the module already. - if (dep && !mod.depMatched[i] && !processed[depId]) { - if (getOwn(traced, depId)) { - mod.defineDep(i, defined[depId]); - mod.check(); //pass false? - } else { - breakCycle(dep, traced, processed); - } - } - }); - processed[id] = true; - } - } - - function checkLoaded() { - var err, usingPathFallback, - waitInterval = config.waitSeconds * 1000, - //It is possible to disable the wait interval by using waitSeconds of 0. - expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), - noLoads = [], - reqCalls = [], - stillLoading = false, - needCycleCheck = true; - - //Do not bother if this call was a result of a cycle break. - if (inCheckLoaded) { - return; - } - - inCheckLoaded = true; - - //Figure out the state of all the modules. - eachProp(enabledRegistry, function (mod) { - var map = mod.map, - modId = map.id; - - //Skip things that are not enabled or in error state. - if (!mod.enabled) { - return; - } - - if (!map.isDefine) { - reqCalls.push(mod); - } - - if (!mod.error) { - //If the module should be executed, and it has not - //been inited and time is up, remember it. - if (!mod.inited && expired) { - if (hasPathFallback(modId)) { - usingPathFallback = true; - stillLoading = true; - } else { - noLoads.push(modId); - removeScript(modId); - } - } else if (!mod.inited && mod.fetched && map.isDefine) { - stillLoading = true; - if (!map.prefix) { - //No reason to keep looking for unfinished - //loading. If the only stillLoading is a - //plugin resource though, keep going, - //because it may be that a plugin resource - //is waiting on a non-plugin cycle. - return (needCycleCheck = false); - } - } - } - }); - - if (expired && noLoads.length) { - //If wait time expired, throw error of unloaded modules. - err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); - err.contextName = context.contextName; - return onError(err); - } - - //Not expired, check for a cycle. - if (needCycleCheck) { - each(reqCalls, function (mod) { - breakCycle(mod, {}, {}); - }); + noLoads.push(modId) + removeScript(modId) } - - //If still waiting on loads, and the waiting load is something - //other than a plugin resource, or there are still outstanding - //scripts, then just try back later. - if ((!expired || usingPathFallback) && stillLoading) { - //Something is still waiting to load. Wait for it, but only - //if a timeout is not already in effect. - if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { - checkLoadedTimeoutId = setTimeout(function () { - checkLoadedTimeoutId = 0; - checkLoaded(); - }, 50); - } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false) } - - inCheckLoaded = false; + } + } + }) + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads) + err.contextName = context.contextName + return onError(err) + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}) + }) + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0 + checkLoaded() + }, 50) } + } - Module = function (map) { - this.events = getOwn(undefEvents, map.id) || {}; - this.map = map; - this.shim = getOwn(config.shim, map.id); - this.depExports = []; - this.depMaps = []; - this.depMatched = []; - this.pluginMaps = {}; - this.depCount = 0; - - /* this.exports this.factory + inCheckLoaded = false + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {} + this.map = map + this.shim = getOwn(config.shim, map.id) + this.depExports = [] + this.depMaps = [] + this.depMatched = [] + this.pluginMaps = {} + this.depCount = 0 + + /* this.exports this.factory this.depMaps = [], this.enabled, this.fetched */ - }; - - Module.prototype = { - init: function (depMaps, factory, errback, options) { - options = options || {}; + } - //Do not do more inits if already done. Can happen if there - //are multiple define calls for the same module. That is not - //a normal, common case, but it is also not unexpected. - if (this.inited) { - return; - } + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {} - this.factory = factory; - - if (errback) { - //Register for errors on this module. - this.on('error', errback); - } else if (this.events.error) { - //If no errback already, but there are error listeners - //on this module, set up an errback to pass to the deps. - errback = bind(this, function (err) { - this.emit('error', err); - }); - } + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return + } - //Do a copy of the dependency array, so that - //source inputs are not modified. For example - //"shim" deps are passed in here directly, and - //doing a direct modification of the depMaps array - //would affect that config. - this.depMaps = depMaps && depMaps.slice(0); - - this.errback = errback; - - //Indicate this module has be initialized - this.inited = true; - - this.ignore = options.ignore; - - //Could have option to init this module in enabled mode, - //or could have been previously marked as enabled. However, - //the dependencies are not known until init is called. So - //if enabled previously, now trigger dependencies as enabled. - if (options.enabled || this.enabled) { - //Enable this module and dependencies. - //Will call this.check() - this.enable(); - } else { - this.check(); - } - }, + this.factory = factory + + if (errback) { + //Register for errors on this module. + this.on('error', errback) + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err) + }) + } - defineDep: function (i, depExports) { - //Because of cycles, defined callback for a given - //export can be called more than once. - if (!this.depMatched[i]) { - this.depMatched[i] = true; - this.depCount -= 1; - this.depExports[i] = depExports; - } - }, + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0) + + this.errback = errback + + //Indicate this module has be initialized + this.inited = true + + this.ignore = options.ignore + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable() + } else { + this.check() + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true + this.depCount -= 1 + this.depExports[i] = depExports + } + }, - fetch: function () { - if (this.fetched) { - return; - } - this.fetched = true; - - context.startTime = (new Date()).getTime(); - - var map = this.map; - - //If the manager is for a plugin managed resource, - //ask the plugin to load it now. - if (this.shim) { - context.makeRequire(this.map, { - enableBuildCallback: true - })(this.shim.deps || [], bind(this, function () { - return map.prefix ? this.callPlugin() : this.load(); - })); - } else { - //Regular dependency. - return map.prefix ? this.callPlugin() : this.load(); - } - }, + fetch: function () { + if (this.fetched) { + return + } + this.fetched = true + + context.startTime = new Date().getTime() + + var map = this.map + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true, + })( + this.shim.deps || [], + bind(this, function () { + return map.prefix ? this.callPlugin() : this.load() + }) + ) + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load() + } + }, - load: function () { - var url = this.map.url; + load: function () { + var url = this.map.url - //Regular dependency. - if (!urlFetched[url]) { - urlFetched[url] = true; - context.load(this.map.id, url); - } - }, + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true + context.load(this.map.id, url) + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return + } - /** - * Checks if the module is ready to define itself, and if so, - * define it. - */ - check: function () { - if (!this.enabled || this.enabling) { - return; + var err, + cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory + + if (!this.inited) { + this.fetch() + } else if (this.error) { + this.emit('error', this.error) + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. However, + //only do it for define()'d modules. require + //errbacks should not be called for failures in + //their callbacks (#699). However if a global + //onError is set, use that. + if ((this.events.error && this.map.isDefine) || req.onError !== defaultOnError) { + try { + exports = context.execCb(id, factory, depExports, exports) + } catch (e) { + err = e } - - var err, cjsModule, - id = this.map.id, - depExports = this.depExports, - exports = this.exports, - factory = this.factory; - - if (!this.inited) { - this.fetch(); - } else if (this.error) { - this.emit('error', this.error); - } else if (!this.defining) { - //The factory could trigger another require call - //that would result in checking this module to - //define itself again. If already in the process - //of doing that, skip this work. - this.defining = true; - - if (this.depCount < 1 && !this.defined) { - if (isFunction(factory)) { - //If there is an error listener, favor passing - //to that instead of throwing an error. However, - //only do it for define()'d modules. require - //errbacks should not be called for failures in - //their callbacks (#699). However if a global - //onError is set, use that. - if ((this.events.error && this.map.isDefine) || - req.onError !== defaultOnError) { - try { - exports = context.execCb(id, factory, depExports, exports); - } catch (e) { - err = e; - } - } else { - exports = context.execCb(id, factory, depExports, exports); - } - - // Favor return value over exports. If node/cjs in play, - // then will not have a return value anyway. Favor - // module.exports assignment over exports object. - if (this.map.isDefine && exports === undefined) { - cjsModule = this.module; - if (cjsModule) { - exports = cjsModule.exports; - } else if (this.usingExports) { - //exports already set the defined value. - exports = this.exports; - } - } - - if (err) { - err.requireMap = this.map; - err.requireModules = this.map.isDefine ? [this.map.id] : null; - err.requireType = this.map.isDefine ? 'define' : 'require'; - return onError((this.error = err)); - } - - } else { - //Just a literal value - exports = factory; - } - - this.exports = exports; - - if (this.map.isDefine && !this.ignore) { - defined[id] = exports; - - if (req.onResourceLoad) { - req.onResourceLoad(context, this.map, this.depMaps); - } - } - - //Clean up - cleanRegistry(id); - - this.defined = true; - } - - //Finished the define stage. Allow calling check again - //to allow define notifications below in the case of a - //cycle. - this.defining = false; - - if (this.defined && !this.defineEmitted) { - this.defineEmitted = true; - this.emit('defined', this.exports); - this.defineEmitComplete = true; - } - + } else { + exports = context.execCb(id, factory, depExports, exports) + } + + // Favor return value over exports. If node/cjs in play, + // then will not have a return value anyway. Favor + // module.exports assignment over exports object. + if (this.map.isDefine && exports === undefined) { + cjsModule = this.module + if (cjsModule) { + exports = cjsModule.exports + } else if (this.usingExports) { + //exports already set the defined value. + exports = this.exports } - }, + } + + if (err) { + err.requireMap = this.map + err.requireModules = this.map.isDefine ? [this.map.id] : null + err.requireType = this.map.isDefine ? 'define' : 'require' + return onError((this.error = err)) + } + } else { + //Just a literal value + exports = factory + } - callPlugin: function () { - var map = this.map, - id = map.id, - //Map already normalized the prefix. - pluginMap = makeModuleMap(map.prefix); + this.exports = exports - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(pluginMap); - - on(pluginMap, 'defined', bind(this, function (plugin) { - var load, normalizedMap, normalizedMod, - bundleId = getOwn(bundlesMap, this.map.id), - name = this.map.name, - parentName = this.map.parentMap ? this.map.parentMap.name : null, - localRequire = context.makeRequire(map.parentMap, { - enableBuildCallback: true - }); - - //If current map is not normalized, wait for that - //normalized name to load instead of continuing. - if (this.map.unnormalized) { - //Normalize the ID if the plugin allows it. - if (plugin.normalize) { - name = plugin.normalize(name, function (name) { - return normalize(name, parentName, true); - }) || ''; - } - - //prefix and name should already be normalized, no need - //for applying map config again either. - normalizedMap = makeModuleMap(map.prefix + '!' + name, - this.map.parentMap); - on(normalizedMap, - 'defined', bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true, - ignore: true - }); - })); - - normalizedMod = getOwn(registry, normalizedMap.id); - if (normalizedMod) { - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(normalizedMap); - - if (this.events.error) { - normalizedMod.on('error', bind(this, function (err) { - this.emit('error', err); - })); - } - normalizedMod.enable(); - } - - return; - } + if (this.map.isDefine && !this.ignore) { + defined[id] = exports - //If a paths config, then just load that file instead to - //resolve the plugin, as it is built into that paths layer. - if (bundleId) { - this.map.url = context.nameToUrl(bundleId); - this.load(); - return; - } + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps) + } + } - load = bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true - }); - }); - - load.error = bind(this, function (err) { - this.inited = true; - this.error = err; - err.requireModules = [id]; - - //Remove temp unnormalized modules for this module, - //since they will never be resolved otherwise now. - eachProp(registry, function (mod) { - if (mod.map.id.indexOf(id + '_unnormalized') === 0) { - cleanRegistry(mod.map.id); - } - }); - - onError(err); - }); - - //Allow plugins to load other code without having to know the - //context or how to 'complete' the load. - load.fromText = bind(this, function (text, textAlt) { - /*jslint evil: true */ - var moduleName = map.name, - moduleMap = makeModuleMap(moduleName), - hasInteractive = useInteractive; - - //As of 2.1.0, support just passing the text, to reinforce - //fromText only being called once per resource. Still - //support old style of passing moduleName but discard - //that moduleName in favor of the internal ref. - if (textAlt) { - text = textAlt; - } - - //Turn off interactive script matching for IE for any define - //calls in the text, then turn it back on at the end. - if (hasInteractive) { - useInteractive = false; - } - - //Prime the system by creating a module instance for - //it. - getModule(moduleMap); - - //Transfer any config to this other module. - if (hasProp(config.config, id)) { - config.config[moduleName] = config.config[id]; - } - - try { - req.exec(text); - } catch (e) { - return onError(makeError('fromtexteval', - 'fromText eval for ' + id + - ' failed: ' + e, - e, - [id])); - } - - if (hasInteractive) { - useInteractive = true; - } - - //Mark this as a dependency for the plugin - //resource - this.depMaps.push(moduleMap); - - //Support anonymous modules. - context.completeLoad(moduleName); - - //Bind the value of that module to the value for this - //resource ID. - localRequire([moduleName], load); - }); - - //Use parentName here since the plugin's name is not reliable, - //could be some weird string with no path that actually wants to - //reference the parentName's path. - plugin.load(map.name, localRequire, load, config); - })); - - context.enable(pluginMap, this); - this.pluginMaps[pluginMap.id] = pluginMap; - }, + //Clean up + cleanRegistry(id) - enable: function () { - enabledRegistry[this.map.id] = this; - this.enabled = true; - - //Set flag mentioning that the module is enabling, - //so that immediate calls to the defined callbacks - //for dependencies do not trigger inadvertent load - //with the depCount still being zero. - this.enabling = true; - - //Enable each dependency - each(this.depMaps, bind(this, function (depMap, i) { - var id, mod, handler; - - if (typeof depMap === 'string') { - //Dependency needs to be converted to a depMap - //and wired up to this module. - depMap = makeModuleMap(depMap, - (this.map.isDefine ? this.map : this.map.parentMap), - false, - !this.skipMap); - this.depMaps[i] = depMap; - - handler = getOwn(handlers, depMap.id); - - if (handler) { - this.depExports[i] = handler(this); - return; - } - - this.depCount += 1; - - on(depMap, 'defined', bind(this, function (depExports) { - this.defineDep(i, depExports); - this.check(); - })); - - if (this.errback) { - on(depMap, 'error', bind(this, this.errback)); - } else if (this.events.error) { - // No direct errback on this module, but something - // else is listening for errors, so be sure to - // propagate the error correctly. - on(depMap, 'error', bind(this, function(err) { - this.emit('error', err); - })); - } - } + this.defined = true + } - id = depMap.id; - mod = registry[id]; + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false - //Skip special modules like 'require', 'exports', 'module' - //Also, don't call enable if it is already enabled, - //important in circular dependency cases. - if (!hasProp(handlers, id) && mod && !mod.enabled) { - context.enable(depMap, this); - } - })); - - //Enable each plugin that is used in - //a dependency - eachProp(this.pluginMaps, bind(this, function (pluginMap) { - var mod = getOwn(registry, pluginMap.id); - if (mod && !mod.enabled) { - context.enable(pluginMap, this); + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true + this.emit('defined', this.exports) + this.defineEmitComplete = true + } + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix) + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap) + + on( + pluginMap, + 'defined', + bind(this, function (plugin) { + var load, + normalizedMap, + normalizedMod, + bundleId = getOwn(bundlesMap, this.map.id), + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true, + }) + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = + plugin.normalize(name, function (name) { + return normalize(name, parentName, true) + }) || '' + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, this.map.parentMap) + on( + normalizedMap, + 'defined', + bind(this, function (value) { + this.init( + [], + function () { + return value + }, + null, + { + enabled: true, + ignore: true, } - })); - - this.enabling = false; - - this.check(); - }, + ) + }) + ) - on: function (name, cb) { - var cbs = this.events[name]; - if (!cbs) { - cbs = this.events[name] = []; + normalizedMod = getOwn(registry, normalizedMap.id) + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap) + + if (this.events.error) { + normalizedMod.on( + 'error', + bind(this, function (err) { + this.emit('error', err) + }) + ) } - cbs.push(cb); - }, + normalizedMod.enable() + } - emit: function (name, evt) { - each(this.events[name], function (cb) { - cb(evt); - }); - if (name === 'error') { - //Now that the error handler was triggered, remove - //the listeners, since this broken Module instance - //can stay around for a while in the registry. - delete this.events[name]; - } + return } - }; - function callGetModule(args) { - //Skip modules already defined. - if (!hasProp(defined, args[0])) { - getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + //If a paths config, then just load that file instead to + //resolve the plugin, as it is built into that paths layer. + if (bundleId) { + this.map.url = context.nameToUrl(bundleId) + this.load() + return } - } - function removeListener(node, func, name, ieName) { - //Favor detachEvent because of IE9 - //issue, see attachEvent/addEventListener comment elsewhere - //in this file. - if (node.detachEvent && !isOpera) { - //Probably IE. If not it will throw an error, which will be - //useful to know. - if (ieName) { - node.detachEvent(ieName, func); + load = bind(this, function (value) { + this.init( + [], + function () { + return value + }, + null, + { + enabled: true, } - } else { - node.removeEventListener(name, func, false); - } - } - - /** - * Given an event from a script node, get the requirejs info from it, - * and then removes the event listeners on the node. - * @param {Event} evt - * @returns {Object} - */ - function getScriptData(evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - var node = evt.currentTarget || evt.srcElement; - - //Remove the listeners once here. - removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); - removeListener(node, context.onScriptError, 'error'); - - return { - node: node, - id: node && node.getAttribute('data-requiremodule') - }; - } - - function intakeDefines() { - var args; - - //Any defined modules in the global queue, intake them now. - takeGlobalQueue(); - - //Make sure any remaining defQueue items get properly processed. - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); - } else { - //args are id, deps, factory. Should be normalized by the - //define() function. - callGetModule(args); + ) + }) + + load.error = bind(this, function (err) { + this.inited = true + this.error = err + err.requireModules = [id] + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id) } + }) + + onError(err) + }) + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap) + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id] + } + + try { + req.exec(text) + } catch (e) { + return onError(makeError('fromtexteval', 'fromText eval for ' + id + ' failed: ' + e, e, [id])) + } + + if (hasInteractive) { + useInteractive = true + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap) + + //Support anonymous modules. + context.completeLoad(moduleName) + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load) + }) + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config) + }) + ) + + context.enable(pluginMap, this) + this.pluginMaps[pluginMap.id] = pluginMap + }, + + enable: function () { + enabledRegistry[this.map.id] = this + this.enabled = true + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true + + //Enable each dependency + each( + this.depMaps, + bind(this, function (depMap, i) { + var id, mod, handler + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, this.map.isDefine ? this.map : this.map.parentMap, false, !this.skipMap) + this.depMaps[i] = depMap + + handler = getOwn(handlers, depMap.id) + + if (handler) { + this.depExports[i] = handler(this) + return + } + + this.depCount += 1 + + on( + depMap, + 'defined', + bind(this, function (depExports) { + this.defineDep(i, depExports) + this.check() + }) + ) + + if (this.errback) { + on(depMap, 'error', bind(this, this.errback)) + } else if (this.events.error) { + // No direct errback on this module, but something + // else is listening for errors, so be sure to + // propagate the error correctly. + on( + depMap, + 'error', + bind(this, function (err) { + this.emit('error', err) + }) + ) + } } - } - - context = { - config: config, - contextName: contextName, - registry: registry, - defined: defined, - urlFetched: urlFetched, - defQueue: defQueue, - Module: Module, - makeModuleMap: makeModuleMap, - nextTick: req.nextTick, - onError: onError, - - /** - * Set a configuration for the context. - * @param {Object} cfg config object to integrate. - */ - configure: function (cfg) { - //Make sure the baseUrl ends in a slash. - if (cfg.baseUrl) { - if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { - cfg.baseUrl += '/'; - } - } - //Save off the paths since they require special processing, - //they are additive. - var shim = config.shim, - objs = { - paths: true, - bundles: true, - config: true, - map: true - }; - - eachProp(cfg, function (value, prop) { - if (objs[prop]) { - if (!config[prop]) { - config[prop] = {}; - } - mixin(config[prop], value, true, true); - } else { - config[prop] = value; - } - }); - - //Reverse map the bundles - if (cfg.bundles) { - eachProp(cfg.bundles, function (value, prop) { - each(value, function (v) { - if (v !== prop) { - bundlesMap[v] = prop; - } - }); - }); - } + id = depMap.id + mod = registry[id] - //Merge shim - if (cfg.shim) { - eachProp(cfg.shim, function (value, id) { - //Normalize the structure - if (isArray(value)) { - value = { - deps: value - }; - } - if ((value.exports || value.init) && !value.exportsFn) { - value.exportsFn = context.makeShimExports(value); - } - shim[id] = value; - }); - config.shim = shim; - } + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this) + } + }) + ) + + //Enable each plugin that is used in + //a dependency + eachProp( + this.pluginMaps, + bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id) + if (mod && !mod.enabled) { + context.enable(pluginMap, this) + } + }) + ) - //Adjust packages if necessary. - if (cfg.packages) { - each(cfg.packages, function (pkgObj) { - var location, name; - - pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; - - name = pkgObj.name; - location = pkgObj.location; - if (location) { - config.paths[name] = pkgObj.location; - } - - //Save pointer to main module ID for pkg name. - //Remove leading dot in main, so main paths are normalized, - //and remove any trailing .js, since different package - //envs have different conventions: some use a module name, - //some use a file name. - config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') - .replace(currDirRegExp, '') - .replace(jsSuffixRegExp, ''); - }); - } + this.enabling = false - //If there are any "waiting to execute" modules in the registry, - //update the maps for them, since their info, like URLs to load, - //may have changed. - eachProp(registry, function (mod, id) { - //If module already has init called, since it is too - //late to modify them, and ignore unnormalized ones - //since they are transient. - if (!mod.inited && !mod.map.unnormalized) { - mod.map = makeModuleMap(id); - } - }); + this.check() + }, - //If a deps array or a config callback is specified, then call - //require with those args. This is useful when require is defined as a - //config object before require.js is loaded. - if (cfg.deps || cfg.callback) { - context.require(cfg.deps || [], cfg.callback); - } - }, + on: function (name, cb) { + var cbs = this.events[name] + if (!cbs) { + cbs = this.events[name] = [] + } + cbs.push(cb) + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt) + }) + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name] + } + }, + } - makeShimExports: function (value) { - function fn() { - var ret; - if (value.init) { - ret = value.init.apply(global, arguments); - } - return ret || (value.exports && getGlobal(value.exports)); - } - return fn; - }, + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]) + } + } - makeRequire: function (relMap, options) { - options = options || {}; + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func) + } + } else { + node.removeEventListener(name, func, false) + } + } - function localRequire(deps, callback, errback) { - var id, map, requireMod; + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange') + removeListener(node, context.onScriptError, 'error') + + return { + node: node, + id: node && node.getAttribute('data-requiremodule'), + } + } - if (options.enableBuildCallback && callback && isFunction(callback)) { - callback.__requireJsBuild = true; - } + function intakeDefines() { + var args + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue() + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift() + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])) + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args) + } + } + } - if (typeof deps === 'string') { - if (isFunction(callback)) { - //Invalid call - return onError(makeError('requireargs', 'Invalid require call'), errback); - } - - //If require|exports|module are requested, get the - //value for them from the special handlers. Caveat: - //this only works while module is being defined. - if (relMap && hasProp(handlers, deps)) { - return handlers[deps](registry[relMap.id]); - } - - //Synchronous access to one module. If require.get is - //available (as in the Node adapter), prefer that. - if (req.get) { - return req.get(context, deps, relMap, localRequire); - } - - //Normalize module name, if it contains . or .. - map = makeModuleMap(deps, relMap, false, true); - id = map.id; - - if (!hasProp(defined, id)) { - return onError(makeError('notloaded', 'Module name "' + - id + - '" has not been loaded yet for context: ' + - contextName + - (relMap ? '' : '. Use require([])'))); - } - return defined[id]; - } + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/' + } + } - //Grab defines waiting in the global queue. - intakeDefines(); + //Save off the paths since they require special processing, + //they are additive. + var shim = config.shim, + objs = { + paths: true, + bundles: true, + config: true, + map: true, + } + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (!config[prop]) { + config[prop] = {} + } + mixin(config[prop], value, true, true) + } else { + config[prop] = value + } + }) + + //Reverse map the bundles + if (cfg.bundles) { + eachProp(cfg.bundles, function (value, prop) { + each(value, function (v) { + if (v !== prop) { + bundlesMap[v] = prop + } + }) + }) + } - //Mark all the dependencies as needing to be loaded. - context.nextTick(function () { - //Some defines could have been added since the - //require call, collect them. - intakeDefines(); + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value, + } + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value) + } + shim[id] = value + }) + config.shim = shim + } - requireMod = getModule(makeModuleMap(null, relMap)); + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location, name - //Store if map config should be applied to this require - //call for dependencies. - requireMod.skipMap = options.skipMap; + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj - requireMod.init(deps, callback, errback, { - enabled: true - }); + name = pkgObj.name + location = pkgObj.location + if (location) { + config.paths[name] = pkgObj.location + } - checkLoaded(); - }); + //Save pointer to main module ID for pkg name. + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + config.pkgs[name] = + pkgObj.name + '/' + (pkgObj.main || 'main').replace(currDirRegExp, '').replace(jsSuffixRegExp, '') + }) + } - return localRequire; - } + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id) + } + }) + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback) + } + }, + + makeShimExports: function (value) { + function fn() { + var ret + if (value.init) { + ret = value.init.apply(global, arguments) + } + return ret || (value.exports && getGlobal(value.exports)) + } + return fn + }, - mixin(localRequire, { - isBrowser: isBrowser, - - /** - * Converts a module name + .extension into an URL path. - * *Requires* the use of a module name. It does not support using - * plain URLs like nameToUrl. - */ - toUrl: function (moduleNamePlusExt) { - var ext, - index = moduleNamePlusExt.lastIndexOf('.'), - segment = moduleNamePlusExt.split('/')[0], - isRelative = segment === '.' || segment === '..'; - - //Have a file extension alias, and it is not the - //dots from a relative path. - if (index !== -1 && (!isRelative || index > 1)) { - ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); - moduleNamePlusExt = moduleNamePlusExt.substring(0, index); - } - - return context.nameToUrl(normalize(moduleNamePlusExt, - relMap && relMap.id, true), ext, true); - }, + makeRequire: function (relMap, options) { + options = options || {} - defined: function (id) { - return hasProp(defined, makeModuleMap(id, relMap, false, true).id); - }, + function localRequire(deps, callback, errback) { + var id, map, requireMod - specified: function (id) { - id = makeModuleMap(id, relMap, false, true).id; - return hasProp(defined, id) || hasProp(registry, id); - } - }); - - //Only allow undef on top level require calls - if (!relMap) { - localRequire.undef = function (id) { - //Bind any waiting define() calls to this context, - //fix for #408 - takeGlobalQueue(); - - var map = makeModuleMap(id, relMap, true), - mod = getOwn(registry, id); - - removeScript(id); - - delete defined[id]; - delete urlFetched[map.url]; - delete undefEvents[id]; - - //Clean queued defines too. Go backwards - //in array so that the splices do not - //mess up the iteration. - eachReverse(defQueue, function(args, i) { - if(args[0] === id) { - defQueue.splice(i, 1); - } - }); - - if (mod) { - //Hold on to listeners in case the - //module will be attempted to be reloaded - //using a different config. - if (mod.events.defined) { - undefEvents[id] = mod.events; - } - - cleanRegistry(id); - } - }; - } + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true + } - return localRequire; - }, + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback) + } - /** - * Called to enable a module if it is still in the registry - * awaiting enablement. A second arg, parent, the parent module, - * is passed in for context, when this method is overridden by - * the optimizer. Not shown here to keep code compact. - */ - enable: function (depMap) { - var mod = getOwn(registry, depMap.id); - if (mod) { - getModule(depMap).enable(); - } - }, + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]) + } - /** - * Internal method used by environment adapters to complete a load event. - * A load event could be a script load or just a load pass from a synchronous - * load call. - * @param {String} moduleName the name of the module to potentially complete. - */ - completeLoad: function (moduleName) { - var found, args, mod, - shim = getOwn(config.shim, moduleName) || {}, - shExports = shim.exports; - - takeGlobalQueue(); - - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - args[0] = moduleName; - //If already found an anonymous module and bound it - //to this name, then this is some other anon module - //waiting for its completeLoad to fire. - if (found) { - break; - } - found = true; - } else if (args[0] === moduleName) { - //Found matching define call for this script! - found = true; - } + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire) + } - callGetModule(args); - } + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true) + id = map.id + + if (!hasProp(defined, id)) { + return onError( + makeError( + 'notloaded', + 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])') + ) + ) + } + return defined[id] + } - //Do this after the cycle of callGetModule in case the result - //of those calls/init calls changes the registry. - mod = getOwn(registry, moduleName); - - if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { - if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { - if (hasPathFallback(moduleName)) { - return; - } else { - return onError(makeError('nodefine', - 'No define call for ' + moduleName, - null, - [moduleName])); - } - } else { - //A script that does not call define(), so just simulate - //the call for it. - callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); - } - } + //Grab defines waiting in the global queue. + intakeDefines() - checkLoaded(); - }, + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines() - /** - * Converts a module name to a file path. Supports cases where - * moduleName may actually be just an URL. - * Note that it **does not** call normalize on the moduleName, - * it is assumed to have already been normalized. This is an - * internal API, not a public one. Use toUrl for the public API. - */ - nameToUrl: function (moduleName, ext, skipExt) { - var paths, syms, i, parentModule, url, - parentPath, bundleId, - pkgMain = getOwn(config.pkgs, moduleName); - - if (pkgMain) { - moduleName = pkgMain; - } + requireMod = getModule(makeModuleMap(null, relMap)) - bundleId = getOwn(bundlesMap, moduleName); + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap - if (bundleId) { - return context.nameToUrl(bundleId, ext, skipExt); - } + requireMod.init(deps, callback, errback, { + enabled: true, + }) - //If a colon is in the URL, it indicates a protocol is used and it is just - //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) - //or ends with .js, then assume the user meant to use an url and not a module id. - //The slash is important for protocol-less URLs as well as full paths. - if (req.jsExtRegExp.test(moduleName)) { - //Just a plain path, not module name lookup, so just return it. - //Add extension if it is included. This is a bit wonky, only non-.js things pass - //an extension, this method probably needs to be reworked. - url = moduleName + (ext || ''); - } else { - //A module that needs to be converted to a path. - paths = config.paths; - - syms = moduleName.split('/'); - //For each module name segment, see if there is a path - //registered for it. Start with most specific name - //and work up from it. - for (i = syms.length; i > 0; i -= 1) { - parentModule = syms.slice(0, i).join('/'); - - parentPath = getOwn(paths, parentModule); - if (parentPath) { - //If an array, it means there are a few choices, - //Choose the one that is desired - if (isArray(parentPath)) { - parentPath = parentPath[0]; - } - syms.splice(0, i, parentPath); - break; - } - } + checkLoaded() + }) - //Join the path parts together, then figure out if baseUrl is needed. - url = syms.join('/'); - url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); - url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; - } - - return config.urlArgs ? url + - ((url.indexOf('?') === -1 ? '?' : '&') + - config.urlArgs) : url; - }, - - //Delegates to req.load. Broken out as a separate function to - //allow overriding in the optimizer. - load: function (id, url) { - req.load(context, id, url); - }, + return localRequire + } - /** - * Executes a module callback function. Broken out as a separate function - * solely to allow the build system to sequence the files in the built - * layer in the right sequence. - * - * @private - */ - execCb: function (name, callback, args, exports) { - return callback.apply(exports, args); - }, + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..' + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length) + moduleNamePlusExt = moduleNamePlusExt.substring(0, index) + } - /** - * callback for script loads, used to check status of loading. - * - * @param {Event} evt the event from the browser for the script - * that was loaded. - */ - onScriptLoad: function (evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - if (evt.type === 'load' || - (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { - //Reset interactive script so a script node is not held onto for - //to long. - interactiveScript = null; - - //Pull out the name of the module and the context. - var data = getScriptData(evt); - context.completeLoad(data.id); - } - }, + return context.nameToUrl(normalize(moduleNamePlusExt, relMap && relMap.id, true), ext, true) + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id) + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id + return hasProp(defined, id) || hasProp(registry, id) + }, + }) + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue() + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id) + + removeScript(id) + + delete defined[id] + delete urlFetched[map.url] + delete undefEvents[id] + + //Clean queued defines too. Go backwards + //in array so that the splices do not + //mess up the iteration. + eachReverse(defQueue, function (args, i) { + if (args[0] === id) { + defQueue.splice(i, 1) + } + }) + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events + } + + cleanRegistry(id) + } + } + } - /** - * Callback for script errors. - */ - onScriptError: function (evt) { - var data = getScriptData(evt); - if (!hasPathFallback(data.id)) { - return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); - } + return localRequire + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overridden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id) + if (mod) { + getModule(depMap).enable() + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, + args, + mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports + + takeGlobalQueue() + + while (defQueue.length) { + args = defQueue.shift() + if (args[0] === null) { + args[0] = moduleName + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break } - }; + found = true + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true + } - context.require = context.makeRequire(); - return context; - } + callGetModule(args) + } - /** - * Main entry point. - * - * If the only argument to require is a string, then the module that - * is represented by that string is fetched for the appropriate context. - * - * If the first argument is an array, then it will be treated as an array - * of dependency string names to fetch. An optional function callback can - * be specified to execute when all of those dependencies are available. - * - * Make a local req variable to help Caja compliance (it assumes things - * on a require that are not standardized), and to give a short - * name for minification/local scope use. - */ - req = requirejs = function (deps, callback, errback, optional) { - - //Find the right context, use default - var context, config, - contextName = defContextName; - - // Determine if have config object in the call. - if (!isArray(deps) && typeof deps !== 'string') { - // deps is a config object - config = deps; - if (isArray(callback)) { - // Adjust args if there are dependencies - deps = callback; - callback = errback; - errback = optional; + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName) + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return } else { - deps = []; + return onError(makeError('nodefine', 'No define call for ' + moduleName, null, [moduleName])) } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, shim.deps || [], shim.exportsFn]) + } } - if (config && config.context) { - contextName = config.context; + checkLoaded() + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, + syms, + i, + parentModule, + url, + parentPath, + bundleId, + pkgMain = getOwn(config.pkgs, moduleName) + + if (pkgMain) { + moduleName = pkgMain } - context = getOwn(contexts, contextName); - if (!context) { - context = contexts[contextName] = req.s.newContext(contextName); - } + bundleId = getOwn(bundlesMap, moduleName) - if (config) { - context.configure(config); + if (bundleId) { + return context.nameToUrl(bundleId, ext, skipExt) } - return context.require(deps, callback, errback); - }; - - /** - * Support require.config() to make it easier to cooperate with other - * AMD loaders on globally agreed names. - */ - req.config = function (config) { - return req(config); - }; + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || '') + } else { + //A module that needs to be converted to a path. + paths = config.paths + + syms = moduleName.split('/') + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/') + + parentPath = getOwn(paths, parentModule) + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0] + } + syms.splice(0, i, parentPath) + break + } + } - /** - * Execute something after the current tick - * of the event loop. Override for other envs - * that have a better solution than setTimeout. - * @param {Function} fn function to execute later. - */ - req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { - setTimeout(fn, 4); - } : function (fn) { fn(); }; + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/') + url += ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js') + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url + } - /** - * Export require as a global, but only if it does not already exist. - */ - if (!require) { - require = req; + return config.urlArgs ? url + ((url.indexOf('?') === -1 ? '?' : '&') + config.urlArgs) : url + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url) + }, + + /** + * Executes a module callback function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args) + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || readyRegExp.test((evt.currentTarget || evt.srcElement).readyState)) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null + + //Pull out the name of the module and the context. + var data = getScriptData(evt) + context.completeLoad(data.id) + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt) + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])) + } + }, } - req.version = version; - - //Used to filter out dependencies that are already paths. - req.jsExtRegExp = /^\/|:|\?|\.js$/; - req.isBrowser = isBrowser; - s = req.s = { - contexts: contexts, - newContext: newContext - }; - - //Create default context. - req({}); - - //Exports some context-sensitive methods on global require. - each([ - 'toUrl', - 'undef', - 'defined', - 'specified' - ], function (prop) { - //Reference from contexts instead of early binding to default context, - //so that during builds, the latest instance of the default context - //with its config gets used. - req[prop] = function () { - var ctx = contexts[defContextName]; - return ctx.require[prop].apply(ctx, arguments); - }; - }); + context.require = context.makeRequire() + return context + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + //Find the right context, use default + var context, + config, + contextName = defContextName + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback + callback = errback + errback = optional + } else { + deps = [] + } + } - if (isBrowser) { - head = s.head = document.getElementsByTagName('head')[0]; - //If BASE tag is in play, using appendChild is a problem for IE6. - //When that browser dies, this can be removed. Details in this jQuery bug: - //http://dev.jquery.com/ticket/2709 - baseElement = document.getElementsByTagName('base')[0]; - if (baseElement) { - head = s.head = baseElement.parentNode; - } + if (config && config.context) { + contextName = config.context } - /** - * Any errors that require explicitly generates will be passed to this - * function. Intercept/override it if you want custom error handling. - * @param {Error} err the error object. - */ - req.onError = defaultOnError; + context = getOwn(contexts, contextName) + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName) + } - /** - * Creates the node for the load command. Only used in browser envs. - */ - req.createNode = function (config, moduleName, url) { - var node = config.xhtml ? - document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : - document.createElement('script'); - node.type = config.scriptType || 'text/javascript'; - node.charset = 'utf-8'; - node.async = true; - return node; - }; + if (config) { + context.configure(config) + } - /** - * Does the request to load a module for the browser case. - * Make this a separate function to allow other environments - * to override it. - * - * @param {Object} context the require context to find state. - * @param {String} moduleName the name of the module. - * @param {Object} url the URL to the module. - */ - req.load = function (context, moduleName, url) { - var config = (context && context.config) || {}, - node; - if (isBrowser) { - //In the browser so use a script tag - node = req.createNode(config, moduleName, url); - - node.setAttribute('data-requirecontext', context.contextName); - node.setAttribute('data-requiremodule', moduleName); - - //Set up load listener. Test attachEvent first because IE9 has - //a subtle issue in its addEventListener and script onload firings - //that do not match the behavior of all other browsers with - //addEventListener support, which fire the onload event for a - //script right after the script execution. See: - //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution - //UNFORTUNATELY Opera implements attachEvent but does not follow the script - //script execution mode. - if (node.attachEvent && - //Check if node.attachEvent is artificially added by custom script or - //natively supported by browser - //read https://github.com/jrburke/requirejs/issues/187 - //if we can NOT find [native code] then it must NOT natively supported. - //in IE8, node.attachEvent does not have toString() - //Note the test for "[native code" with no closing brace, see: - //https://github.com/jrburke/requirejs/issues/273 - !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && - !isOpera) { - //Probably IE. IE (at least 6-8) do not fire - //script onload right after executing the script, so - //we cannot tie the anonymous define call to a name. - //However, IE reports the script as being in 'interactive' - //readyState at the time of the define call. - useInteractive = true; - - node.attachEvent('onreadystatechange', context.onScriptLoad); - //It would be great to add an error handler here to catch - //404s in IE9+. However, onreadystatechange will fire before - //the error handler, so that does not help. If addEventListener - //is used, then IE will fire error before load, but we cannot - //use that pathway given the connect.microsoft.com issue - //mentioned above about not doing the 'script execute, - //then fire the script load event listener before execute - //next script' that other browsers do. - //Best hope: IE10 fixes the issues, - //and then destroys all installs of IE 6-9. - //node.attachEvent('onerror', context.onScriptError); - } else { - node.addEventListener('load', context.onScriptLoad, false); - node.addEventListener('error', context.onScriptError, false); - } - node.src = url; - - //For some cache cases in IE 6-8, the script executes before the end - //of the appendChild execution, so to tie an anonymous define - //call to the module name (which is stored on the node), hold on - //to a reference to this node, but clear after the DOM insertion. - currentlyAddingScript = node; - if (baseElement) { - head.insertbeforeAll(node, baseElement); - } else { - head.appendChild(node); - } - currentlyAddingScript = null; - - return node; - } else if (isWebWorker) { - try { - //In a web worker, use importScripts. This is not a very - //efficient use of importScripts, importScripts will block until - //its script is downloaded and evaluated. However, if web workers - //are in play, the expectation that a build has been done so that - //only one script needs to be loaded anyway. This may need to be - //reevaluated if other use cases become common. - importScripts(url); - - //Account for anonymous modules - context.completeLoad(moduleName); - } catch (e) { - context.onError(makeError('importscripts', - 'importScripts failed for ' + - moduleName + ' at ' + url, - e, - [moduleName])); - } + return context.require(deps, callback, errback) + } + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config) + } + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = + typeof setTimeout !== 'undefined' + ? function (fn) { + setTimeout(fn, 4) } - }; - - function getInteractiveScript() { - if (interactiveScript && interactiveScript.readyState === 'interactive') { - return interactiveScript; + : function (fn) { + fn() } - eachReverse(scripts(), function (script) { - if (script.readyState === 'interactive') { - return (interactiveScript = script); - } - }); - return interactiveScript; + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req + } + + req.version = version + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/ + req.isBrowser = isBrowser + s = req.s = { + contexts: contexts, + newContext: newContext, + } + + //Create default context. + req({}) + + //Exports some context-sensitive methods on global require. + each(['toUrl', 'undef', 'defined', 'specified'], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName] + return ctx.require[prop].apply(ctx, arguments) } + }) + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0] + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0] + if (baseElement) { + head = s.head = baseElement.parentNode + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = defaultOnError + + /** + * Creates the node for the load command. Only used in browser envs. + */ + req.createNode = function (config, moduleName, url) { + var node = config.xhtml + ? document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') + : document.createElement('script') + node.type = config.scriptType || 'text/javascript' + node.charset = 'utf-8' + node.async = true + return node + } + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node + if (isBrowser) { + //In the browser so use a script tag + node = req.createNode(config, moduleName, url) + + node.setAttribute('data-requirecontext', context.contextName) + node.setAttribute('data-requiremodule', moduleName) + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if ( + node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera + ) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true + + node.attachEvent('onreadystatechange', context.onScriptLoad) + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false) + node.addEventListener('error', context.onScriptError, false) + } + node.src = url + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node + if (baseElement) { + head.insertbeforeAll(node, baseElement) + } else { + head.appendChild(node) + } + currentlyAddingScript = null + + return node + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url) + + //Account for anonymous modules + context.completeLoad(moduleName) + } catch (e) { + context.onError( + makeError('importscripts', 'importScripts failed for ' + moduleName + ' at ' + url, e, [moduleName]) + ) + } + } + } - //Look for a data-main script attribute, which could also adjust the baseUrl. - if (isBrowser && !cfg.skipDataMain) { - //Figure out baseUrl. Get it from the script tag with require.js in it. - eachReverse(scripts(), function (script) { - //Set the 'head' where we can append children by - //using the script's parent. - if (!head) { - head = script.parentNode; - } - - //Look for a data-main attribute to set main script for the page - //to load. If it is there, the path to data main becomes the - //baseUrl, if it is not already set. - dataMain = script.getAttribute('data-main'); - if (dataMain) { - //Preserve dataMain in case it is a path (i.e. contains '?') - mainScript = dataMain; - - //Set final baseUrl if there is not already an explicit one. - if (!cfg.baseUrl) { - //Pull off the directory of data-main for use as the - //baseUrl. - src = mainScript.split('/'); - mainScript = src.pop(); - subPath = src.length ? src.join('/') + '/' : './'; - - cfg.baseUrl = subPath; - } - - //Strip off any trailing .js since mainScript is now - //like a module name. - mainScript = mainScript.replace(jsSuffixRegExp, ''); - - //If mainScript is still a path, fall back to dataMain - if (req.jsExtRegExp.test(mainScript)) { - mainScript = dataMain; - } - - //Put the data-main script in the files to load. - cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; - - return true; - } - }); + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript } - /** - * The function that handles definitions of modules. Differs from - * require() in that a string for the module should be the first argument, - * and the function to execute after dependencies are loaded should - * return a value to define the module corresponding to the first argument's - * name. - */ - define = function (name, deps, callback) { - var node, context; - - //Allow for anonymous modules - if (typeof name !== 'string') { - //Adjust args appropriately - callback = deps; - deps = name; - name = null; + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script) + } + }) + return interactiveScript + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser && !cfg.skipDataMain) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main') + if (dataMain) { + //Preserve dataMain in case it is a path (i.e. contains '?') + mainScript = dataMain + + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = mainScript.split('/') + mainScript = src.pop() + subPath = src.length ? src.join('/') + '/' : './' + + cfg.baseUrl = subPath } - //This module may not have dependencies - if (!isArray(deps)) { - callback = deps; - deps = null; - } + //Strip off any trailing .js since mainScript is now + //like a module name. + mainScript = mainScript.replace(jsSuffixRegExp, '') - //If no name, and callback is a function, then figure out if it a - //CommonJS thing with dependencies. - if (!deps && isFunction(callback)) { - deps = []; - //Remove comments from the callback string, - //look for require calls, and pull them into the dependencies, - //but only if there are function args. - if (callback.length) { - callback - .toString() - .replace(commentRegExp, '') - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - - //May be a CommonJS thing even without require calls, but still - //could use exports, and module. Avoid doing exports and module - //work though if it just needs require. - //REQUIRES the function to expect the CommonJS variables in the - //order listed below. - deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); - } + //If mainScript is still a path, fall back to dataMain + if (req.jsExtRegExp.test(mainScript)) { + mainScript = dataMain } - //If in IE 6-8 and hit an anonymous define() call, do the interactive - //work. - if (useInteractive) { - node = currentlyAddingScript || getInteractiveScript(); - if (node) { - if (!name) { - name = node.getAttribute('data-requiremodule'); - } - context = contexts[node.getAttribute('data-requirecontext')]; - } - } + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript] + + return true + } + }) + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps + deps = name + name = null + } - //Always save off evaluating the def call until the script onload handler. - //This allows multiple modules to be in a file without prematurely - //tracing dependencies, and allows for anonymous module support, - //where the module name is not known until the script onload event - //occurs. If no context, use the global queue, and get it processed - //in the onscript load callback. - (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); - }; + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps + deps = null + } - define.amd = { - jQuery: true - }; + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps && isFunction(callback)) { + deps = [] + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep) + }) + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps) + } + } + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript() + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule') + } + context = contexts[node.getAttribute('data-requirecontext')] + } + } - /** - * Executes the text. Normally just uses eval, but can be modified - * to use a better, environment-specific call. Only used for transpiling - * loader plugins, not for plain JS modules. - * @param {String} text the text to execute/evaluate. - */ - req.exec = function (text) { - /*jslint evil: true */ - return eval(text); - }; - - //Set up with config info. - req(cfg); -}(this)); + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + ;(context ? context.defQueue : globalDefQueue).push([name, deps, callback]) + } + + define.amd = { + jQuery: true, + } + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text) + } + + //Set up with config info. + req(cfg) +})(this) diff --git a/__test__/utils.classes.test.js b/__test__/utils.classes.test.js index 9ea0f3c7..e2ad006f 100644 --- a/__test__/utils.classes.test.js +++ b/__test__/utils.classes.test.js @@ -1,46 +1,45 @@ -const classes = require('../src/utils/classes'); +const classes = require('../src/utils/classes') -describe('Classes', function() { - var el; +describe('Classes', function () { + var el - beforeEach(function() { + beforeEach(function () { el = document.createElement('div') - document.body.appendChild(el); - }); + document.body.appendChild(el) + }) - afterEach(function() { - document.body.removeChild(el); - }); + afterEach(function () { + document.body.removeChild(el) + }) - it('should add', function() { + it('should add', function () { classes(el).add('show') - expect(el.getAttribute('class')).toBe('show'); - }); - it('should remove', function() { - el.setAttribute('class', 'show'); - expect(el.getAttribute('class')).toBe('show'); + expect(el.getAttribute('class')).toBe('show') + }) + it('should remove', function () { + el.setAttribute('class', 'show') + expect(el.getAttribute('class')).toBe('show') classes(el).remove('show') - expect(el.getAttribute('class')).toBe(''); - }); - it('should toggle', function() { + expect(el.getAttribute('class')).toBe('') + }) + it('should toggle', function () { classes(el).toggle('show') - expect(el.getAttribute('class')).toBe('show'); + expect(el.getAttribute('class')).toBe('show') classes(el).toggle('show') - expect(el.getAttribute('class')).toBe(''); - }); - it('should array', function() { - el.setAttribute('class', 'foo bar'); - expect(classes(el).array()).toEqual(['foo','bar']); - }); - it('should has', function() { - expect(classes(el).has('show')).toBe(false); - el.setAttribute('class', 'show'); - expect(classes(el).has('show')).toBe(true); - }); - it('should contains', function() { - expect(classes(el).contains('show')).toBe(false); - el.setAttribute('class', 'show'); - expect(classes(el).contains('show')).toBe(true); - }); - -}); + expect(el.getAttribute('class')).toBe('') + }) + it('should array', function () { + el.setAttribute('class', 'foo bar') + expect(classes(el).array()).toEqual(['foo', 'bar']) + }) + it('should has', function () { + expect(classes(el).has('show')).toBe(false) + el.setAttribute('class', 'show') + expect(classes(el).has('show')).toBe(true) + }) + it('should contains', function () { + expect(classes(el).contains('show')).toBe(false) + el.setAttribute('class', 'show') + expect(classes(el).contains('show')).toBe(true) + }) +}) diff --git a/__test__/utils.get-by-class.test.js b/__test__/utils.get-by-class.test.js index e1ececcf..b524b544 100644 --- a/__test__/utils.get-by-class.test.js +++ b/__test__/utils.get-by-class.test.js @@ -1,25 +1,25 @@ -const getByClass = require('../src/utils/get-by-class'); +const getByClass = require('../src/utils/get-by-class') -describe('GetByClass', function() { - var el; +describe('GetByClass', function () { + var el - beforeEach(function() { + beforeEach(function () { el = document.createElement('div') el.setAttribute('class', 'foo') - document.body.appendChild(el); - }); + document.body.appendChild(el) + }) - afterEach(function() { - document.body.removeChild(el); - }); + afterEach(function () { + document.body.removeChild(el) + }) - it('should use getElementsByClassName', function() { - expect(getByClass(document.body, 'foo', false, { test: true, getElementsByClassName: true}).length).toBe(1); - }); - it('should use getElementsByClassName', function() { - expect(getByClass(document.body, 'foo', false, { test: true, querySelector: true}).length).toBe(1); - }); - it('should toggle', function() { - expect(getByClass(document.body, 'foo', false, { test: true, polyfill: true}).length).toBe(1); - }); -}); + it('should use getElementsByClassName', function () { + expect(getByClass(document.body, 'foo', false, { test: true, getElementsByClassName: true }).length).toBe(1) + }) + it('should use getElementsByClassName', function () { + expect(getByClass(document.body, 'foo', false, { test: true, querySelector: true }).length).toBe(1) + }) + it('should toggle', function () { + expect(getByClass(document.body, 'foo', false, { test: true, polyfill: true }).length).toBe(1) + }) +}) diff --git a/package.json b/package.json index 063efacc..aefa1c9a 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "jshint": "^2.12.0", "jshint-loader": "^0.8.4", "webpack": "^3.12.0" + "prettier": "^2.2.0", }, "main": "src/index", "engines": { diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 00000000..342b8e5c --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,5 @@ +module.exports = { + semi: false, + singleQuote: true, + printWidth: 120, +} \ No newline at end of file diff --git a/src/add-async.js b/src/add-async.js index aa223f32..1e034ba3 100644 --- a/src/add-async.js +++ b/src/add-async.js @@ -1,16 +1,16 @@ -module.exports = function(list) { - var addAsync = function(values, callback, items) { - var valuesToAdd = values.splice(0, 50); - items = items || []; - items = items.concat(list.add(valuesToAdd)); +module.exports = function (list) { + var addAsync = function (values, callback, items) { + var valuesToAdd = values.splice(0, 50) + items = items || [] + items = items.concat(list.add(valuesToAdd)) if (values.length > 0) { - setTimeout(function() { - addAsync(values, callback, items); - }, 1); + setTimeout(function () { + addAsync(values, callback, items) + }, 1) } else { - list.update(); - callback(items); + list.update() + callback(items) } - }; - return addAsync; -}; + } + return addAsync +} diff --git a/src/filter.js b/src/filter.js index 4b147670..3fd79f38 100644 --- a/src/filter.js +++ b/src/filter.js @@ -1,29 +1,28 @@ -module.exports = function(list) { - +module.exports = function (list) { // Add handlers - list.handlers.filterStart = list.handlers.filterStart || []; - list.handlers.filterComplete = list.handlers.filterComplete || []; + list.handlers.filterStart = list.handlers.filterStart || [] + list.handlers.filterComplete = list.handlers.filterComplete || [] - return function(filterFunction) { - list.trigger('filterStart'); - list.i = 1; // Reset paging - list.reset.filter(); + return function (filterFunction) { + list.trigger('filterStart') + list.i = 1 // Reset paging + list.reset.filter() if (filterFunction === undefined) { - list.filtered = false; + list.filtered = false } else { - list.filtered = true; - var is = list.items; + list.filtered = true + var is = list.items for (var i = 0, il = is.length; i < il; i++) { - var item = is[i]; + var item = is[i] if (filterFunction(item)) { - item.filtered = true; + item.filtered = true } else { - item.filtered = false; + item.filtered = false } } } - list.update(); - list.trigger('filterComplete'); - return list.visibleItems; - }; -}; + list.update() + list.trigger('filterComplete') + return list.visibleItems + } +} diff --git a/src/fuzzy-search.js b/src/fuzzy-search.js index ac49dfa1..0c44d189 100644 --- a/src/fuzzy-search.js +++ b/src/fuzzy-search.js @@ -1,67 +1,66 @@ - var classes = require('./utils/classes'), events = require('./utils/events'), extend = require('./utils/extend'), toString = require('./utils/to-string'), getByClass = require('./utils/get-by-class'), - fuzzy = require('./utils/fuzzy'); - -module.exports = function(list, options) { - options = options || {}; - - options = extend({ - location: 0, - distance: 100, - threshold: 0.4, - multiSearch: true, - searchClass: 'fuzzy-search' - }, options); + fuzzy = require('./utils/fuzzy') +module.exports = function (list, options) { + options = options || {} + options = extend( + { + location: 0, + distance: 100, + threshold: 0.4, + multiSearch: true, + searchClass: 'fuzzy-search', + }, + options + ) var fuzzySearch = { - search: function(searchString, columns) { + search: function (searchString, columns) { // Substract arguments from the searchString or put searchString as only argument - var searchArguments = options.multiSearch ? searchString.replace(/ +$/, '').split(/ +/) : [searchString]; + var searchArguments = options.multiSearch ? searchString.replace(/ +$/, '').split(/ +/) : [searchString] for (var k = 0, kl = list.items.length; k < kl; k++) { - fuzzySearch.item(list.items[k], columns, searchArguments); + fuzzySearch.item(list.items[k], columns, searchArguments) } }, - item: function(item, columns, searchArguments) { - var found = true; - for(var i = 0; i < searchArguments.length; i++) { - var foundArgument = false; + item: function (item, columns, searchArguments) { + var found = true + for (var i = 0; i < searchArguments.length; i++) { + var foundArgument = false for (var j = 0, jl = columns.length; j < jl; j++) { if (fuzzySearch.values(item.values(), columns[j], searchArguments[i])) { - foundArgument = true; + foundArgument = true } } - if(!foundArgument) { - found = false; + if (!foundArgument) { + found = false } } - item.found = found; + item.found = found }, - values: function(values, value, searchArgument) { + values: function (values, value, searchArgument) { if (values.hasOwnProperty(value)) { - var text = toString(values[value]).toLowerCase(); + var text = toString(values[value]).toLowerCase() if (fuzzy(text, searchArgument, options)) { - return true; + return true } } - return false; - } - }; - + return false + }, + } - events.bind(getByClass(list.listContainer, options.searchClass), 'keyup', function(e) { - var target = e.target || e.srcElement; // IE have srcElement - list.search(target.value, fuzzySearch.search); - }); + events.bind(getByClass(list.listContainer, options.searchClass), 'keyup', function (e) { + var target = e.target || e.srcElement // IE have srcElement + list.search(target.value, fuzzySearch.search) + }) - return function(str, columns) { - list.search(str, columns, fuzzySearch.search); - }; -}; + return function (str, columns) { + list.search(str, columns, fuzzySearch.search) + } +} diff --git a/src/index.js b/src/index.js index 887019ff..816bcaaa 100644 --- a/src/index.js +++ b/src/index.js @@ -6,32 +6,31 @@ var naturalSort = require('string-natural-compare'), toString = require('./utils/to-string'), classes = require('./utils/classes'), getAttribute = require('./utils/get-attribute'), - toArray = require('./utils/to-array'); - -module.exports = function(id, options, values) { + toArray = require('./utils/to-array') +module.exports = function (id, options, values) { var self = this, init, Item = require('./item')(self), addAsync = require('./add-async')(self), - initPagination = require('./pagination')(self); + initPagination = require('./pagination')(self) init = { - start: function() { - self.listClass = "list"; - self.searchClass = "search"; - self.sortClass = "sort"; - self.page = 10000; - self.i = 1; - self.items = []; - self.visibleItems = []; - self.matchingItems = []; - self.searched = false; - self.filtered = false; - self.searchColumns = undefined; - self.handlers = { 'updated': [] }; - self.valueNames = []; - self.utils = { + start: function () { + self.listClass = 'list' + self.searchClass = 'search' + self.sortClass = 'sort' + self.page = 10000 + self.i = 1 + self.items = [] + self.visibleItems = [] + self.matchingItems = [] + self.searched = false + self.filtered = false + self.searchColumns = undefined + self.handlers = { updated: [] } + self.valueNames = [] + self.utils = { getByClass: getByClass, extend: extend, indexOf: indexOf, @@ -40,223 +39,224 @@ module.exports = function(id, options, values) { naturalSort: naturalSort, classes: classes, getAttribute: getAttribute, - toArray: toArray - }; + toArray: toArray, + } - self.utils.extend(self, options); + self.utils.extend(self, options) - self.listContainer = (typeof(id) === 'string') ? document.getElementById(id) : id; - if (!self.listContainer) { return; } - self.list = getByClass(self.listContainer, self.listClass, true); + self.listContainer = typeof id === 'string' ? document.getElementById(id) : id + if (!self.listContainer) { + return + } + self.list = getByClass(self.listContainer, self.listClass, true) - self.parse = require('./parse')(self); - self.templater = require('./templater')(self); - self.search = require('./search')(self); - self.filter = require('./filter')(self); - self.sort = require('./sort')(self); - self.fuzzySearch = require('./fuzzy-search')(self, options.fuzzySearch); + self.parse = require('./parse')(self) + self.templater = require('./templater')(self) + self.search = require('./search')(self) + self.filter = require('./filter')(self) + self.sort = require('./sort')(self) + self.fuzzySearch = require('./fuzzy-search')(self, options.fuzzySearch) - this.handlers(); - this.items(); - this.pagination(); + this.handlers() + this.items() + this.pagination() - self.update(); + self.update() }, - handlers: function() { + handlers: function () { for (var handler in self.handlers) { if (self[handler]) { - self.on(handler, self[handler]); + self.on(handler, self[handler]) } } }, - items: function() { - self.parse(self.list); + items: function () { + self.parse(self.list) if (values !== undefined) { - self.add(values); + self.add(values) } }, - pagination: function() { + pagination: function () { if (options.pagination !== undefined) { if (options.pagination === true) { - options.pagination = [{}]; + options.pagination = [{}] } - if (options.pagination[0] === undefined){ - options.pagination = [options.pagination]; + if (options.pagination[0] === undefined) { + options.pagination = [options.pagination] } for (var i = 0, il = options.pagination.length; i < il; i++) { - initPagination(options.pagination[i]); + initPagination(options.pagination[i]) } } - } - }; + }, + } /* - * Re-parse the List, use if html have changed - */ - this.reIndex = function() { - self.items = []; - self.visibleItems = []; - self.matchingItems = []; - self.searched = false; - self.filtered = false; - self.parse(self.list); - }; + * Re-parse the List, use if html have changed + */ + this.reIndex = function () { + self.items = [] + self.visibleItems = [] + self.matchingItems = [] + self.searched = false + self.filtered = false + self.parse(self.list) + } - this.toJSON = function() { - var json = []; + this.toJSON = function () { + var json = [] for (var i = 0, il = self.items.length; i < il; i++) { - json.push(self.items[i].values()); + json.push(self.items[i].values()) } - return json; - }; - + return json + } /* - * Add object to list - */ - this.add = function(values, callback) { + * Add object to list + */ + this.add = function (values, callback) { if (values.length === 0) { - return; + return } if (callback) { - addAsync(values, callback); - return; + addAsync(values, callback) + return } var added = [], - notCreate = false; - if (values[0] === undefined){ - values = [values]; + notCreate = false + if (values[0] === undefined) { + values = [values] } for (var i = 0, il = values.length; i < il; i++) { - var item = null; - notCreate = (self.items.length > self.page) ? true : false; - item = new Item(values[i], undefined, notCreate); - self.items.push(item); - added.push(item); + var item = null + notCreate = self.items.length > self.page ? true : false + item = new Item(values[i], undefined, notCreate) + self.items.push(item) + added.push(item) } - self.update(); - return added; - }; + self.update() + return added + } - this.show = function(i, page) { - this.i = i; - this.page = page; - self.update(); - return self; - }; + this.show = function (i, page) { + this.i = i + this.page = page + self.update() + return self + } /* Removes object from list. - * Loops through the list and removes objects where - * property "valuename" === value - */ - this.remove = function(valueName, value, options) { - var found = 0; + * Loops through the list and removes objects where + * property "valuename" === value + */ + this.remove = function (valueName, value, options) { + var found = 0 for (var i = 0, il = self.items.length; i < il; i++) { if (self.items[i].values()[valueName] == value) { - self.templater.remove(self.items[i], options); - self.items.splice(i,1); - il--; - i--; - found++; + self.templater.remove(self.items[i], options) + self.items.splice(i, 1) + il-- + i-- + found++ } } - self.update(); - return found; - }; + self.update() + return found + } /* Gets the objects in the list which - * property "valueName" === value - */ - this.get = function(valueName, value) { - var matchedItems = []; + * property "valueName" === value + */ + this.get = function (valueName, value) { + var matchedItems = [] for (var i = 0, il = self.items.length; i < il; i++) { - var item = self.items[i]; + var item = self.items[i] if (item.values()[valueName] == value) { - matchedItems.push(item); + matchedItems.push(item) } } - return matchedItems; - }; + return matchedItems + } /* - * Get size of the list - */ - this.size = function() { - return self.items.length; - }; + * Get size of the list + */ + this.size = function () { + return self.items.length + } /* - * Removes all items from the list - */ - this.clear = function() { - self.templater.clear(); - self.items = []; - return self; - }; + * Removes all items from the list + */ + this.clear = function () { + self.templater.clear() + self.items = [] + return self + } - this.on = function(event, callback) { - self.handlers[event].push(callback); - return self; - }; + this.on = function (event, callback) { + self.handlers[event].push(callback) + return self + } - this.off = function(event, callback) { - var e = self.handlers[event]; - var index = indexOf(e, callback); + this.off = function (event, callback) { + var e = self.handlers[event] + var index = indexOf(e, callback) if (index > -1) { - e.splice(index, 1); + e.splice(index, 1) } - return self; - }; + return self + } - this.trigger = function(event) { - var i = self.handlers[event].length; - while(i--) { - self.handlers[event][i](self); + this.trigger = function (event) { + var i = self.handlers[event].length + while (i--) { + self.handlers[event][i](self) } - return self; - }; + return self + } this.reset = { - filter: function() { + filter: function () { var is = self.items, - il = is.length; + il = is.length while (il--) { - is[il].filtered = false; + is[il].filtered = false } - return self; + return self }, - search: function() { + search: function () { var is = self.items, - il = is.length; + il = is.length while (il--) { - is[il].found = false; + is[il].found = false } - return self; - } - }; + return self + }, + } - this.update = function() { + this.update = function () { var is = self.items, - il = is.length; + il = is.length - self.visibleItems = []; - self.matchingItems = []; - self.templater.clear(); + self.visibleItems = [] + self.matchingItems = [] + self.templater.clear() for (var i = 0; i < il; i++) { - if (is[i].matching() && ((self.matchingItems.length+1) >= self.i && self.visibleItems.length < self.page)) { - is[i].show(); - self.visibleItems.push(is[i]); - self.matchingItems.push(is[i]); + if (is[i].matching() && self.matchingItems.length + 1 >= self.i && self.visibleItems.length < self.page) { + is[i].show() + self.visibleItems.push(is[i]) + self.matchingItems.push(is[i]) } else if (is[i].matching()) { - self.matchingItems.push(is[i]); - is[i].hide(); + self.matchingItems.push(is[i]) + is[i].hide() } else { - is[i].hide(); + is[i].hide() } } - self.trigger('updated'); - return self; - }; + self.trigger('updated') + return self + } - init.start(); -}; + init.start() +} diff --git a/src/item.js b/src/item.js index f5ab9a18..41410625 100644 --- a/src/item.js +++ b/src/item.js @@ -1,60 +1,60 @@ -module.exports = function(list) { - return function(initValues, element, notCreate) { - var item = this; +module.exports = function (list) { + return function (initValues, element, notCreate) { + var item = this - this._values = {}; + this._values = {} - this.found = false; // Show if list.searched == true and this.found == true - this.filtered = false;// Show if list.filtered == true and this.filtered == true + this.found = false // Show if list.searched == true and this.found == true + this.filtered = false // Show if list.filtered == true and this.filtered == true - var init = function(initValues, element, notCreate) { + var init = function (initValues, element, notCreate) { if (element === undefined) { if (notCreate) { - item.values(initValues, notCreate); + item.values(initValues, notCreate) } else { - item.values(initValues); + item.values(initValues) } } else { - item.elm = element; - var values = list.templater.get(item, initValues); - item.values(values); + item.elm = element + var values = list.templater.get(item, initValues) + item.values(values) } - }; + } - this.values = function(newValues, notCreate) { + this.values = function (newValues, notCreate) { if (newValues !== undefined) { - for(var name in newValues) { - item._values[name] = newValues[name]; + for (var name in newValues) { + item._values[name] = newValues[name] } if (notCreate !== true) { - list.templater.set(item, item.values()); + list.templater.set(item, item.values()) } } else { - return item._values; + return item._values } - }; + } - this.show = function() { - list.templater.show(item); - }; + this.show = function () { + list.templater.show(item) + } - this.hide = function() { - list.templater.hide(item); - }; + this.hide = function () { + list.templater.hide(item) + } - this.matching = function() { + this.matching = function () { return ( (list.filtered && list.searched && item.found && item.filtered) || (list.filtered && !list.searched && item.filtered) || (!list.filtered && list.searched && item.found) || (!list.filtered && !list.searched) - ); - }; + ) + } - this.visible = function() { - return (item.elm && (item.elm.parentNode == list.list)) ? true : false; - }; + this.visible = function () { + return item.elm && item.elm.parentNode == list.list ? true : false + } - init(initValues, element, notCreate); - }; -}; + init(initValues, element, notCreate) + } +} diff --git a/src/pagination.js b/src/pagination.js index 69e9f5e7..203c195d 100644 --- a/src/pagination.js +++ b/src/pagination.js @@ -1,17 +1,17 @@ var classes = require('./utils/classes'), events = require('./utils/events'), - List = require('./index'); + List = require('./index') -module.exports = function(list) { - var isHidden = false; +module.exports = function (list) { + var isHidden = false - var refresh = function(pagingList, options) { + var refresh = function (pagingList, options) { if (list.page < 1) { - list.listContainer.style.display = 'none'; - isHidden = true; - return; - } else if (isHidden){ - list.listContainer.style.display = 'block'; + list.listContainer.style.display = 'none' + isHidden = true + return + } else if (isHidden) { + list.listContainer.style.display = 'block' } var item, @@ -19,87 +19,90 @@ module.exports = function(list) { index = list.i, page = list.page, pages = Math.ceil(l / page), - currentPage = Math.ceil((index / page)), + currentPage = Math.ceil(index / page), innerWindow = options.innerWindow || 2, left = options.left || options.outerWindow || 0, - right = options.right || options.outerWindow || 0; + right = options.right || options.outerWindow || 0 - right = pages - right; - pagingList.clear(); + right = pages - right + pagingList.clear() for (var i = 1; i <= pages; i++) { - var className = (currentPage === i) ? "active" : ""; + var className = currentPage === i ? 'active' : '' //console.log(i, left, right, currentPage, (currentPage - innerWindow), (currentPage + innerWindow), className); if (is.number(i, left, right, currentPage, innerWindow)) { item = pagingList.add({ page: i, - dotted: false - })[0]; + dotted: false, + })[0] if (className) { - classes(item.elm).add(className); + classes(item.elm).add(className) } - item.elm.firstChild.setAttribute('data-i', i); - item.elm.firstChild.setAttribute('data-page', page); + item.elm.firstChild.setAttribute('data-i', i) + item.elm.firstChild.setAttribute('data-page', page) } else if (is.dotted(pagingList, i, left, right, currentPage, innerWindow, pagingList.size())) { item = pagingList.add({ - page: "...", - dotted: true - })[0]; - classes(item.elm).add("disabled"); + page: '...', + dotted: true, + })[0] + classes(item.elm).add('disabled') } } - }; + } var is = { - number: function(i, left, right, currentPage, innerWindow) { - return this.left(i, left) || this.right(i, right) || this.innerWindow(i, currentPage, innerWindow); + number: function (i, left, right, currentPage, innerWindow) { + return this.left(i, left) || this.right(i, right) || this.innerWindow(i, currentPage, innerWindow) }, - left: function(i, left) { - return (i <= left); + left: function (i, left) { + return i <= left }, - right: function(i, right) { - return (i > right); + right: function (i, right) { + return i > right }, - innerWindow: function(i, currentPage, innerWindow) { - return ( i >= (currentPage - innerWindow) && i <= (currentPage + innerWindow)); + innerWindow: function (i, currentPage, innerWindow) { + return i >= currentPage - innerWindow && i <= currentPage + innerWindow }, - dotted: function(pagingList, i, left, right, currentPage, innerWindow, currentPageItem) { - return this.dottedLeft(pagingList, i, left, right, currentPage, innerWindow) || (this.dottedRight(pagingList, i, left, right, currentPage, innerWindow, currentPageItem)); + dotted: function (pagingList, i, left, right, currentPage, innerWindow, currentPageItem) { + return ( + this.dottedLeft(pagingList, i, left, right, currentPage, innerWindow) || + this.dottedRight(pagingList, i, left, right, currentPage, innerWindow, currentPageItem) + ) }, - dottedLeft: function(pagingList, i, left, right, currentPage, innerWindow) { - return ((i == (left + 1)) && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right)); + dottedLeft: function (pagingList, i, left, right, currentPage, innerWindow) { + return i == left + 1 && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right) }, - dottedRight: function(pagingList, i, left, right, currentPage, innerWindow, currentPageItem) { - if (pagingList.items[currentPageItem-1].values().dotted) { - return false; + dottedRight: function (pagingList, i, left, right, currentPage, innerWindow, currentPageItem) { + if (pagingList.items[currentPageItem - 1].values().dotted) { + return false } else { - return ((i == (right)) && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right)); + return i == right && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right) } - } - }; + }, + } - return function(options) { + return function (options) { var pagingList = new List(list.listContainer.id, { listClass: options.paginationClass || 'pagination', item: "
  • ", valueNames: ['page', 'dotted'], searchClass: 'pagination-search-that-is-not-supposed-to-exist', - sortClass: 'pagination-sort-that-is-not-supposed-to-exist' - }); + sortClass: 'pagination-sort-that-is-not-supposed-to-exist', + }) - events.bind(pagingList.listContainer, 'click', function(e) { - var target = e.target || e.srcElement - , page = list.utils.getAttribute(target, 'data-page') - , i = list.utils.getAttribute(target, 'data-i'); - if(i){ - list.show((i-1)*page + 1, page); + events.bind(pagingList.listContainer, 'click', function (e) { + var target = e.target || e.srcElement, + page = list.utils.getAttribute(target, 'data-page'), + i = list.utils.getAttribute(target, 'data-i') + if (i) { + list.show((i - 1) * page + 1, page) } - }); + }) - list.on('updated', function() { - refresh(pagingList, options); - }); - refresh(pagingList, options); - }; -}; + list.on('updated', function () { + refresh(pagingList, options) + }) + refresh(pagingList, options) + } +} diff --git a/src/parse.js b/src/parse.js index 2294a476..0abe5900 100644 --- a/src/parse.js +++ b/src/parse.js @@ -1,47 +1,46 @@ -module.exports = function(list) { +module.exports = function (list) { + var Item = require('./item')(list) - var Item = require('./item')(list); - - var getChildren = function(parent) { + var getChildren = function (parent) { var nodes = parent.childNodes, - items = []; + items = [] for (var i = 0, il = nodes.length; i < il; i++) { // Only textnodes have a data attribute if (nodes[i].data === undefined) { - items.push(nodes[i]); + items.push(nodes[i]) } } - return items; - }; + return items + } - var parse = function(itemElements, valueNames) { + var parse = function (itemElements, valueNames) { for (var i = 0, il = itemElements.length; i < il; i++) { - list.items.push(new Item(valueNames, itemElements[i])); + list.items.push(new Item(valueNames, itemElements[i])) } - }; - var parseAsync = function(itemElements, valueNames) { - var itemsToIndex = itemElements.splice(0, 50); // TODO: If < 100 items, what happens in IE etc? - parse(itemsToIndex, valueNames); + } + var parseAsync = function (itemElements, valueNames) { + var itemsToIndex = itemElements.splice(0, 50) // TODO: If < 100 items, what happens in IE etc? + parse(itemsToIndex, valueNames) if (itemElements.length > 0) { - setTimeout(function() { - parseAsync(itemElements, valueNames); - }, 1); + setTimeout(function () { + parseAsync(itemElements, valueNames) + }, 1) } else { - list.update(); - list.trigger('parseComplete'); + list.update() + list.trigger('parseComplete') } - }; + } - list.handlers.parseComplete = list.handlers.parseComplete || []; + list.handlers.parseComplete = list.handlers.parseComplete || [] - return function() { + return function () { var itemsToIndex = getChildren(list.list), - valueNames = list.valueNames; + valueNames = list.valueNames if (list.indexAsync) { - parseAsync(itemsToIndex, valueNames); + parseAsync(itemsToIndex, valueNames) } else { - parse(itemsToIndex, valueNames); + parse(itemsToIndex, valueNames) } - }; -}; + } +} diff --git a/src/search.js b/src/search.js index f7b0b6db..afdfaef9 100644 --- a/src/search.js +++ b/src/search.js @@ -1,120 +1,117 @@ -module.exports = function(list) { - var item, - text, - columns, - searchString, - customSearch; +module.exports = function (list) { + var item, text, columns, searchString, customSearch var prepare = { - resetList: function() { - list.i = 1; - list.templater.clear(); - customSearch = undefined; + resetList: function () { + list.i = 1 + list.templater.clear() + customSearch = undefined }, - setOptions: function(args) { + setOptions: function (args) { if (args.length == 2 && args[1] instanceof Array) { - columns = args[1]; - } else if (args.length == 2 && typeof(args[1]) == "function") { - columns = undefined; - customSearch = args[1]; + columns = args[1] + } else if (args.length == 2 && typeof args[1] == 'function') { + columns = undefined + customSearch = args[1] } else if (args.length == 3) { - columns = args[1]; - customSearch = args[2]; + columns = args[1] + customSearch = args[2] } else { - columns = undefined; + columns = undefined } }, - setColumns: function() { - if (list.items.length === 0) return; + setColumns: function () { + if (list.items.length === 0) return if (columns === undefined) { - columns = (list.searchColumns === undefined) ? prepare.toArray(list.items[0].values()) : list.searchColumns; + columns = list.searchColumns === undefined ? prepare.toArray(list.items[0].values()) : list.searchColumns } }, - setSearchString: function(s) { - s = list.utils.toString(s).toLowerCase(); - s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"); // Escape regular expression characters - searchString = s; + setSearchString: function (s) { + s = list.utils.toString(s).toLowerCase() + s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, '\\$&') // Escape regular expression characters + searchString = s }, - toArray: function(values) { - var tmpColumn = []; + toArray: function (values) { + var tmpColumn = [] for (var name in values) { - tmpColumn.push(name); + tmpColumn.push(name) } - return tmpColumn; - } - }; + return tmpColumn + }, + } var search = { - list: function() { + list: function () { for (var k = 0, kl = list.items.length; k < kl; k++) { - search.item(list.items[k]); + search.item(list.items[k]) } }, - item: function(item) { - item.found = false; + item: function (item) { + item.found = false for (var j = 0, jl = columns.length; j < jl; j++) { if (search.values(item.values(), columns[j])) { - item.found = true; - return; + item.found = true + return } } }, - values: function(values, column) { + values: function (values, column) { if (values.hasOwnProperty(column)) { - text = list.utils.toString(values[column]).toLowerCase(); - if ((searchString !== "") && (text.search(searchString) > -1)) { - return true; + text = list.utils.toString(values[column]).toLowerCase() + if (searchString !== '' && text.search(searchString) > -1) { + return true } } - return false; + return false }, - reset: function() { - list.reset.search(); - list.searched = false; - } - }; + reset: function () { + list.reset.search() + list.searched = false + }, + } - var searchMethod = function(str) { - list.trigger('searchStart'); + var searchMethod = function (str) { + list.trigger('searchStart') - prepare.resetList(); - prepare.setSearchString(str); - prepare.setOptions(arguments); // str, cols|searchFunction, searchFunction - prepare.setColumns(); + prepare.resetList() + prepare.setSearchString(str) + prepare.setOptions(arguments) // str, cols|searchFunction, searchFunction + prepare.setColumns() - if (searchString === "" ) { - search.reset(); + if (searchString === '') { + search.reset() } else { - list.searched = true; + list.searched = true if (customSearch) { - customSearch(searchString, columns); + customSearch(searchString, columns) } else { - search.list(); + search.list() } } - list.update(); - list.trigger('searchComplete'); - return list.visibleItems; - }; + list.update() + list.trigger('searchComplete') + return list.visibleItems + } - list.handlers.searchStart = list.handlers.searchStart || []; - list.handlers.searchComplete = list.handlers.searchComplete || []; + list.handlers.searchStart = list.handlers.searchStart || [] + list.handlers.searchComplete = list.handlers.searchComplete || [] - list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'keyup', function(e) { + list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'keyup', function (e) { var target = e.target || e.srcElement, // IE have srcElement - alreadyCleared = (target.value === "" && !list.searched); - if (!alreadyCleared) { // If oninput already have resetted the list, do nothing - searchMethod(target.value); + alreadyCleared = target.value === '' && !list.searched + if (!alreadyCleared) { + // If oninput already have resetted the list, do nothing + searchMethod(target.value) } - }); + }) // Used to detect click on HTML5 clear button - list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'input', function(e) { - var target = e.target || e.srcElement; - if (target.value === "") { - searchMethod(''); + list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'input', function (e) { + var target = e.target || e.srcElement + if (target.value === '') { + searchMethod('') } - }); + }) - return searchMethod; -}; + return searchMethod +} diff --git a/src/sort.js b/src/sort.js index 8a59b0a3..4e4b415f 100644 --- a/src/sort.js +++ b/src/sort.js @@ -1,106 +1,104 @@ -module.exports = function(list) { - +module.exports = function (list) { var buttons = { els: undefined, - clear: function() { + clear: function () { for (var i = 0, il = buttons.els.length; i < il; i++) { - list.utils.classes(buttons.els[i]).remove('asc'); - list.utils.classes(buttons.els[i]).remove('desc'); + list.utils.classes(buttons.els[i]).remove('asc') + list.utils.classes(buttons.els[i]).remove('desc') } }, - getOrder: function(btn) { - var predefinedOrder = list.utils.getAttribute(btn, 'data-order'); - if (predefinedOrder == "asc" || predefinedOrder == "desc") { - return predefinedOrder; + getOrder: function (btn) { + var predefinedOrder = list.utils.getAttribute(btn, 'data-order') + if (predefinedOrder == 'asc' || predefinedOrder == 'desc') { + return predefinedOrder } else if (list.utils.classes(btn).has('desc')) { - return "asc"; + return 'asc' } else if (list.utils.classes(btn).has('asc')) { - return "desc"; + return 'desc' } else { - return "asc"; + return 'asc' } }, - getInSensitive: function(btn, options) { - var insensitive = list.utils.getAttribute(btn, 'data-insensitive'); - if (insensitive === "false") { - options.insensitive = false; + getInSensitive: function (btn, options) { + var insensitive = list.utils.getAttribute(btn, 'data-insensitive') + if (insensitive === 'false') { + options.insensitive = false } else { - options.insensitive = true; + options.insensitive = true } }, - setOrder: function(options) { + setOrder: function (options) { for (var i = 0, il = buttons.els.length; i < il; i++) { - var btn = buttons.els[i]; + var btn = buttons.els[i] if (list.utils.getAttribute(btn, 'data-sort') !== options.valueName) { - continue; + continue } - var predefinedOrder = list.utils.getAttribute(btn, 'data-order'); - if (predefinedOrder == "asc" || predefinedOrder == "desc") { + var predefinedOrder = list.utils.getAttribute(btn, 'data-order') + if (predefinedOrder == 'asc' || predefinedOrder == 'desc') { if (predefinedOrder == options.order) { - list.utils.classes(btn).add(options.order); + list.utils.classes(btn).add(options.order) } } else { - list.utils.classes(btn).add(options.order); + list.utils.classes(btn).add(options.order) } } - } - }; + }, + } - var sort = function() { - list.trigger('sortStart'); - var options = {}; + var sort = function () { + list.trigger('sortStart') + var options = {} - var target = arguments[0].currentTarget || arguments[0].srcElement || undefined; + var target = arguments[0].currentTarget || arguments[0].srcElement || undefined if (target) { - options.valueName = list.utils.getAttribute(target, 'data-sort'); - buttons.getInSensitive(target, options); - options.order = buttons.getOrder(target); + options.valueName = list.utils.getAttribute(target, 'data-sort') + buttons.getInSensitive(target, options) + options.order = buttons.getOrder(target) } else { - options = arguments[1] || options; - options.valueName = arguments[0]; - options.order = options.order || "asc"; - options.insensitive = (typeof options.insensitive == "undefined") ? true : options.insensitive; + options = arguments[1] || options + options.valueName = arguments[0] + options.order = options.order || 'asc' + options.insensitive = typeof options.insensitive == 'undefined' ? true : options.insensitive } - buttons.clear(); - buttons.setOrder(options); - + buttons.clear() + buttons.setOrder(options) // caseInsensitive // alphabet - var customSortFunction = (options.sortFunction || list.sortFunction || null), - multi = ((options.order === 'desc') ? -1 : 1), - sortFunction; + var customSortFunction = options.sortFunction || list.sortFunction || null, + multi = options.order === 'desc' ? -1 : 1, + sortFunction if (customSortFunction) { - sortFunction = function(itemA, itemB) { - return customSortFunction(itemA, itemB, options) * multi; - }; + sortFunction = function (itemA, itemB) { + return customSortFunction(itemA, itemB, options) * multi + } } else { - sortFunction = function(itemA, itemB) { - var sort = list.utils.naturalSort; - sort.alphabet = list.alphabet || options.alphabet || undefined; + sortFunction = function (itemA, itemB) { + var sort = list.utils.naturalSort + sort.alphabet = list.alphabet || options.alphabet || undefined if (!sort.alphabet && options.insensitive) { - sort = list.utils.naturalSort.caseInsensitive; + sort = list.utils.naturalSort.caseInsensitive } - return sort(itemA.values()[options.valueName], itemB.values()[options.valueName]) * multi; - }; + return sort(itemA.values()[options.valueName], itemB.values()[options.valueName]) * multi + } } - list.items.sort(sortFunction); - list.update(); - list.trigger('sortComplete'); - }; + list.items.sort(sortFunction) + list.update() + list.trigger('sortComplete') + } // Add handlers - list.handlers.sortStart = list.handlers.sortStart || []; - list.handlers.sortComplete = list.handlers.sortComplete || []; + list.handlers.sortStart = list.handlers.sortStart || [] + list.handlers.sortComplete = list.handlers.sortComplete || [] - buttons.els = list.utils.getByClass(list.listContainer, list.sortClass); - list.utils.events.bind(buttons.els, 'click', sort); - list.on('searchStart', buttons.clear); - list.on('filterStart', buttons.clear); + buttons.els = list.utils.getByClass(list.listContainer, list.sortClass) + list.utils.events.bind(buttons.els, 'click', sort) + list.on('searchStart', buttons.clear) + list.on('filterStart', buttons.clear) - return sort; -}; + return sort +} diff --git a/src/templater.js b/src/templater.js index ba37138f..83b91197 100644 --- a/src/templater.js +++ b/src/templater.js @@ -1,174 +1,172 @@ -var Templater = function(list) { +var Templater = function (list) { var itemSource, - templater = this; + templater = this - var init = function() { - itemSource = templater.getItemSource(list.item); + var init = function () { + itemSource = templater.getItemSource(list.item) if (itemSource) { - itemSource = templater.clearSourceItem(itemSource, list.valueNames); + itemSource = templater.clearSourceItem(itemSource, list.valueNames) } - }; + } - this.clearSourceItem = function(el, valueNames) { - for(var i = 0, il = valueNames.length; i < il; i++) { - var elm; + this.clearSourceItem = function (el, valueNames) { + for (var i = 0, il = valueNames.length; i < il; i++) { + var elm if (valueNames[i].data) { for (var j = 0, jl = valueNames[i].data.length; j < jl; j++) { - el.setAttribute('data-'+valueNames[i].data[j], ''); + el.setAttribute('data-' + valueNames[i].data[j], '') } } else if (valueNames[i].attr && valueNames[i].name) { - elm = list.utils.getByClass(el, valueNames[i].name, true); + elm = list.utils.getByClass(el, valueNames[i].name, true) if (elm) { - elm.setAttribute(valueNames[i].attr, ""); + elm.setAttribute(valueNames[i].attr, '') } } else { - elm = list.utils.getByClass(el, valueNames[i], true); + elm = list.utils.getByClass(el, valueNames[i], true) if (elm) { - elm.innerHTML = ""; + elm.innerHTML = '' } } - elm = undefined; + elm = undefined } - return el; - }; + return el + } - this.getItemSource = function(item) { + this.getItemSource = function (item) { if (item === undefined) { var nodes = list.list.childNodes, - items = []; + items = [] for (var i = 0, il = nodes.length; i < il; i++) { // Only textnodes have a data attribute if (nodes[i].data === undefined) { - return nodes[i].cloneNode(true); + return nodes[i].cloneNode(true) } } } else if (/]/g.exec(item)) { - var tbody = document.createElement('tbody'); - tbody.innerHTML = item; - return tbody.firstChild; - } else if (item.indexOf("<") !== -1) { - var div = document.createElement('div'); - div.innerHTML = item; - return div.firstChild; + var tbody = document.createElement('tbody') + tbody.innerHTML = item + return tbody.firstChild + } else if (item.indexOf('<') !== -1) { + var div = document.createElement('div') + div.innerHTML = item + return div.firstChild } else { - var source = document.getElementById(list.item); + var source = document.getElementById(list.item) if (source) { - return source; + return source } } - return undefined; - }; + return undefined + } - this.get = function(item, valueNames) { - templater.create(item); - var values = {}; - for(var i = 0, il = valueNames.length; i < il; i++) { - var elm; + this.get = function (item, valueNames) { + templater.create(item) + var values = {} + for (var i = 0, il = valueNames.length; i < il; i++) { + var elm if (valueNames[i].data) { for (var j = 0, jl = valueNames[i].data.length; j < jl; j++) { - values[valueNames[i].data[j]] = list.utils.getAttribute(item.elm, 'data-'+valueNames[i].data[j]); + values[valueNames[i].data[j]] = list.utils.getAttribute(item.elm, 'data-' + valueNames[i].data[j]) } } else if (valueNames[i].attr && valueNames[i].name) { - elm = list.utils.getByClass(item.elm, valueNames[i].name, true); - values[valueNames[i].name] = elm ? list.utils.getAttribute(elm, valueNames[i].attr) : ""; + elm = list.utils.getByClass(item.elm, valueNames[i].name, true) + values[valueNames[i].name] = elm ? list.utils.getAttribute(elm, valueNames[i].attr) : '' } else { - elm = list.utils.getByClass(item.elm, valueNames[i], true); - values[valueNames[i]] = elm ? elm.innerHTML : ""; + elm = list.utils.getByClass(item.elm, valueNames[i], true) + values[valueNames[i]] = elm ? elm.innerHTML : '' } - elm = undefined; + elm = undefined } - return values; - }; + return values + } - this.set = function(item, values) { - var getValueName = function(name) { + this.set = function (item, values) { + var getValueName = function (name) { for (var i = 0, il = list.valueNames.length; i < il; i++) { if (list.valueNames[i].data) { - var data = list.valueNames[i].data; + var data = list.valueNames[i].data for (var j = 0, jl = data.length; j < jl; j++) { if (data[j] === name) { - return { data: name }; + return { data: name } } } } else if (list.valueNames[i].attr && list.valueNames[i].name && list.valueNames[i].name == name) { - return list.valueNames[i]; + return list.valueNames[i] } else if (list.valueNames[i] === name) { - return name; + return name } } - }; - var setValue = function(name, value) { - var elm; - var valueName = getValueName(name); - if (!valueName) - return; + } + var setValue = function (name, value) { + var elm + var valueName = getValueName(name) + if (!valueName) return if (valueName.data) { - item.elm.setAttribute('data-'+valueName.data, value); + item.elm.setAttribute('data-' + valueName.data, value) } else if (valueName.attr && valueName.name) { - elm = list.utils.getByClass(item.elm, valueName.name, true); + elm = list.utils.getByClass(item.elm, valueName.name, true) if (elm) { - elm.setAttribute(valueName.attr, value); + elm.setAttribute(valueName.attr, value) } } else { - elm = list.utils.getByClass(item.elm, valueName, true); + elm = list.utils.getByClass(item.elm, valueName, true) if (elm) { - elm.innerHTML = value; + elm.innerHTML = value } } - elm = undefined; - }; + elm = undefined + } if (!templater.create(item)) { - for(var v in values) { + for (var v in values) { if (values.hasOwnProperty(v)) { - setValue(v, values[v]); + setValue(v, values[v]) } } } - }; + } - this.create = function(item) { + this.create = function (item) { if (item.elm !== undefined) { - return false; + return false } if (itemSource === undefined) { - throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template."); + throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.") } /* If item source does not exists, use the first item in list as source for new items */ - var newItem = itemSource.cloneNode(true); - newItem.removeAttribute('id'); - item.elm = newItem; - templater.set(item, item.values()); - return true; - }; - this.remove = function(item) { + var newItem = itemSource.cloneNode(true) + newItem.removeAttribute('id') + item.elm = newItem + templater.set(item, item.values()) + return true + } + this.remove = function (item) { if (item.elm.parentNode === list.list) { - list.list.removeChild(item.elm); + list.list.removeChild(item.elm) } - }; - this.show = function(item) { - templater.create(item); - list.list.appendChild(item.elm); - }; - this.hide = function(item) { + } + this.show = function (item) { + templater.create(item) + list.list.appendChild(item.elm) + } + this.hide = function (item) { if (item.elm !== undefined && item.elm.parentNode === list.list) { - list.list.removeChild(item.elm); + list.list.removeChild(item.elm) } - }; - this.clear = function() { + } + this.clear = function () { /* .innerHTML = ''; fucks up IE */ if (list.list.hasChildNodes()) { - while (list.list.childNodes.length >= 1) - { - list.list.removeChild(list.list.firstChild); + while (list.list.childNodes.length >= 1) { + list.list.removeChild(list.list.firstChild) } } - }; + } - init(); -}; + init() +} -module.exports = function(list) { - return new Templater(list); -}; +module.exports = function (list) { + return new Templater(list) +} diff --git a/src/utils/classes.js b/src/utils/classes.js index a48abba9..523f277d 100644 --- a/src/utils/classes.js +++ b/src/utils/classes.js @@ -2,19 +2,19 @@ * Module dependencies. */ -var index = require('./index-of'); +var index = require('./index-of') /** * Whitespace regexp. */ -var re = /\s+/; +var re = /\s+/ /** * toString reference. */ -var toString = Object.prototype.toString; +var toString = Object.prototype.toString /** * Wrap `el` in a `ClassList`. @@ -24,9 +24,9 @@ var toString = Object.prototype.toString; * @api public */ -module.exports = function(el){ - return new ClassList(el); -}; +module.exports = function (el) { + return new ClassList(el) +} /** * Initialize a new ClassList for `el`. @@ -37,10 +37,10 @@ module.exports = function(el){ function ClassList(el) { if (!el || !el.nodeType) { - throw new Error('A DOM element reference is required'); + throw new Error('A DOM element reference is required') } - this.el = el; - this.list = el.classList; + this.el = el + this.list = el.classList } /** @@ -51,20 +51,20 @@ function ClassList(el) { * @api public */ -ClassList.prototype.add = function(name){ +ClassList.prototype.add = function (name) { // classList if (this.list) { - this.list.add(name); - return this; + this.list.add(name) + return this } // fallback - var arr = this.array(); - var i = index(arr, name); - if (!~i) arr.push(name); - this.el.className = arr.join(' '); - return this; -}; + var arr = this.array() + var i = index(arr, name) + if (!~i) arr.push(name) + this.el.className = arr.join(' ') + return this +} /** * Remove class `name` when present, or @@ -76,21 +76,20 @@ ClassList.prototype.add = function(name){ * @api public */ -ClassList.prototype.remove = function(name){ +ClassList.prototype.remove = function (name) { // classList if (this.list) { - this.list.remove(name); - return this; + this.list.remove(name) + return this } // fallback - var arr = this.array(); - var i = index(arr, name); - if (~i) arr.splice(i, 1); - this.el.className = arr.join(' '); - return this; -}; - + var arr = this.array() + var i = index(arr, name) + if (~i) arr.splice(i, 1) + this.el.className = arr.join(' ') + return this +} /** * Toggle class `name`, can force state via `force`. @@ -104,36 +103,36 @@ ClassList.prototype.remove = function(name){ * @api public */ -ClassList.prototype.toggle = function(name, force){ +ClassList.prototype.toggle = function (name, force) { // classList if (this.list) { - if ("undefined" !== typeof force) { + if ('undefined' !== typeof force) { if (force !== this.list.toggle(name, force)) { - this.list.toggle(name); // toggle again to correct + this.list.toggle(name) // toggle again to correct } } else { - this.list.toggle(name); + this.list.toggle(name) } - return this; + return this } // fallback - if ("undefined" !== typeof force) { + if ('undefined' !== typeof force) { if (!force) { - this.remove(name); + this.remove(name) } else { - this.add(name); + this.add(name) } } else { if (this.has(name)) { - this.remove(name); + this.remove(name) } else { - this.add(name); + this.add(name) } } - return this; -}; + return this +} /** * Return an array of classes. @@ -142,13 +141,13 @@ ClassList.prototype.toggle = function(name, force){ * @api public */ -ClassList.prototype.array = function(){ - var className = this.el.getAttribute('class') || ''; - var str = className.replace(/^\s+|\s+$/g, ''); - var arr = str.split(re); - if ('' === arr[0]) arr.shift(); - return arr; -}; +ClassList.prototype.array = function () { + var className = this.el.getAttribute('class') || '' + var str = className.replace(/^\s+|\s+$/g, '') + var arr = str.split(re) + if ('' === arr[0]) arr.shift() + return arr +} /** * Check if class `name` is present. @@ -158,7 +157,6 @@ ClassList.prototype.array = function(){ * @api public */ -ClassList.prototype.has = -ClassList.prototype.contains = function(name){ - return this.list ? this.list.contains(name) : !! ~index(this.array(), name); -}; +ClassList.prototype.has = ClassList.prototype.contains = function (name) { + return this.list ? this.list.contains(name) : !!~index(this.array(), name) +} diff --git a/src/utils/events.js b/src/utils/events.js index 21695985..30aa97ce 100644 --- a/src/utils/events.js +++ b/src/utils/events.js @@ -1,7 +1,7 @@ var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', - unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', - prefix = bind !== 'addEventListener' ? 'on' : '', - toArray = require('./to-array'); + unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', + prefix = bind !== 'addEventListener' ? 'on' : '', + toArray = require('./to-array') /** * Bind `el` event `type` to `fn`. @@ -13,12 +13,12 @@ var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', * @api public */ -exports.bind = function(el, type, fn, capture){ - el = toArray(el); - for ( var i = 0; i < el.length; i++ ) { - el[i][bind](prefix + type, fn, capture || false); +exports.bind = function (el, type, fn, capture) { + el = toArray(el) + for (var i = 0; i < el.length; i++) { + el[i][bind](prefix + type, fn, capture || false) } -}; +} /** * Unbind `el` event `type`'s callback `fn`. @@ -30,9 +30,9 @@ exports.bind = function(el, type, fn, capture){ * @api public */ -exports.unbind = function(el, type, fn, capture){ - el = toArray(el); - for ( var i = 0; i < el.length; i++ ) { - el[i][unbind](prefix + type, fn, capture || false); +exports.unbind = function (el, type, fn, capture) { + el = toArray(el) + for (var i = 0; i < el.length; i++) { + el[i][unbind](prefix + type, fn, capture || false) } -}; +} diff --git a/src/utils/extend.js b/src/utils/extend.js index 9fc60375..38cbe56b 100644 --- a/src/utils/extend.js +++ b/src/utils/extend.js @@ -2,17 +2,17 @@ * Source: https://github.com/segmentio/extend */ -module.exports = function extend (object) { - // Takes an unlimited number of extenders. - var args = Array.prototype.slice.call(arguments, 1); +module.exports = function extend(object) { + // Takes an unlimited number of extenders. + var args = Array.prototype.slice.call(arguments, 1) - // For each extender, copy their properties on our object. - for (var i = 0, source; source = args[i]; i++) { - if (!source) continue; - for (var property in source) { - object[property] = source[property]; - } + // For each extender, copy their properties on our object. + for (var i = 0, source; (source = args[i]); i++) { + if (!source) continue + for (var property in source) { + object[property] = source[property] } + } - return object; -}; + return object +} diff --git a/src/utils/fuzzy.js b/src/utils/fuzzy.js index b63787f3..c123dfc4 100644 --- a/src/utils/fuzzy.js +++ b/src/utils/fuzzy.js @@ -1,123 +1,123 @@ -module.exports = function(text, pattern, options) { - // Aproximately where in the text is the pattern expected to be found? - var Match_Location = options.location || 0; +module.exports = function (text, pattern, options) { + // Aproximately where in the text is the pattern expected to be found? + var Match_Location = options.location || 0 - //Determines how close the match must be to the fuzzy location (specified above). An exact letter match which is 'distance' characters away from the fuzzy location would score as a complete mismatch. A distance of '0' requires the match be at the exact location specified, a threshold of '1000' would require a perfect match to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. - var Match_Distance = options.distance || 100; + //Determines how close the match must be to the fuzzy location (specified above). An exact letter match which is 'distance' characters away from the fuzzy location would score as a complete mismatch. A distance of '0' requires the match be at the exact location specified, a threshold of '1000' would require a perfect match to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. + var Match_Distance = options.distance || 100 - // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match (of both letters and location), a threshold of '1.0' would match anything. - var Match_Threshold = options.threshold || 0.4; + // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match (of both letters and location), a threshold of '1.0' would match anything. + var Match_Threshold = options.threshold || 0.4 - if (pattern === text) return true; // Exact match - if (pattern.length > 32) return false; // This algorithm cannot be used + if (pattern === text) return true // Exact match + if (pattern.length > 32) return false // This algorithm cannot be used - // Set starting location at beginning text and initialise the alphabet. - var loc = Match_Location, - s = (function() { - var q = {}, - i; + // Set starting location at beginning text and initialise the alphabet. + var loc = Match_Location, + s = (function () { + var q = {}, + i - for (i = 0; i < pattern.length; i++) { - q[pattern.charAt(i)] = 0; - } + for (i = 0; i < pattern.length; i++) { + q[pattern.charAt(i)] = 0 + } - for (i = 0; i < pattern.length; i++) { - q[pattern.charAt(i)] |= 1 << (pattern.length - i - 1); - } + for (i = 0; i < pattern.length; i++) { + q[pattern.charAt(i)] |= 1 << (pattern.length - i - 1) + } - return q; - }()); + return q + })() - // Compute and return the score for a match with e errors and x location. - // Accesses loc and pattern through being a closure. + // Compute and return the score for a match with e errors and x location. + // Accesses loc and pattern through being a closure. - function match_bitapScore_(e, x) { - var accuracy = e / pattern.length, - proximity = Math.abs(loc - x); + function match_bitapScore_(e, x) { + var accuracy = e / pattern.length, + proximity = Math.abs(loc - x) - if (!Match_Distance) { - // Dodge divide by zero error. - return proximity ? 1.0 : accuracy; - } - return accuracy + (proximity / Match_Distance); + if (!Match_Distance) { + // Dodge divide by zero error. + return proximity ? 1.0 : accuracy } + return accuracy + proximity / Match_Distance + } - var score_threshold = Match_Threshold, // Highest score beyond which we give up. - best_loc = text.indexOf(pattern, loc); // Is there a nearby exact match? (speedup) + var score_threshold = Match_Threshold, // Highest score beyond which we give up. + best_loc = text.indexOf(pattern, loc) // Is there a nearby exact match? (speedup) - if (best_loc != -1) { - score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold); - // What about in the other direction? (speedup) - best_loc = text.lastIndexOf(pattern, loc + pattern.length); + if (best_loc != -1) { + score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold) + // What about in the other direction? (speedup) + best_loc = text.lastIndexOf(pattern, loc + pattern.length) - if (best_loc != -1) { - score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold); - } + if (best_loc != -1) { + score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold) } - - // Initialise the bit arrays. - var matchmask = 1 << (pattern.length - 1); - best_loc = -1; - - var bin_min, bin_mid; - var bin_max = pattern.length + text.length; - var last_rd; - for (var d = 0; d < pattern.length; d++) { - // Scan for the best match; each iteration allows for one more error. - // Run a binary search to determine how far from 'loc' we can stray at this - // error level. - bin_min = 0; - bin_mid = bin_max; - while (bin_min < bin_mid) { - if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) { - bin_min = bin_mid; - } else { - bin_max = bin_mid; - } - bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min); - } - // Use the result from this iteration as the maximum for the next. - bin_max = bin_mid; - var start = Math.max(1, loc - bin_mid + 1); - var finish = Math.min(loc + bin_mid, text.length) + pattern.length; - - var rd = Array(finish + 2); - rd[finish + 1] = (1 << d) - 1; - for (var j = finish; j >= start; j--) { - // The alphabet (s) is a sparse hash, so the following line generates - // warnings. - var charMatch = s[text.charAt(j - 1)]; - if (d === 0) { // First pass: exact match. - rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; - } else { // Subsequent passes: fuzzy match. - rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) | - (((last_rd[j + 1] | last_rd[j]) << 1) | 1) | - last_rd[j + 1]; - } - if (rd[j] & matchmask) { - var score = match_bitapScore_(d, j - 1); - // This match will almost certainly be better than any existing match. - // But check anyway. - if (score <= score_threshold) { - // Told you so. - score_threshold = score; - best_loc = j - 1; - if (best_loc > loc) { - // When passing loc, don't exceed our current distance from loc. - start = Math.max(1, 2 * loc - best_loc); - } else { - // Already passed loc, downhill from here on in. - break; - } - } - } - } - // No hope for a (better) match at greater error levels. - if (match_bitapScore_(d + 1, loc) > score_threshold) { - break; + } + + // Initialise the bit arrays. + var matchmask = 1 << (pattern.length - 1) + best_loc = -1 + + var bin_min, bin_mid + var bin_max = pattern.length + text.length + var last_rd + for (var d = 0; d < pattern.length; d++) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from 'loc' we can stray at this + // error level. + bin_min = 0 + bin_mid = bin_max + while (bin_min < bin_mid) { + if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) { + bin_min = bin_mid + } else { + bin_max = bin_mid + } + bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min) + } + // Use the result from this iteration as the maximum for the next. + bin_max = bin_mid + var start = Math.max(1, loc - bin_mid + 1) + var finish = Math.min(loc + bin_mid, text.length) + pattern.length + + var rd = Array(finish + 2) + rd[finish + 1] = (1 << d) - 1 + for (var j = finish; j >= start; j--) { + // The alphabet (s) is a sparse hash, so the following line generates + // warnings. + var charMatch = s[text.charAt(j - 1)] + if (d === 0) { + // First pass: exact match. + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch + } else { + // Subsequent passes: fuzzy match. + rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) | (((last_rd[j + 1] | last_rd[j]) << 1) | 1) | last_rd[j + 1] + } + if (rd[j] & matchmask) { + var score = match_bitapScore_(d, j - 1) + // This match will almost certainly be better than any existing match. + // But check anyway. + if (score <= score_threshold) { + // Told you so. + score_threshold = score + best_loc = j - 1 + if (best_loc > loc) { + // When passing loc, don't exceed our current distance from loc. + start = Math.max(1, 2 * loc - best_loc) + } else { + // Already passed loc, downhill from here on in. + break + } } - last_rd = rd; + } + } + // No hope for a (better) match at greater error levels. + if (match_bitapScore_(d + 1, loc) > score_threshold) { + break } + last_rd = rd + } - return (best_loc < 0) ? false : true; -}; + return best_loc < 0 ? false : true +} diff --git a/src/utils/get-attribute.js b/src/utils/get-attribute.js index 729e6514..72b87ffc 100644 --- a/src/utils/get-attribute.js +++ b/src/utils/get-attribute.js @@ -9,18 +9,18 @@ * @api public */ -module.exports = function(el, attr) { - var result = (el.getAttribute && el.getAttribute(attr)) || null; - if( !result ) { - var attrs = el.attributes; - var length = attrs.length; - for(var i = 0; i < length; i++) { +module.exports = function (el, attr) { + var result = (el.getAttribute && el.getAttribute(attr)) || null + if (!result) { + var attrs = el.attributes + var length = attrs.length + for (var i = 0; i < length; i++) { if (attr[i] !== undefined) { - if(attr[i].nodeName === attr) { - result = attr[i].nodeValue; + if (attr[i].nodeName === attr) { + result = attr[i].nodeValue } } } } - return result; -}; + return result +} diff --git a/src/utils/get-by-class.js b/src/utils/get-by-class.js index 28fcb855..46926f65 100644 --- a/src/utils/get-by-class.js +++ b/src/utils/get-by-class.js @@ -12,52 +12,52 @@ * @api public */ -var getElementsByClassName = function(container, className, single) { +var getElementsByClassName = function (container, className, single) { if (single) { - return container.getElementsByClassName(className)[0]; + return container.getElementsByClassName(className)[0] } else { - return container.getElementsByClassName(className); + return container.getElementsByClassName(className) } -}; +} -var querySelector = function(container, className, single) { - className = '.' + className; +var querySelector = function (container, className, single) { + className = '.' + className if (single) { - return container.querySelector(className); + return container.querySelector(className) } else { - return container.querySelectorAll(className); + return container.querySelectorAll(className) } -}; +} -var polyfill = function(container, className, single) { +var polyfill = function (container, className, single) { var classElements = [], - tag = '*'; + tag = '*' - var els = container.getElementsByTagName(tag); - var elsLen = els.length; - var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)"); + var els = container.getElementsByTagName(tag) + var elsLen = els.length + var pattern = new RegExp('(^|\\s)' + className + '(\\s|$)') for (var i = 0, j = 0; i < elsLen; i++) { - if ( pattern.test(els[i].className) ) { + if (pattern.test(els[i].className)) { if (single) { - return els[i]; + return els[i] } else { - classElements[j] = els[i]; - j++; + classElements[j] = els[i] + j++ } } } - return classElements; -}; + return classElements +} -module.exports = (function() { - return function(container, className, single, options) { - options = options || {}; +module.exports = (function () { + return function (container, className, single, options) { + options = options || {} if ((options.test && options.getElementsByClassName) || (!options.test && document.getElementsByClassName)) { - return getElementsByClassName(container, className, single); + return getElementsByClassName(container, className, single) } else if ((options.test && options.querySelector) || (!options.test && document.querySelector)) { - return querySelector(container, className, single); + return querySelector(container, className, single) } else { - return polyfill(container, className, single); + return polyfill(container, className, single) } - }; -})(); + } +})() diff --git a/src/utils/index-of.js b/src/utils/index-of.js index 4c261619..64bd312c 100644 --- a/src/utils/index-of.js +++ b/src/utils/index-of.js @@ -1,9 +1,9 @@ -var indexOf = [].indexOf; +var indexOf = [].indexOf -module.exports = function(arr, obj){ - if (indexOf) return arr.indexOf(obj); +module.exports = function (arr, obj) { + if (indexOf) return arr.indexOf(obj) for (var i = 0; i < arr.length; ++i) { - if (arr[i] === obj) return i; + if (arr[i] === obj) return i } - return -1; -}; + return -1 +} diff --git a/src/utils/to-array.js b/src/utils/to-array.js index 9fac2610..cb2e6e8c 100644 --- a/src/utils/to-array.js +++ b/src/utils/to-array.js @@ -10,24 +10,24 @@ */ module.exports = function toArray(collection) { - if (typeof collection === 'undefined') return []; - if (collection === null) return [null]; - if (collection === window) return [window]; - if (typeof collection === 'string') return [collection]; - if (isArray(collection)) return collection; - if (typeof collection.length != 'number') return [collection]; - if (typeof collection === 'function' && collection instanceof Function) return [collection]; + if (typeof collection === 'undefined') return [] + if (collection === null) return [null] + if (collection === window) return [window] + if (typeof collection === 'string') return [collection] + if (isArray(collection)) return collection + if (typeof collection.length != 'number') return [collection] + if (typeof collection === 'function' && collection instanceof Function) return [collection] - var arr = []; + var arr = [] for (var i = 0; i < collection.length; i++) { if (Object.prototype.hasOwnProperty.call(collection, i) || i in collection) { - arr.push(collection[i]); + arr.push(collection[i]) } } - if (!arr.length) return []; - return arr; -}; + if (!arr.length) return [] + return arr +} function isArray(arr) { - return Object.prototype.toString.call(arr) === "[object Array]"; + return Object.prototype.toString.call(arr) === '[object Array]' } diff --git a/src/utils/to-string.js b/src/utils/to-string.js index cdda3bcf..8ec67ca0 100644 --- a/src/utils/to-string.js +++ b/src/utils/to-string.js @@ -1,6 +1,6 @@ -module.exports = function(s) { - s = (s === undefined) ? "" : s; - s = (s === null) ? "" : s; - s = s.toString(); - return s; -}; +module.exports = function (s) { + s = s === undefined ? '' : s + s = s === null ? '' : s + s = s.toString() + return s +}