From a9c4f54cd4d13eb0a19c1e11db6a96f4bd2354b3 Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 20 Oct 2021 22:45:53 +0100 Subject: [PATCH] . --- .../autocomplete_light/autocomplete_light.js | 461 + .../autocomplete_light.min.js | 1 + static/autocomplete_light/i18n/af.js | 2 + static/autocomplete_light/i18n/ar.js | 2 + static/autocomplete_light/i18n/az.js | 2 + static/autocomplete_light/i18n/bg.js | 2 + static/autocomplete_light/i18n/bn.js | 2 + static/autocomplete_light/i18n/bs.js | 2 + static/autocomplete_light/i18n/ca.js | 2 + static/autocomplete_light/i18n/cs.js | 2 + static/autocomplete_light/i18n/da.js | 2 + static/autocomplete_light/i18n/de.js | 2 + static/autocomplete_light/i18n/dsb.js | 2 + static/autocomplete_light/i18n/el.js | 2 + static/autocomplete_light/i18n/en.js | 2 + static/autocomplete_light/i18n/es.js | 2 + static/autocomplete_light/i18n/et.js | 2 + static/autocomplete_light/i18n/eu.js | 2 + static/autocomplete_light/i18n/fa.js | 2 + static/autocomplete_light/i18n/fi.js | 2 + static/autocomplete_light/i18n/fr.js | 2 + static/autocomplete_light/i18n/gl.js | 2 + static/autocomplete_light/i18n/he.js | 2 + static/autocomplete_light/i18n/hi.js | 2 + static/autocomplete_light/i18n/hr.js | 2 + static/autocomplete_light/i18n/hsb.js | 2 + static/autocomplete_light/i18n/hu.js | 2 + static/autocomplete_light/i18n/hy.js | 2 + static/autocomplete_light/i18n/id.js | 2 + static/autocomplete_light/i18n/is.js | 2 + static/autocomplete_light/i18n/it.js | 2 + static/autocomplete_light/i18n/ja.js | 2 + static/autocomplete_light/i18n/ka.js | 2 + static/autocomplete_light/i18n/km.js | 2 + static/autocomplete_light/i18n/ko.js | 2 + static/autocomplete_light/i18n/lt.js | 2 + static/autocomplete_light/i18n/lv.js | 2 + static/autocomplete_light/i18n/mk.js | 2 + static/autocomplete_light/i18n/ms.js | 2 + static/autocomplete_light/i18n/nb.js | 2 + static/autocomplete_light/i18n/ne.js | 2 + static/autocomplete_light/i18n/nl.js | 2 + static/autocomplete_light/i18n/pl.js | 2 + static/autocomplete_light/i18n/ps.js | 2 + static/autocomplete_light/i18n/pt-BR.js | 2 + static/autocomplete_light/i18n/pt.js | 2 + static/autocomplete_light/i18n/ro.js | 2 + static/autocomplete_light/i18n/ru.js | 2 + static/autocomplete_light/i18n/sk.js | 2 + static/autocomplete_light/i18n/sl.js | 2 + static/autocomplete_light/i18n/sq.js | 2 + static/autocomplete_light/i18n/sr-Cyrl.js | 2 + static/autocomplete_light/i18n/sr.js | 2 + static/autocomplete_light/i18n/sv.js | 2 + static/autocomplete_light/i18n/th.js | 2 + static/autocomplete_light/i18n/tk.js | 2 + static/autocomplete_light/i18n/tr.js | 2 + static/autocomplete_light/i18n/uk.js | 2 + static/autocomplete_light/i18n/vi.js | 2 + static/autocomplete_light/i18n/zh-CN.js | 2 + static/autocomplete_light/i18n/zh-TW.js | 2 + static/autocomplete_light/select2.css | 14 + static/autocomplete_light/select2.js | 122 + static/autocomplete_light/select2.min.js | 1 + .../vendor/select2/Gruntfile.js | 380 + .../vendor/select2/bower.json | 13 + .../vendor/select2/component.json | 19 + .../vendor/select2/composer.json | 25 + .../vendor/select2/dist/css/select2.css | 484 + .../vendor/select2/dist/css/select2.min.css | 1 + .../vendor/select2/dist/js/i18n/af.js | 3 + .../vendor/select2/dist/js/i18n/ar.js | 3 + .../vendor/select2/dist/js/i18n/az.js | 3 + .../vendor/select2/dist/js/i18n/bg.js | 3 + .../vendor/select2/dist/js/i18n/bs.js | 3 + .../vendor/select2/dist/js/i18n/ca.js | 3 + .../vendor/select2/dist/js/i18n/cs.js | 3 + .../vendor/select2/dist/js/i18n/da.js | 3 + .../vendor/select2/dist/js/i18n/de.js | 3 + .../vendor/select2/dist/js/i18n/dsb.js | 3 + .../vendor/select2/dist/js/i18n/el.js | 3 + .../vendor/select2/dist/js/i18n/en.js | 3 + .../vendor/select2/dist/js/i18n/es.js | 3 + .../vendor/select2/dist/js/i18n/et.js | 3 + .../vendor/select2/dist/js/i18n/eu.js | 3 + .../vendor/select2/dist/js/i18n/fa.js | 3 + .../vendor/select2/dist/js/i18n/fi.js | 3 + .../vendor/select2/dist/js/i18n/fr.js | 3 + .../vendor/select2/dist/js/i18n/gl.js | 3 + .../vendor/select2/dist/js/i18n/he.js | 3 + .../vendor/select2/dist/js/i18n/hi.js | 3 + .../vendor/select2/dist/js/i18n/hr.js | 3 + .../vendor/select2/dist/js/i18n/hsb.js | 3 + .../vendor/select2/dist/js/i18n/hu.js | 3 + .../vendor/select2/dist/js/i18n/hy.js | 3 + .../vendor/select2/dist/js/i18n/id.js | 3 + .../vendor/select2/dist/js/i18n/is.js | 3 + .../vendor/select2/dist/js/i18n/it.js | 3 + .../vendor/select2/dist/js/i18n/ja.js | 3 + .../vendor/select2/dist/js/i18n/km.js | 3 + .../vendor/select2/dist/js/i18n/ko.js | 3 + .../vendor/select2/dist/js/i18n/lt.js | 3 + .../vendor/select2/dist/js/i18n/lv.js | 3 + .../vendor/select2/dist/js/i18n/mk.js | 3 + .../vendor/select2/dist/js/i18n/ms.js | 3 + .../vendor/select2/dist/js/i18n/nb.js | 3 + .../vendor/select2/dist/js/i18n/nl.js | 3 + .../vendor/select2/dist/js/i18n/pl.js | 3 + .../vendor/select2/dist/js/i18n/ps.js | 3 + .../vendor/select2/dist/js/i18n/pt-BR.js | 3 + .../vendor/select2/dist/js/i18n/pt.js | 3 + .../vendor/select2/dist/js/i18n/ro.js | 3 + .../vendor/select2/dist/js/i18n/ru.js | 3 + .../vendor/select2/dist/js/i18n/sk.js | 3 + .../vendor/select2/dist/js/i18n/sl.js | 3 + .../vendor/select2/dist/js/i18n/sr-Cyrl.js | 3 + .../vendor/select2/dist/js/i18n/sr.js | 3 + .../vendor/select2/dist/js/i18n/sv.js | 3 + .../vendor/select2/dist/js/i18n/th.js | 3 + .../vendor/select2/dist/js/i18n/tk.js | 3 + .../vendor/select2/dist/js/i18n/tr.js | 3 + .../vendor/select2/dist/js/i18n/uk.js | 3 + .../vendor/select2/dist/js/i18n/vi.js | 3 + .../vendor/select2/dist/js/i18n/zh-CN.js | 3 + .../vendor/select2/dist/js/i18n/zh-TW.js | 3 + .../vendor/select2/dist/js/select2.full.js | 6559 ++++++++++ .../select2/dist/js/select2.full.min.js | 1 + .../vendor/select2/dist/js/select2.js | 5847 +++++++++ .../vendor/select2/dist/js/select2.min.js | 1 + .../vendor/select2/package.json | 74 + .../vendor/select2/select2.jquery.json | 32 + .../vendor/select2/src/js/banner.end.js | 6 + .../vendor/select2/src/js/banner.start.js | 6 + .../select2/src/js/jquery.mousewheel.shim.js | 6 + .../vendor/select2/src/js/jquery.select2.js | 58 + .../vendor/select2/src/js/jquery.shim.js | 14 + .../src/js/select2/compat/containerCss.js | 56 + .../src/js/select2/compat/dropdownCss.js | 56 + .../src/js/select2/compat/initSelection.js | 42 + .../src/js/select2/compat/inputData.js | 128 + .../select2/src/js/select2/compat/matcher.js | 42 + .../select2/src/js/select2/compat/query.js | 26 + .../select2/src/js/select2/compat/utils.js | 43 + .../vendor/select2/src/js/select2/core.js | 618 + .../select2/src/js/select2/data/ajax.js | 110 + .../select2/src/js/select2/data/array.js | 79 + .../select2/src/js/select2/data/base.js | 40 + .../src/js/select2/data/maximumInputLength.js | 31 + .../js/select2/data/maximumSelectionLength.js | 31 + .../src/js/select2/data/minimumInputLength.js | 30 + .../select2/src/js/select2/data/select.js | 285 + .../select2/src/js/select2/data/tags.js | 128 + .../select2/src/js/select2/data/tokenizer.js | 116 + .../vendor/select2/src/js/select2/defaults.js | 396 + .../select2/src/js/select2/diacritics.js | 847 ++ .../vendor/select2/src/js/select2/dropdown.js | 42 + .../src/js/select2/dropdown/attachBody.js | 222 + .../js/select2/dropdown/attachContainer.js | 18 + .../src/js/select2/dropdown/closeOnSelect.js | 35 + .../js/select2/dropdown/hidePlaceholder.js | 42 + .../src/js/select2/dropdown/infiniteScroll.js | 89 + .../dropdown/minimumResultsForSearch.js | 39 + .../select2/src/js/select2/dropdown/search.js | 102 + .../src/js/select2/dropdown/selectOnClose.js | 50 + .../js/select2/dropdown/stopPropagation.js | 38 + .../vendor/select2/src/js/select2/i18n/af.js | 44 + .../vendor/select2/src/js/select2/i18n/ar.js | 30 + .../vendor/select2/src/js/select2/i18n/az.js | 27 + .../vendor/select2/src/js/select2/i18n/bg.js | 47 + .../vendor/select2/src/js/select2/i18n/bs.js | 55 + .../vendor/select2/src/js/select2/i18n/ca.js | 52 + .../vendor/select2/src/js/select2/i18n/cs.js | 61 + .../vendor/select2/src/js/select2/i18n/da.js | 36 + .../vendor/select2/src/js/select2/i18n/de.js | 40 + .../vendor/select2/src/js/select2/i18n/dsb.js | 48 + .../vendor/select2/src/js/select2/i18n/el.js | 52 + .../vendor/select2/src/js/select2/i18n/en.js | 44 + .../vendor/select2/src/js/select2/i18n/es.js | 52 + .../vendor/select2/src/js/select2/i18n/et.js | 53 + .../vendor/select2/src/js/select2/i18n/eu.js | 51 + .../vendor/select2/src/js/select2/i18n/fa.js | 38 + .../vendor/select2/src/js/select2/i18n/fi.js | 30 + .../vendor/select2/src/js/select2/i18n/fr.js | 33 + .../vendor/select2/src/js/select2/i18n/gl.js | 39 + .../vendor/select2/src/js/select2/i18n/he.js | 56 + .../vendor/select2/src/js/select2/i18n/hi.js | 39 + .../vendor/select2/src/js/select2/i18n/hr.js | 44 + .../vendor/select2/src/js/select2/i18n/hsb.js | 48 + .../vendor/select2/src/js/select2/i18n/hu.js | 30 + .../vendor/select2/src/js/select2/i18n/hy.js | 38 + .../vendor/select2/src/js/select2/i18n/id.js | 30 + .../vendor/select2/src/js/select2/i18n/is.js | 41 + .../vendor/select2/src/js/select2/i18n/it.js | 48 + .../vendor/select2/src/js/select2/i18n/ja.js | 36 + .../vendor/select2/src/js/select2/i18n/km.js | 36 + .../vendor/select2/src/js/select2/i18n/ko.js | 36 + .../vendor/select2/src/js/select2/i18n/lt.js | 52 + .../vendor/select2/src/js/select2/i18n/lv.js | 51 + .../vendor/select2/src/js/select2/i18n/mk.js | 47 + .../vendor/select2/src/js/select2/i18n/ms.js | 30 + .../vendor/select2/src/js/select2/i18n/nb.js | 30 + .../vendor/select2/src/js/select2/i18n/nl.js | 43 + .../vendor/select2/src/js/select2/i18n/pl.js | 45 + .../vendor/select2/src/js/select2/i18n/ps.js | 45 + .../select2/src/js/select2/i18n/pt-BR.js | 46 + .../vendor/select2/src/js/select2/i18n/pt.js | 40 + .../vendor/select2/src/js/select2/i18n/ro.js | 46 + .../vendor/select2/src/js/select2/i18n/ru.js | 58 + .../vendor/select2/src/js/select2/i18n/sk.js | 59 + .../vendor/select2/src/js/select2/i18n/sl.js | 54 + .../select2/src/js/select2/i18n/sr-Cyrl.js | 55 + .../vendor/select2/src/js/select2/i18n/sr.js | 55 + .../vendor/select2/src/js/select2/i18n/sv.js | 37 + .../vendor/select2/src/js/select2/i18n/th.js | 36 + .../vendor/select2/src/js/select2/i18n/tk.js | 36 + .../vendor/select2/src/js/select2/i18n/tr.js | 36 + .../vendor/select2/src/js/select2/i18n/uk.js | 43 + .../vendor/select2/src/js/select2/i18n/vi.js | 37 + .../select2/src/js/select2/i18n/zh-CN.js | 36 + .../select2/src/js/select2/i18n/zh-TW.js | 33 + .../vendor/select2/src/js/select2/keys.js | 25 + .../vendor/select2/src/js/select2/options.js | 123 + .../vendor/select2/src/js/select2/results.js | 524 + .../src/js/select2/selection/allowClear.js | 111 + .../select2/src/js/select2/selection/base.js | 161 + .../src/js/select2/selection/clickMask.js | 29 + .../src/js/select2/selection/eventRelay.js | 48 + .../src/js/select2/selection/multiple.js | 111 + .../src/js/select2/selection/placeholder.js | 49 + .../src/js/select2/selection/search.js | 228 + .../src/js/select2/selection/single.js | 100 + .../js/select2/selection/stopPropagation.js | 38 + .../select2/src/js/select2/translation.js | 36 + .../vendor/select2/src/js/select2/utils.js | 337 + .../vendor/select2/src/js/wrapper.end.js | 12 + .../vendor/select2/src/js/wrapper.start.js | 38 + .../vendor/select2/tests/a11y/search-tests.js | 51 + .../select2/tests/a11y/selection-tests.js | 154 + .../vendor/select2/tests/data/array-tests.js | 329 + .../vendor/select2/tests/data/base-tests.js | 29 + .../select2/tests/data/inputData-tests.js | 158 + .../tests/data/maximumInputLength-tests.js | 138 + .../data/maximumSelectionLength-tests.js | 202 + .../tests/data/minimumInputLength-tests.js | 138 + .../vendor/select2/tests/data/select-tests.js | 554 + .../vendor/select2/tests/data/tags-tests.js | 276 + .../select2/tests/data/tokenizer-tests.js | 219 + .../tests/dropdown/dropdownCss-tests.js | 104 + .../tests/dropdown/positioning-tests.js | 177 + .../tests/dropdown/selectOnClose-tests.js | 137 + .../tests/dropdown/stopPropagation-tests.js | 33 + .../vendor/select2/tests/helpers.js | 46 + .../vendor/select2/tests/integration.html | 21 + .../select2/tests/integration/dom-changes.js | 257 + .../select2/tests/integration/jquery-calls.js | 98 + .../tests/integration/select2-methods.js | 139 + .../select2/tests/options/ajax-tests.js | 50 + .../select2/tests/options/data-tests.js | 44 + .../select2/tests/options/deprecated-tests.js | 250 + .../tests/options/translation-tests.js | 28 + .../select2/tests/options/width-tests.js | 66 + .../select2/tests/results/focusing-tests.js | 138 + .../tests/selection/allowClear-tests.js | 310 + .../tests/selection/containerCss-tests.js | 104 + .../select2/tests/selection/multiple-tests.js | 151 + .../tests/selection/placeholder-tests.js | 74 + .../select2/tests/selection/search-tests.js | 191 + .../select2/tests/selection/single-tests.js | 119 + .../tests/selection/stopPropagation-tests.js | 33 + .../vendor/select2/tests/unit.html | 97 + .../select2/tests/utils/decorator-tests.js | 189 + .../select2/tests/utils/escapeMarkup-tests.js | 36 + .../select2/tests/vendor/jquery-1.7.2.js | 9404 ++++++++++++++ .../select2/tests/vendor/qunit-1.23.1.css | 305 + .../select2/tests/vendor/qunit-1.23.1.js | 4334 +++++++ .../vendor/select2/vendor/jquery-2.1.0.js | 9111 +++++++++++++ static/vendor/select2/Gruntfile.js | 262 + static/vendor/select2/bower.json | 13 + static/vendor/select2/component.json | 19 + static/vendor/select2/composer.json | 22 + static/vendor/select2/dist/css/select2.css | 481 + .../vendor/select2/dist/css/select2.min.css | 1 + static/vendor/select2/dist/js/i18n/af.js | 3 + static/vendor/select2/dist/js/i18n/ar.js | 3 + static/vendor/select2/dist/js/i18n/az.js | 3 + static/vendor/select2/dist/js/i18n/bg.js | 3 + static/vendor/select2/dist/js/i18n/bn.js | 3 + static/vendor/select2/dist/js/i18n/bs.js | 3 + static/vendor/select2/dist/js/i18n/ca.js | 3 + static/vendor/select2/dist/js/i18n/cs.js | 3 + static/vendor/select2/dist/js/i18n/da.js | 3 + static/vendor/select2/dist/js/i18n/de.js | 3 + static/vendor/select2/dist/js/i18n/dsb.js | 3 + static/vendor/select2/dist/js/i18n/el.js | 3 + static/vendor/select2/dist/js/i18n/en.js | 3 + static/vendor/select2/dist/js/i18n/es.js | 3 + static/vendor/select2/dist/js/i18n/et.js | 3 + static/vendor/select2/dist/js/i18n/eu.js | 3 + static/vendor/select2/dist/js/i18n/fa.js | 3 + static/vendor/select2/dist/js/i18n/fi.js | 3 + static/vendor/select2/dist/js/i18n/fr.js | 3 + static/vendor/select2/dist/js/i18n/gl.js | 3 + static/vendor/select2/dist/js/i18n/he.js | 3 + static/vendor/select2/dist/js/i18n/hi.js | 3 + static/vendor/select2/dist/js/i18n/hr.js | 3 + static/vendor/select2/dist/js/i18n/hsb.js | 3 + static/vendor/select2/dist/js/i18n/hu.js | 3 + static/vendor/select2/dist/js/i18n/hy.js | 3 + static/vendor/select2/dist/js/i18n/id.js | 3 + static/vendor/select2/dist/js/i18n/is.js | 3 + static/vendor/select2/dist/js/i18n/it.js | 3 + static/vendor/select2/dist/js/i18n/ja.js | 3 + static/vendor/select2/dist/js/i18n/ka.js | 3 + static/vendor/select2/dist/js/i18n/km.js | 3 + static/vendor/select2/dist/js/i18n/ko.js | 3 + static/vendor/select2/dist/js/i18n/lt.js | 3 + static/vendor/select2/dist/js/i18n/lv.js | 3 + static/vendor/select2/dist/js/i18n/mk.js | 3 + static/vendor/select2/dist/js/i18n/ms.js | 3 + static/vendor/select2/dist/js/i18n/nb.js | 3 + static/vendor/select2/dist/js/i18n/ne.js | 3 + static/vendor/select2/dist/js/i18n/nl.js | 3 + static/vendor/select2/dist/js/i18n/pl.js | 3 + static/vendor/select2/dist/js/i18n/ps.js | 3 + static/vendor/select2/dist/js/i18n/pt-BR.js | 3 + static/vendor/select2/dist/js/i18n/pt.js | 3 + static/vendor/select2/dist/js/i18n/ro.js | 3 + static/vendor/select2/dist/js/i18n/ru.js | 3 + static/vendor/select2/dist/js/i18n/sk.js | 3 + static/vendor/select2/dist/js/i18n/sl.js | 3 + static/vendor/select2/dist/js/i18n/sq.js | 3 + static/vendor/select2/dist/js/i18n/sr-Cyrl.js | 3 + static/vendor/select2/dist/js/i18n/sr.js | 3 + static/vendor/select2/dist/js/i18n/sv.js | 3 + static/vendor/select2/dist/js/i18n/th.js | 3 + static/vendor/select2/dist/js/i18n/tk.js | 3 + static/vendor/select2/dist/js/i18n/tr.js | 3 + static/vendor/select2/dist/js/i18n/uk.js | 3 + static/vendor/select2/dist/js/i18n/vi.js | 3 + static/vendor/select2/dist/js/i18n/zh-CN.js | 3 + static/vendor/select2/dist/js/i18n/zh-TW.js | 3 + static/vendor/select2/dist/js/select2.full.js | 6749 ++++++++++ .../select2/dist/js/select2.full.min.js | 2 + static/vendor/select2/dist/js/select2.js | 6037 +++++++++ static/vendor/select2/dist/js/select2.min.js | 2 + .../select2/docs/announcements-4.0.html | 12 + static/vendor/select2/docs/community.html | 12 + static/vendor/select2/docs/examples.html | 12 + static/vendor/select2/docs/index.html | 12 + static/vendor/select2/docs/options-old.html | 12 + static/vendor/select2/docs/options.html | 12 + static/vendor/select2/package.json | 65 + static/vendor/select2/src/js/banner.end.js | 6 + static/vendor/select2/src/js/banner.start.js | 6 + .../select2/src/js/jquery.mousewheel.shim.js | 6 + .../vendor/select2/src/js/jquery.select2.js | 58 + static/vendor/select2/src/js/jquery.shim.js | 14 + .../src/js/select2/compat/containerCss.js | 56 + .../src/js/select2/compat/dropdownCss.js | 56 + .../src/js/select2/compat/initSelection.js | 42 + .../src/js/select2/compat/inputData.js | 128 + .../select2/src/js/select2/compat/matcher.js | 42 + .../select2/src/js/select2/compat/query.js | 26 + .../select2/src/js/select2/compat/utils.js | 43 + static/vendor/select2/src/js/select2/core.js | 624 + .../select2/src/js/select2/data/ajax.js | 110 + .../select2/src/js/select2/data/array.js | 83 + .../select2/src/js/select2/data/base.js | 40 + .../src/js/select2/data/maximumInputLength.js | 31 + .../js/select2/data/maximumSelectionLength.js | 54 + .../src/js/select2/data/minimumInputLength.js | 30 + .../select2/src/js/select2/data/select.js | 285 + .../select2/src/js/select2/data/tags.js | 126 + .../select2/src/js/select2/data/tokenizer.js | 116 + .../vendor/select2/src/js/select2/defaults.js | 457 + .../select2/src/js/select2/diacritics.js | 850 ++ .../vendor/select2/src/js/select2/dropdown.js | 42 + .../src/js/select2/dropdown/attachBody.js | 247 + .../js/select2/dropdown/attachContainer.js | 18 + .../src/js/select2/dropdown/closeOnSelect.js | 35 + .../js/select2/dropdown/hidePlaceholder.js | 42 + .../src/js/select2/dropdown/infiniteScroll.js | 92 + .../dropdown/minimumResultsForSearch.js | 39 + .../select2/src/js/select2/dropdown/search.js | 115 + .../src/js/select2/dropdown/selectOnClose.js | 50 + .../js/select2/dropdown/stopPropagation.js | 38 + .../vendor/select2/src/js/select2/i18n/af.js | 47 + .../vendor/select2/src/js/select2/i18n/ar.js | 33 + .../vendor/select2/src/js/select2/i18n/az.js | 30 + .../vendor/select2/src/js/select2/i18n/bg.js | 50 + .../vendor/select2/src/js/select2/i18n/bn.js | 45 + .../vendor/select2/src/js/select2/i18n/bs.js | 58 + .../vendor/select2/src/js/select2/i18n/ca.js | 55 + .../vendor/select2/src/js/select2/i18n/cs.js | 64 + .../vendor/select2/src/js/select2/i18n/da.js | 39 + .../vendor/select2/src/js/select2/i18n/de.js | 41 + .../vendor/select2/src/js/select2/i18n/dsb.js | 52 + .../vendor/select2/src/js/select2/i18n/el.js | 55 + .../vendor/select2/src/js/select2/i18n/en.js | 47 + .../vendor/select2/src/js/select2/i18n/es.js | 55 + .../vendor/select2/src/js/select2/i18n/et.js | 56 + .../vendor/select2/src/js/select2/i18n/eu.js | 54 + .../vendor/select2/src/js/select2/i18n/fa.js | 41 + .../vendor/select2/src/js/select2/i18n/fi.js | 33 + .../vendor/select2/src/js/select2/i18n/fr.js | 36 + .../vendor/select2/src/js/select2/i18n/gl.js | 42 + .../vendor/select2/src/js/select2/i18n/he.js | 59 + .../vendor/select2/src/js/select2/i18n/hi.js | 42 + .../vendor/select2/src/js/select2/i18n/hr.js | 47 + .../vendor/select2/src/js/select2/i18n/hsb.js | 52 + .../vendor/select2/src/js/select2/i18n/hu.js | 33 + .../vendor/select2/src/js/select2/i18n/hy.js | 41 + .../vendor/select2/src/js/select2/i18n/id.js | 33 + .../vendor/select2/src/js/select2/i18n/is.js | 44 + .../vendor/select2/src/js/select2/i18n/it.js | 51 + .../vendor/select2/src/js/select2/i18n/ja.js | 39 + .../vendor/select2/src/js/select2/i18n/ka.js | 40 + .../vendor/select2/src/js/select2/i18n/km.js | 39 + .../vendor/select2/src/js/select2/i18n/ko.js | 39 + .../vendor/select2/src/js/select2/i18n/lt.js | 55 + .../vendor/select2/src/js/select2/i18n/lv.js | 54 + .../vendor/select2/src/js/select2/i18n/mk.js | 50 + .../vendor/select2/src/js/select2/i18n/ms.js | 33 + .../vendor/select2/src/js/select2/i18n/nb.js | 33 + .../vendor/select2/src/js/select2/i18n/ne.js | 47 + .../vendor/select2/src/js/select2/i18n/nl.js | 46 + .../vendor/select2/src/js/select2/i18n/pl.js | 48 + .../vendor/select2/src/js/select2/i18n/ps.js | 48 + .../select2/src/js/select2/i18n/pt-BR.js | 49 + .../vendor/select2/src/js/select2/i18n/pt.js | 43 + .../vendor/select2/src/js/select2/i18n/ro.js | 49 + .../vendor/select2/src/js/select2/i18n/ru.js | 61 + .../vendor/select2/src/js/select2/i18n/sk.js | 62 + .../vendor/select2/src/js/select2/i18n/sl.js | 57 + .../vendor/select2/src/js/select2/i18n/sq.js | 48 + .../select2/src/js/select2/i18n/sr-Cyrl.js | 58 + .../vendor/select2/src/js/select2/i18n/sr.js | 58 + .../vendor/select2/src/js/select2/i18n/sv.js | 40 + .../vendor/select2/src/js/select2/i18n/th.js | 39 + .../vendor/select2/src/js/select2/i18n/tk.js | 40 + .../vendor/select2/src/js/select2/i18n/tr.js | 39 + .../vendor/select2/src/js/select2/i18n/uk.js | 46 + .../vendor/select2/src/js/select2/i18n/vi.js | 37 + .../select2/src/js/select2/i18n/zh-CN.js | 39 + .../select2/src/js/select2/i18n/zh-TW.js | 36 + static/vendor/select2/src/js/select2/keys.js | 25 + .../vendor/select2/src/js/select2/options.js | 142 + .../vendor/select2/src/js/select2/results.js | 535 + .../src/js/select2/selection/allowClear.js | 113 + .../select2/src/js/select2/selection/base.js | 157 + .../src/js/select2/selection/clickMask.js | 29 + .../src/js/select2/selection/eventRelay.js | 48 + .../src/js/select2/selection/multiple.js | 116 + .../src/js/select2/selection/placeholder.js | 49 + .../src/js/select2/selection/search.js | 236 + .../src/js/select2/selection/single.js | 107 + .../js/select2/selection/stopPropagation.js | 38 + .../select2/src/js/select2/translation.js | 36 + static/vendor/select2/src/js/select2/utils.js | 340 + static/vendor/select2/src/js/wrapper.end.js | 12 + static/vendor/select2/src/js/wrapper.start.js | 38 + .../select2/tests/a11y/selection-tests.js | 186 + .../vendor/select2/tests/data/array-tests.js | 386 + .../vendor/select2/tests/data/base-tests.js | 29 + .../select2/tests/data/inputData-tests.js | 173 + .../tests/data/maximumInputLength-tests.js | 138 + .../data/maximumSelectionLength-tests.js | 152 + .../tests/data/minimumInputLength-tests.js | 138 + .../vendor/select2/tests/data/select-tests.js | 557 + .../vendor/select2/tests/data/tags-tests.js | 276 + .../select2/tests/data/tokenizer-tests.js | 219 + .../tests/dropdown/dropdownCss-tests.js | 104 + .../tests/dropdown/dropdownParent-tests.js | 83 + .../tests/dropdown/positioning-tests.js | 177 + .../tests/dropdown/search-a11y-tests.js | 185 + .../tests/dropdown/selectOnClose-tests.js | 137 + .../tests/dropdown/stopPropagation-tests.js | 33 + static/vendor/select2/tests/helpers.js | 50 + .../vendor/select2/tests/integration-jq1.html | 21 + .../vendor/select2/tests/integration-jq2.html | 21 + .../vendor/select2/tests/integration-jq3.html | 21 + .../select2/tests/integration/dom-changes.js | 288 + .../select2/tests/integration/jquery-calls.js | 98 + .../tests/integration/select2-methods.js | 139 + .../select2/tests/options/ajax-tests.js | 50 + .../select2/tests/options/data-tests.js | 44 + .../select2/tests/options/deprecated-tests.js | 250 + .../tests/options/translation-tests.js | 288 + .../select2/tests/options/width-tests.js | 84 + .../select2/tests/results/a11y-tests.js | 25 + .../select2/tests/results/focusing-tests.js | 241 + .../tests/results/infiniteScroll-tests.js | 126 + .../select2/tests/results/option-tests.js | 116 + .../tests/selection/allowClear-tests.js | 400 + .../tests/selection/containerCss-tests.js | 104 + .../select2/tests/selection/focusing-tests.js | 41 + .../select2/tests/selection/multiple-tests.js | 258 + .../tests/selection/placeholder-tests.js | 74 + .../tests/selection/search-a11y-tests.js | 217 + .../selection/search-placeholder-tests.js | 55 + .../select2/tests/selection/search-tests.js | 277 + .../select2/tests/selection/single-tests.js | 227 + .../tests/selection/stopPropagation-tests.js | 33 + static/vendor/select2/tests/unit-jq1.html | 105 + static/vendor/select2/tests/unit-jq2.html | 105 + static/vendor/select2/tests/unit-jq3.html | 105 + .../vendor/select2/tests/utils/data-tests.js | 36 + .../select2/tests/utils/decorator-tests.js | 189 + .../select2/tests/utils/escapeMarkup-tests.js | 36 + .../select2/tests/vendor/jquery-1.7.2.js | 9404 ++++++++++++++ .../select2/tests/vendor/jquery-2.2.4.js | 9814 ++++++++++++++ .../select2/tests/vendor/jquery-3.4.1.js | 10598 ++++++++++++++++ .../select2/tests/vendor/qunit-1.23.1.css | 305 + .../select2/tests/vendor/qunit-1.23.1.js | 4334 +++++++ 514 files changed, 115006 insertions(+) create mode 100644 static/autocomplete_light/autocomplete_light.js create mode 100644 static/autocomplete_light/autocomplete_light.min.js create mode 100644 static/autocomplete_light/i18n/af.js create mode 100644 static/autocomplete_light/i18n/ar.js create mode 100644 static/autocomplete_light/i18n/az.js create mode 100644 static/autocomplete_light/i18n/bg.js create mode 100644 static/autocomplete_light/i18n/bn.js create mode 100644 static/autocomplete_light/i18n/bs.js create mode 100644 static/autocomplete_light/i18n/ca.js create mode 100644 static/autocomplete_light/i18n/cs.js create mode 100644 static/autocomplete_light/i18n/da.js create mode 100644 static/autocomplete_light/i18n/de.js create mode 100644 static/autocomplete_light/i18n/dsb.js create mode 100644 static/autocomplete_light/i18n/el.js create mode 100644 static/autocomplete_light/i18n/en.js create mode 100644 static/autocomplete_light/i18n/es.js create mode 100644 static/autocomplete_light/i18n/et.js create mode 100644 static/autocomplete_light/i18n/eu.js create mode 100644 static/autocomplete_light/i18n/fa.js create mode 100644 static/autocomplete_light/i18n/fi.js create mode 100644 static/autocomplete_light/i18n/fr.js create mode 100644 static/autocomplete_light/i18n/gl.js create mode 100644 static/autocomplete_light/i18n/he.js create mode 100644 static/autocomplete_light/i18n/hi.js create mode 100644 static/autocomplete_light/i18n/hr.js create mode 100644 static/autocomplete_light/i18n/hsb.js create mode 100644 static/autocomplete_light/i18n/hu.js create mode 100644 static/autocomplete_light/i18n/hy.js create mode 100644 static/autocomplete_light/i18n/id.js create mode 100644 static/autocomplete_light/i18n/is.js create mode 100644 static/autocomplete_light/i18n/it.js create mode 100644 static/autocomplete_light/i18n/ja.js create mode 100644 static/autocomplete_light/i18n/ka.js create mode 100644 static/autocomplete_light/i18n/km.js create mode 100644 static/autocomplete_light/i18n/ko.js create mode 100644 static/autocomplete_light/i18n/lt.js create mode 100644 static/autocomplete_light/i18n/lv.js create mode 100644 static/autocomplete_light/i18n/mk.js create mode 100644 static/autocomplete_light/i18n/ms.js create mode 100644 static/autocomplete_light/i18n/nb.js create mode 100644 static/autocomplete_light/i18n/ne.js create mode 100644 static/autocomplete_light/i18n/nl.js create mode 100644 static/autocomplete_light/i18n/pl.js create mode 100644 static/autocomplete_light/i18n/ps.js create mode 100644 static/autocomplete_light/i18n/pt-BR.js create mode 100644 static/autocomplete_light/i18n/pt.js create mode 100644 static/autocomplete_light/i18n/ro.js create mode 100644 static/autocomplete_light/i18n/ru.js create mode 100644 static/autocomplete_light/i18n/sk.js create mode 100644 static/autocomplete_light/i18n/sl.js create mode 100644 static/autocomplete_light/i18n/sq.js create mode 100644 static/autocomplete_light/i18n/sr-Cyrl.js create mode 100644 static/autocomplete_light/i18n/sr.js create mode 100644 static/autocomplete_light/i18n/sv.js create mode 100644 static/autocomplete_light/i18n/th.js create mode 100644 static/autocomplete_light/i18n/tk.js create mode 100644 static/autocomplete_light/i18n/tr.js create mode 100644 static/autocomplete_light/i18n/uk.js create mode 100644 static/autocomplete_light/i18n/vi.js create mode 100644 static/autocomplete_light/i18n/zh-CN.js create mode 100644 static/autocomplete_light/i18n/zh-TW.js create mode 100644 static/autocomplete_light/select2.css create mode 100644 static/autocomplete_light/select2.js create mode 100644 static/autocomplete_light/select2.min.js create mode 100644 static/autocomplete_light/vendor/select2/Gruntfile.js create mode 100644 static/autocomplete_light/vendor/select2/bower.json create mode 100644 static/autocomplete_light/vendor/select2/component.json create mode 100644 static/autocomplete_light/vendor/select2/composer.json create mode 100644 static/autocomplete_light/vendor/select2/dist/css/select2.css create mode 100644 static/autocomplete_light/vendor/select2/dist/css/select2.min.css create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/af.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ar.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/az.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/bg.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/bs.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ca.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/cs.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/da.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/de.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/dsb.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/el.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/en.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/es.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/et.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/eu.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/fa.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/fi.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/fr.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/gl.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/he.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/hi.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/hr.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/hsb.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/hu.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/hy.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/id.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/is.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/it.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ja.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/km.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ko.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/lt.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/lv.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/mk.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ms.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/nb.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/nl.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/pl.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ps.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/pt-BR.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/pt.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ro.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/ru.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/sk.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/sl.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/sr-Cyrl.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/sr.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/sv.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/th.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/tk.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/tr.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/uk.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/vi.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/zh-CN.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/i18n/zh-TW.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/select2.full.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/select2.full.min.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/select2.js create mode 100644 static/autocomplete_light/vendor/select2/dist/js/select2.min.js create mode 100644 static/autocomplete_light/vendor/select2/package.json create mode 100644 static/autocomplete_light/vendor/select2/select2.jquery.json create mode 100644 static/autocomplete_light/vendor/select2/src/js/banner.end.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/banner.start.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/jquery.mousewheel.shim.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/jquery.select2.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/jquery.shim.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/containerCss.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/dropdownCss.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/initSelection.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/inputData.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/matcher.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/query.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/compat/utils.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/core.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/ajax.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/array.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/base.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/maximumInputLength.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/maximumSelectionLength.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/minimumInputLength.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/select.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/tags.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/data/tokenizer.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/defaults.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/diacritics.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/attachBody.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/attachContainer.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/closeOnSelect.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/hidePlaceholder.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/infiniteScroll.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/minimumResultsForSearch.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/search.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/selectOnClose.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/dropdown/stopPropagation.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/af.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ar.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/az.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/bg.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/bs.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ca.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/cs.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/da.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/de.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/dsb.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/el.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/en.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/es.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/et.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/eu.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/fa.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/fi.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/fr.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/gl.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/he.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/hi.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/hr.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/hsb.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/hu.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/hy.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/id.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/is.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/it.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ja.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/km.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ko.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/lt.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/lv.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/mk.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ms.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/nb.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/nl.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/pl.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ps.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/pt-BR.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/pt.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ro.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/ru.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/sk.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/sl.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/sr-Cyrl.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/sr.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/sv.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/th.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/tk.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/tr.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/uk.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/vi.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/zh-CN.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/i18n/zh-TW.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/keys.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/options.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/results.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/allowClear.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/base.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/clickMask.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/eventRelay.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/multiple.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/placeholder.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/search.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/single.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/selection/stopPropagation.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/translation.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/select2/utils.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/wrapper.end.js create mode 100644 static/autocomplete_light/vendor/select2/src/js/wrapper.start.js create mode 100644 static/autocomplete_light/vendor/select2/tests/a11y/search-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/a11y/selection-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/array-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/base-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/inputData-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/maximumInputLength-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/maximumSelectionLength-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/minimumInputLength-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/select-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/tags-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/data/tokenizer-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/dropdown/dropdownCss-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/dropdown/positioning-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/dropdown/selectOnClose-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/dropdown/stopPropagation-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/helpers.js create mode 100644 static/autocomplete_light/vendor/select2/tests/integration.html create mode 100644 static/autocomplete_light/vendor/select2/tests/integration/dom-changes.js create mode 100644 static/autocomplete_light/vendor/select2/tests/integration/jquery-calls.js create mode 100644 static/autocomplete_light/vendor/select2/tests/integration/select2-methods.js create mode 100644 static/autocomplete_light/vendor/select2/tests/options/ajax-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/options/data-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/options/deprecated-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/options/translation-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/options/width-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/results/focusing-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/allowClear-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/containerCss-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/multiple-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/placeholder-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/search-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/single-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/selection/stopPropagation-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/unit.html create mode 100644 static/autocomplete_light/vendor/select2/tests/utils/decorator-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/utils/escapeMarkup-tests.js create mode 100644 static/autocomplete_light/vendor/select2/tests/vendor/jquery-1.7.2.js create mode 100644 static/autocomplete_light/vendor/select2/tests/vendor/qunit-1.23.1.css create mode 100644 static/autocomplete_light/vendor/select2/tests/vendor/qunit-1.23.1.js create mode 100644 static/autocomplete_light/vendor/select2/vendor/jquery-2.1.0.js create mode 100644 static/vendor/select2/Gruntfile.js create mode 100644 static/vendor/select2/bower.json create mode 100644 static/vendor/select2/component.json create mode 100644 static/vendor/select2/composer.json create mode 100644 static/vendor/select2/dist/css/select2.css create mode 100644 static/vendor/select2/dist/css/select2.min.css create mode 100644 static/vendor/select2/dist/js/i18n/af.js create mode 100644 static/vendor/select2/dist/js/i18n/ar.js create mode 100644 static/vendor/select2/dist/js/i18n/az.js create mode 100644 static/vendor/select2/dist/js/i18n/bg.js create mode 100644 static/vendor/select2/dist/js/i18n/bn.js create mode 100644 static/vendor/select2/dist/js/i18n/bs.js create mode 100644 static/vendor/select2/dist/js/i18n/ca.js create mode 100644 static/vendor/select2/dist/js/i18n/cs.js create mode 100644 static/vendor/select2/dist/js/i18n/da.js create mode 100644 static/vendor/select2/dist/js/i18n/de.js create mode 100644 static/vendor/select2/dist/js/i18n/dsb.js create mode 100644 static/vendor/select2/dist/js/i18n/el.js create mode 100644 static/vendor/select2/dist/js/i18n/en.js create mode 100644 static/vendor/select2/dist/js/i18n/es.js create mode 100644 static/vendor/select2/dist/js/i18n/et.js create mode 100644 static/vendor/select2/dist/js/i18n/eu.js create mode 100644 static/vendor/select2/dist/js/i18n/fa.js create mode 100644 static/vendor/select2/dist/js/i18n/fi.js create mode 100644 static/vendor/select2/dist/js/i18n/fr.js create mode 100644 static/vendor/select2/dist/js/i18n/gl.js create mode 100644 static/vendor/select2/dist/js/i18n/he.js create mode 100644 static/vendor/select2/dist/js/i18n/hi.js create mode 100644 static/vendor/select2/dist/js/i18n/hr.js create mode 100644 static/vendor/select2/dist/js/i18n/hsb.js create mode 100644 static/vendor/select2/dist/js/i18n/hu.js create mode 100644 static/vendor/select2/dist/js/i18n/hy.js create mode 100644 static/vendor/select2/dist/js/i18n/id.js create mode 100644 static/vendor/select2/dist/js/i18n/is.js create mode 100644 static/vendor/select2/dist/js/i18n/it.js create mode 100644 static/vendor/select2/dist/js/i18n/ja.js create mode 100644 static/vendor/select2/dist/js/i18n/ka.js create mode 100644 static/vendor/select2/dist/js/i18n/km.js create mode 100644 static/vendor/select2/dist/js/i18n/ko.js create mode 100644 static/vendor/select2/dist/js/i18n/lt.js create mode 100644 static/vendor/select2/dist/js/i18n/lv.js create mode 100644 static/vendor/select2/dist/js/i18n/mk.js create mode 100644 static/vendor/select2/dist/js/i18n/ms.js create mode 100644 static/vendor/select2/dist/js/i18n/nb.js create mode 100644 static/vendor/select2/dist/js/i18n/ne.js create mode 100644 static/vendor/select2/dist/js/i18n/nl.js create mode 100644 static/vendor/select2/dist/js/i18n/pl.js create mode 100644 static/vendor/select2/dist/js/i18n/ps.js create mode 100644 static/vendor/select2/dist/js/i18n/pt-BR.js create mode 100644 static/vendor/select2/dist/js/i18n/pt.js create mode 100644 static/vendor/select2/dist/js/i18n/ro.js create mode 100644 static/vendor/select2/dist/js/i18n/ru.js create mode 100644 static/vendor/select2/dist/js/i18n/sk.js create mode 100644 static/vendor/select2/dist/js/i18n/sl.js create mode 100644 static/vendor/select2/dist/js/i18n/sq.js create mode 100644 static/vendor/select2/dist/js/i18n/sr-Cyrl.js create mode 100644 static/vendor/select2/dist/js/i18n/sr.js create mode 100644 static/vendor/select2/dist/js/i18n/sv.js create mode 100644 static/vendor/select2/dist/js/i18n/th.js create mode 100644 static/vendor/select2/dist/js/i18n/tk.js create mode 100644 static/vendor/select2/dist/js/i18n/tr.js create mode 100644 static/vendor/select2/dist/js/i18n/uk.js create mode 100644 static/vendor/select2/dist/js/i18n/vi.js create mode 100644 static/vendor/select2/dist/js/i18n/zh-CN.js create mode 100644 static/vendor/select2/dist/js/i18n/zh-TW.js create mode 100644 static/vendor/select2/dist/js/select2.full.js create mode 100644 static/vendor/select2/dist/js/select2.full.min.js create mode 100644 static/vendor/select2/dist/js/select2.js create mode 100644 static/vendor/select2/dist/js/select2.min.js create mode 100644 static/vendor/select2/docs/announcements-4.0.html create mode 100644 static/vendor/select2/docs/community.html create mode 100644 static/vendor/select2/docs/examples.html create mode 100644 static/vendor/select2/docs/index.html create mode 100644 static/vendor/select2/docs/options-old.html create mode 100644 static/vendor/select2/docs/options.html create mode 100644 static/vendor/select2/package.json create mode 100644 static/vendor/select2/src/js/banner.end.js create mode 100644 static/vendor/select2/src/js/banner.start.js create mode 100644 static/vendor/select2/src/js/jquery.mousewheel.shim.js create mode 100644 static/vendor/select2/src/js/jquery.select2.js create mode 100644 static/vendor/select2/src/js/jquery.shim.js create mode 100644 static/vendor/select2/src/js/select2/compat/containerCss.js create mode 100644 static/vendor/select2/src/js/select2/compat/dropdownCss.js create mode 100644 static/vendor/select2/src/js/select2/compat/initSelection.js create mode 100644 static/vendor/select2/src/js/select2/compat/inputData.js create mode 100644 static/vendor/select2/src/js/select2/compat/matcher.js create mode 100644 static/vendor/select2/src/js/select2/compat/query.js create mode 100644 static/vendor/select2/src/js/select2/compat/utils.js create mode 100644 static/vendor/select2/src/js/select2/core.js create mode 100644 static/vendor/select2/src/js/select2/data/ajax.js create mode 100644 static/vendor/select2/src/js/select2/data/array.js create mode 100644 static/vendor/select2/src/js/select2/data/base.js create mode 100644 static/vendor/select2/src/js/select2/data/maximumInputLength.js create mode 100644 static/vendor/select2/src/js/select2/data/maximumSelectionLength.js create mode 100644 static/vendor/select2/src/js/select2/data/minimumInputLength.js create mode 100644 static/vendor/select2/src/js/select2/data/select.js create mode 100644 static/vendor/select2/src/js/select2/data/tags.js create mode 100644 static/vendor/select2/src/js/select2/data/tokenizer.js create mode 100644 static/vendor/select2/src/js/select2/defaults.js create mode 100644 static/vendor/select2/src/js/select2/diacritics.js create mode 100644 static/vendor/select2/src/js/select2/dropdown.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/attachBody.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/attachContainer.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/closeOnSelect.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/hidePlaceholder.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/infiniteScroll.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/minimumResultsForSearch.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/search.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/selectOnClose.js create mode 100644 static/vendor/select2/src/js/select2/dropdown/stopPropagation.js create mode 100644 static/vendor/select2/src/js/select2/i18n/af.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ar.js create mode 100644 static/vendor/select2/src/js/select2/i18n/az.js create mode 100644 static/vendor/select2/src/js/select2/i18n/bg.js create mode 100644 static/vendor/select2/src/js/select2/i18n/bn.js create mode 100644 static/vendor/select2/src/js/select2/i18n/bs.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ca.js create mode 100644 static/vendor/select2/src/js/select2/i18n/cs.js create mode 100644 static/vendor/select2/src/js/select2/i18n/da.js create mode 100644 static/vendor/select2/src/js/select2/i18n/de.js create mode 100644 static/vendor/select2/src/js/select2/i18n/dsb.js create mode 100644 static/vendor/select2/src/js/select2/i18n/el.js create mode 100644 static/vendor/select2/src/js/select2/i18n/en.js create mode 100644 static/vendor/select2/src/js/select2/i18n/es.js create mode 100644 static/vendor/select2/src/js/select2/i18n/et.js create mode 100644 static/vendor/select2/src/js/select2/i18n/eu.js create mode 100644 static/vendor/select2/src/js/select2/i18n/fa.js create mode 100644 static/vendor/select2/src/js/select2/i18n/fi.js create mode 100644 static/vendor/select2/src/js/select2/i18n/fr.js create mode 100644 static/vendor/select2/src/js/select2/i18n/gl.js create mode 100644 static/vendor/select2/src/js/select2/i18n/he.js create mode 100644 static/vendor/select2/src/js/select2/i18n/hi.js create mode 100644 static/vendor/select2/src/js/select2/i18n/hr.js create mode 100644 static/vendor/select2/src/js/select2/i18n/hsb.js create mode 100644 static/vendor/select2/src/js/select2/i18n/hu.js create mode 100644 static/vendor/select2/src/js/select2/i18n/hy.js create mode 100644 static/vendor/select2/src/js/select2/i18n/id.js create mode 100644 static/vendor/select2/src/js/select2/i18n/is.js create mode 100644 static/vendor/select2/src/js/select2/i18n/it.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ja.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ka.js create mode 100644 static/vendor/select2/src/js/select2/i18n/km.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ko.js create mode 100644 static/vendor/select2/src/js/select2/i18n/lt.js create mode 100644 static/vendor/select2/src/js/select2/i18n/lv.js create mode 100644 static/vendor/select2/src/js/select2/i18n/mk.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ms.js create mode 100644 static/vendor/select2/src/js/select2/i18n/nb.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ne.js create mode 100644 static/vendor/select2/src/js/select2/i18n/nl.js create mode 100644 static/vendor/select2/src/js/select2/i18n/pl.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ps.js create mode 100644 static/vendor/select2/src/js/select2/i18n/pt-BR.js create mode 100644 static/vendor/select2/src/js/select2/i18n/pt.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ro.js create mode 100644 static/vendor/select2/src/js/select2/i18n/ru.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sk.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sl.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sq.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sr-Cyrl.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sr.js create mode 100644 static/vendor/select2/src/js/select2/i18n/sv.js create mode 100644 static/vendor/select2/src/js/select2/i18n/th.js create mode 100644 static/vendor/select2/src/js/select2/i18n/tk.js create mode 100644 static/vendor/select2/src/js/select2/i18n/tr.js create mode 100644 static/vendor/select2/src/js/select2/i18n/uk.js create mode 100644 static/vendor/select2/src/js/select2/i18n/vi.js create mode 100644 static/vendor/select2/src/js/select2/i18n/zh-CN.js create mode 100644 static/vendor/select2/src/js/select2/i18n/zh-TW.js create mode 100644 static/vendor/select2/src/js/select2/keys.js create mode 100644 static/vendor/select2/src/js/select2/options.js create mode 100644 static/vendor/select2/src/js/select2/results.js create mode 100644 static/vendor/select2/src/js/select2/selection/allowClear.js create mode 100644 static/vendor/select2/src/js/select2/selection/base.js create mode 100644 static/vendor/select2/src/js/select2/selection/clickMask.js create mode 100644 static/vendor/select2/src/js/select2/selection/eventRelay.js create mode 100644 static/vendor/select2/src/js/select2/selection/multiple.js create mode 100644 static/vendor/select2/src/js/select2/selection/placeholder.js create mode 100644 static/vendor/select2/src/js/select2/selection/search.js create mode 100644 static/vendor/select2/src/js/select2/selection/single.js create mode 100644 static/vendor/select2/src/js/select2/selection/stopPropagation.js create mode 100644 static/vendor/select2/src/js/select2/translation.js create mode 100644 static/vendor/select2/src/js/select2/utils.js create mode 100644 static/vendor/select2/src/js/wrapper.end.js create mode 100644 static/vendor/select2/src/js/wrapper.start.js create mode 100644 static/vendor/select2/tests/a11y/selection-tests.js create mode 100644 static/vendor/select2/tests/data/array-tests.js create mode 100644 static/vendor/select2/tests/data/base-tests.js create mode 100644 static/vendor/select2/tests/data/inputData-tests.js create mode 100644 static/vendor/select2/tests/data/maximumInputLength-tests.js create mode 100644 static/vendor/select2/tests/data/maximumSelectionLength-tests.js create mode 100644 static/vendor/select2/tests/data/minimumInputLength-tests.js create mode 100644 static/vendor/select2/tests/data/select-tests.js create mode 100644 static/vendor/select2/tests/data/tags-tests.js create mode 100644 static/vendor/select2/tests/data/tokenizer-tests.js create mode 100644 static/vendor/select2/tests/dropdown/dropdownCss-tests.js create mode 100644 static/vendor/select2/tests/dropdown/dropdownParent-tests.js create mode 100644 static/vendor/select2/tests/dropdown/positioning-tests.js create mode 100644 static/vendor/select2/tests/dropdown/search-a11y-tests.js create mode 100644 static/vendor/select2/tests/dropdown/selectOnClose-tests.js create mode 100644 static/vendor/select2/tests/dropdown/stopPropagation-tests.js create mode 100644 static/vendor/select2/tests/helpers.js create mode 100644 static/vendor/select2/tests/integration-jq1.html create mode 100644 static/vendor/select2/tests/integration-jq2.html create mode 100644 static/vendor/select2/tests/integration-jq3.html create mode 100644 static/vendor/select2/tests/integration/dom-changes.js create mode 100644 static/vendor/select2/tests/integration/jquery-calls.js create mode 100644 static/vendor/select2/tests/integration/select2-methods.js create mode 100644 static/vendor/select2/tests/options/ajax-tests.js create mode 100644 static/vendor/select2/tests/options/data-tests.js create mode 100644 static/vendor/select2/tests/options/deprecated-tests.js create mode 100644 static/vendor/select2/tests/options/translation-tests.js create mode 100644 static/vendor/select2/tests/options/width-tests.js create mode 100644 static/vendor/select2/tests/results/a11y-tests.js create mode 100644 static/vendor/select2/tests/results/focusing-tests.js create mode 100644 static/vendor/select2/tests/results/infiniteScroll-tests.js create mode 100644 static/vendor/select2/tests/results/option-tests.js create mode 100644 static/vendor/select2/tests/selection/allowClear-tests.js create mode 100644 static/vendor/select2/tests/selection/containerCss-tests.js create mode 100644 static/vendor/select2/tests/selection/focusing-tests.js create mode 100644 static/vendor/select2/tests/selection/multiple-tests.js create mode 100644 static/vendor/select2/tests/selection/placeholder-tests.js create mode 100644 static/vendor/select2/tests/selection/search-a11y-tests.js create mode 100644 static/vendor/select2/tests/selection/search-placeholder-tests.js create mode 100644 static/vendor/select2/tests/selection/search-tests.js create mode 100644 static/vendor/select2/tests/selection/single-tests.js create mode 100644 static/vendor/select2/tests/selection/stopPropagation-tests.js create mode 100644 static/vendor/select2/tests/unit-jq1.html create mode 100644 static/vendor/select2/tests/unit-jq2.html create mode 100644 static/vendor/select2/tests/unit-jq3.html create mode 100644 static/vendor/select2/tests/utils/data-tests.js create mode 100644 static/vendor/select2/tests/utils/decorator-tests.js create mode 100644 static/vendor/select2/tests/utils/escapeMarkup-tests.js create mode 100644 static/vendor/select2/tests/vendor/jquery-1.7.2.js create mode 100644 static/vendor/select2/tests/vendor/jquery-2.2.4.js create mode 100644 static/vendor/select2/tests/vendor/jquery-3.4.1.js create mode 100644 static/vendor/select2/tests/vendor/qunit-1.23.1.css create mode 100644 static/vendor/select2/tests/vendor/qunit-1.23.1.js diff --git a/static/autocomplete_light/autocomplete_light.js b/static/autocomplete_light/autocomplete_light.js new file mode 100644 index 00000000..c58c837b --- /dev/null +++ b/static/autocomplete_light/autocomplete_light.js @@ -0,0 +1,461 @@ +/*! + * Django Autocomplete Light + */ + +var yl = yl || {}; +yl.functions = {}; +/** + * Register your own JS function for DAL. + * + * @param name The name of your function. This should be the same as the widget + * `autocomplete_function` property value. + * @param func The callback that will initialize your custom autocomplete. + */ +yl.registerFunction = function (name, func) { + if (this.functions.hasOwnProperty(name)) { + // This function already exists to show an error and skip. + console.error('The DAL function "' + name + '" has already been registered.'); + return + } + if (typeof func != 'function') { + // It's not a function kill it. + throw new Error('The custom DAL function must be a function.'); + } + this.functions[name] = func; + var event = new CustomEvent('dal-function-registered.' + name, {detail: {name: name, func: func}}) + window.dispatchEvent(event); +}; + + +window.addEventListener("load", function () { + + // Check if `django.jQuery` exists otherwise set `django.jQuery` to non namespaced jQuery. + window.django = window.django || {}; + if (!django.hasOwnProperty('jQuery') && jQuery !== 'undefined') { + django.jQuery = jQuery; + } + + (function ($) { + $.fn.getFormPrefix = function () { + /* Get the form prefix for a field. + * + * For example: + * + * $(':input[name$=owner]').getFormsetPrefix() + * + * Would return an empty string for an input with name 'owner' but would return + * 'inline_model-0-' for an input named 'inline_model-0-owner'. + */ + var parts = $(this).attr('name').split('-'); + var prefix = ''; + + for (var i in parts) { + var testPrefix = parts.slice(0, -i).join('-'); + if (!testPrefix.length) continue; + testPrefix += '-'; + + var result = $(':input[name^=' + testPrefix + ']') + + if (result.length) { + return testPrefix; + } + } + + return ''; + } + + $.fn.getFormPrefixes = function () { + /* + * Get the form prefixes for a field, from the most specific to the least. + * + * For example: + * + * $(':input[name$=owner]').getFormPrefixes() + * + * Would return: + * - [''] for an input named 'owner'. + * - ['inline_model-0-', ''] for an input named 'inline_model-0-owner' (i.e. nested with a nested inline). + * - ['sections-0-items-0-', 'sections-0-', ''] for an input named 'sections-0-items-0-product' + * (i.e. nested multiple time with django-nested-admin). + */ + var parts = $(this).attr('name').split('-').slice(0, -1); + var prefixes = []; + + for (i = 0; i < parts.length; i += 2) { + var testPrefix = parts.slice(0, -i || parts.length).join('-'); + if (!testPrefix.length) + continue; + + testPrefix += '-'; + + var result = $(':input[name^=' + testPrefix + ']') + + if (result.length) + prefixes.push(testPrefix); + } + + prefixes.push(''); + + return prefixes; + } + + /* + * This ensures the Language file is loaded and passes it our jQuery. + */ + if (typeof dalLoadLanguage !== 'undefined') { + dalLoadLanguage($); + } else { + document.addEventListener('dal-language-loaded', function (e) { + // `e.lang` is the language that was loaded. + dalLoadLanguage($); + }) + } + + // Fire init event for yl.registerFunction() execution. + var event = new CustomEvent('dal-init-function'); + document.dispatchEvent(event); + + var initialized = []; + + $.fn.excludeTemplateForms = function() { + // exclude elements that contain '__prefix__' in their id + // these are used by django formsets for template forms + return this.not('[id*=__prefix__]').filter(function() { + // exclude elements that contain '-empty-' in their ids + // these are used by django-nested-admin for nested template formsets + // note that the filter also ensures that 'empty' is not actually the related_name for some relation + // by ensuring that it is not surrounded by numbers on both sides + return !this.id.match(/(?= 0) { + return; + } + + // The DAL function to execute. + var dalFunction = $(element).attr('data-autocomplete-light-function'); + + if (yl.functions.hasOwnProperty(dalFunction) && typeof yl.functions[dalFunction] == 'function') { + // If the function has been registered call it. + yl.functions[dalFunction]($, element); + } else if (yl.functions.hasOwnProperty(dalFunction)) { + // If the function exists but has not been registered wait for it to be registered. + window.addEventListener('dal-function-registered.' + dalFunction, function (e) { + yl.functions[dalFunction]($, element); + }) + } else { + // Otherwise notify that the function should be registered. + console.warn('Your custom DAL function "' + dalFunction + '" uses a deprecated event listener that will be removed in future versions. https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#overriding-javascript-code') + } + + // Fire init event for custom function execution. + // DEPRECATED + $(element).trigger('autocompleteLightInitialize'); + + // Add element to the array of already initialized fields + initialized.push(element); + } + + if (!window.__dal__initialize) { + window.__dal__initialize = initialize; + + $(document).ready(function () { + $('[data-autocomplete-light-function]').excludeTemplateForms().each(initialize); + }); + + if ('MutationObserver' in window) { + new MutationObserver(function (mutations) { + var mutationRecord; + var addedNode; + + for (var i = 0; i < mutations.length; i++) { + mutationRecord = mutations[i]; + + if (mutationRecord.addedNodes.length > 0) { + for (var j = 0; j < mutationRecord.addedNodes.length; j++) { + addedNode = mutationRecord.addedNodes[j]; + + $(addedNode).find('[data-autocomplete-light-function]').excludeTemplateForms().each(initialize); + } + } + } + + }).observe(document.documentElement, {childList: true, subtree: true}); + } else { + $(document).on('DOMNodeInserted', function (e) { + $(e.target).find('[data-autocomplete-light-function]').excludeTemplateForms().each(initialize); + }); + } + } + + // using jQuery + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = $.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + document.csrftoken = getCookie('csrftoken'); + if (document.csrftoken === null) { + // Try to get CSRF token from DOM when cookie is missing + var $csrf = $('form :input[name="csrfmiddlewaretoken"]'); + if ($csrf.length > 0) { + document.csrftoken = $csrf[0].value; + } + } + })(django.jQuery); + + // Does the same thing as django's admin/js/autocomplete.js, but uses yl.jQuery. + (function ($) { + 'use strict'; + var init = function ($element, options) { + var settings = $.extend({ + ajax: { + data: function (params) { + return { + term: params.term, + page: params.page + }; + } + } + }, options); + $element.select2(settings); + }; + + $.fn.djangoAdminSelect2 = function (options) { + var settings = $.extend({}, options); + $.each(this, function (i, element) { + var $element = $(element); + init($element, settings); + }); + return this; + }; + + $(function () { + // Initialize all autocomplete widgets except the one in the template + // form used when a new formset is added. + $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2(); + }); + + $(document).on('formset:added', (function () { + return function (event, $newFormset) { + return $newFormset.find('.admin-autocomplete').djangoAdminSelect2(); + }; + })(this)); + }(django.jQuery)); + + (function ($, yl) { + yl.forwardHandlerRegistry = yl.forwardHandlerRegistry || {}; + + yl.registerForwardHandler = function (name, handler) { + yl.forwardHandlerRegistry[name] = handler; + }; + + yl.getForwardHandler = function (name) { + return yl.forwardHandlerRegistry[name]; + }; + + function getForwardStrategy(element) { + var checkForCheckboxes = function () { + var all = true; + $.each(element, function (ix, e) { + if ($(e).attr("type") !== "checkbox") { + all = false; + } + }); + return all; + }; + + if (element.length === 1 && + element.attr("type") === "checkbox" && + element.attr("value") === undefined) { + // Single checkbox without 'value' attribute + // Boolean field + return "exists"; + } else if (element.length === 1 && + element.attr("multiple") !== undefined) { + // Multiple by HTML semantics. E. g. multiple select + // Multiple choice field + return "multiple"; + } else if (checkForCheckboxes()) { + // Multiple checkboxes or one checkbox with 'value' attribute. + // Multiple choice field represented by checkboxes + return "multiple"; + } else { + // Other cases + return "single"; + } + } + + /** + * Get fields with name `name` relative to `element` with considering form + * prefixes. + * @param element the element + * @param name name of the field + * @returns jQuery object with found fields or empty jQuery object if no + * field was found + */ + yl.getFieldRelativeTo = function (element, name) { + var prefixes = $(element).getFormPrefixes(); + + for (var i = 0; i < prefixes.length; i++) { + var fieldSelector = "[name=" + prefixes[i] + name + "]"; + var field = $(fieldSelector); + + if (field.length) { + return field; + } + } + + return $(); + }; + + /** + * Get field value which is put to forwarded dictionary + * @param field the field + * @returns forwarded value + */ + yl.getValueFromField = function (field) { + var strategy = getForwardStrategy(field); + var serializedField = $(field).serializeArray(); + + if ((serializedField == false) && ($(field).prop('disabled'))) { + $(field).prop('disabled', false); + serializedField = $(field).serializeArray(); + $(field).prop('disabled', true); + } + + var getSerializedFieldElementAt = function (index) { + // Return serializedField[index] + // or null if something went wrong + if (serializedField.length > index) { + return serializedField[index]; + } else { + return null; + } + }; + + var getValueOf = function (elem) { + // Return elem.value + // or null if something went wrong + if (elem.hasOwnProperty("value") && + elem.value !== undefined + ) { + return elem.value; + } else { + return null; + } + }; + + var getSerializedFieldValueAt = function (index) { + // Return serializedField[index].value + // or null if something went wrong + var elem = getSerializedFieldElementAt(index); + if (elem !== null) { + return getValueOf(elem); + } else { + return null; + } + }; + + if (strategy === "multiple") { + return serializedField.map( + function (item) { + return getValueOf(item); + } + ); + } else if (strategy === "exists") { + return serializedField.length > 0; + } else { + return getSerializedFieldValueAt(0); + } + }; + + yl.getForwards = function (element) { + var forwardElem, + forwardList, + forwardedData, + divSelector, + form; + divSelector = "div.dal-forward-conf#dal-forward-conf-for-" + + element.attr("id") + ", " + + "div.dal-forward-conf#dal-forward-conf-for_" + + element.attr("id"); + form = element.length > 0 ? $(element[0].form) : $(); + + forwardElem = + form.find(divSelector).find('script'); + if (forwardElem.length === 0) { + return; + } + try { + forwardList = JSON.parse(forwardElem.text()); + } catch (e) { + return; + } + + if (!Array.isArray(forwardList)) { + return; + } + + forwardedData = {}; + + $.each(forwardList, function (ix, field) { + var srcName, dstName; + if (field.type === "const") { + forwardedData[field.dst] = field.val; + } else if (field.type === "self") { + if (field.hasOwnProperty("dst")) { + dstName = field.dst; + } else { + dstName = "self"; + } + forwardedData[dstName] = yl.getValueFromField(element); + } else if (field.type === "field") { + srcName = field.src; + if (field.hasOwnProperty("dst")) { + dstName = field.dst; + } else { + dstName = srcName; + } + var forwardedField = yl.getFieldRelativeTo(element, srcName); + + if (!forwardedField.length) { + return; + } + + forwardedData[dstName] = yl.getValueFromField(forwardedField); + } else if (field.type === "javascript") { + var handler = yl.getForwardHandler(field.handler); + forwardedData[field.dst || field.handler] = handler(element); + } + + }); + return JSON.stringify(forwardedData); + }; + + })(django.jQuery, yl); +}); \ No newline at end of file diff --git a/static/autocomplete_light/autocomplete_light.min.js b/static/autocomplete_light/autocomplete_light.min.js new file mode 100644 index 00000000..da5e185b --- /dev/null +++ b/static/autocomplete_light/autocomplete_light.min.js @@ -0,0 +1 @@ +var yl=yl||{};yl.functions={},yl.registerFunction=function(e,t){if(this.functions.hasOwnProperty(e))console.error('The DAL function "'+e+'" has already been registered.');else{if("function"!=typeof t)throw new Error("The custom DAL function must be a function.");this.functions[e]=t;var n=new CustomEvent("dal-function-registered."+e,{detail:{name:e,func:t}});window.dispatchEvent(n)}},window.addEventListener("load",function(){window.django=window.django||{},django.hasOwnProperty("jQuery")||"undefined"===jQuery||(django.jQuery=jQuery),function($){$.fn.getFormPrefix=function(){var e=$(this).attr("name").split("-");for(var t in e){var n=e.slice(0,-t).join("-");if(n.length)if($(":input[name^="+(n+="-")+"]").length)return n}return""},$.fn.getFormPrefixes=function(){var e=$(this).attr("name").split("-").slice(0,-1),t=[];for(i=0;ii?n[i]:null)?r(o):null)},yl.getForwards=function(a){var e,d,t="div.dal-forward-conf#dal-forward-conf-for-"+a.attr("id")+", div.dal-forward-conf#dal-forward-conf-for_"+a.attr("id"),n=(0'); + $result.html(text); + return $result; + } else { + return text; + } + } + + function result_template(item) { + var text = template(item.text, + ($element.attr('data-html') !== undefined || $element.attr('data-result-html') !== undefined) && !item.create_id + ); + + if (item.create_id) { + return $('').text(text).addClass('dal-create'); + } else { + return text + } + } + + function selected_template(item) { + if (item.selected_text !== undefined) { + return template(item.selected_text, + $element.attr('data-html') !== undefined || $element.attr('data-selected-html') !== undefined + ); + } else { + return result_template(item); + } + return + } + + var ajax = null; + if ($element.attr('data-autocomplete-light-url')) { + ajax = { + url: $element.attr('data-autocomplete-light-url'), + dataType: 'json', + delay: 250, + + data: function (params) { + var data = { + q: params.term, // search term + page: params.page, + create: $element.attr('data-autocomplete-light-create') && !$element.attr('data-tags'), + forward: yl.getForwards($element) + }; + + return data; + }, + processResults: function (data, page) { + if ($element.attr('data-tags')) { + $.each(data.results, function (index, value) { + value.id = value.text; + }); + } + + return data; + }, + cache: true + }; + } + + $element.select2({ + tokenSeparators: $element.attr('data-tags') ? [','] : null, + debug: true, + containerCssClass: ':all:', + placeholder: $element.attr('data-placeholder') || '', + language: $element.attr('data-autocomplete-light-language'), + minimumInputLength: $element.attr('data-minimum-input-length') || 0, + allowClear: !$element.is('[required]'), + templateResult: result_template, + templateSelection: selected_template, + ajax: ajax, + with: null, + tags: Boolean($element.attr('data-tags')), + }); + + $element.on('select2:selecting', function (e) { + var data = e.params.args.data; + + if (data.create_id !== true) + return; + + e.preventDefault(); + + var select = $element; + + $.ajax({ + url: $element.attr('data-autocomplete-light-url'), + type: 'POST', + dataType: 'json', + data: { + text: data.id, + forward: yl.getForwards($element) + }, + beforeSend: function (xhr, settings) { + xhr.setRequestHeader("X-CSRFToken", document.csrftoken); + }, + success: function (data, textStatus, jqXHR) { + select.append( + $(' element should be created for the two with children' + ); +}); + +test('optgroup tags have the right properties', function (assert) { + var $select = $('#qunit-fixture .single-empty'); + + var data = new ArrayData($select, nestedOptions); + + var container = new MockContainer(); + data.bind(container, $('
')); + + var $group = $select.children('optgroup'); + + assert.equal( + $group.prop('label'), + 'Default', + 'An `` label should match the text property' + ); + + assert.equal( + $group.children().length, + 1, + 'The should have one child under it' + ); +}); + +test('existing selections are respected on initialization', function (assert) { + var $select = $( + '' + ); + + var options = new Options({ + data: [ + { + id: 'Second', + text: 'Second' + }, + { + id: 'Third', + text: 'Third' + } + ] + }); + + assert.equal($select.val(), 'Second'); + + var data = new ArrayData($select, options); + + var container = new MockContainer(); + data.bind(container, $('
')); + + assert.equal($select.val(), 'Second'); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/data/base-tests.js b/static/vendor/select2/tests/data/base-tests.js new file mode 100644 index 00000000..b90158f3 --- /dev/null +++ b/static/vendor/select2/tests/data/base-tests.js @@ -0,0 +1,29 @@ +module('Data adapters - Base'); + +var BaseData = require('select2/data/base'); +var $ = require('jquery'); +var Options = require('select2/options'); + +var options = new Options({}); + +test('current is required', function (assert) { + var data = new BaseData($('#qunit-fixture select'), options); + + assert.throws( + function () { + data.current(function () {}); + }, + 'current has no default implementation' + ); +}); + +test('query is required', function (assert) { + var data = new BaseData($('#qunit-fixture select'), options); + + assert.throws( + function () { + data.query({}, function () {}); + }, + 'query has no default implementation' + ); +}); diff --git a/static/vendor/select2/tests/data/inputData-tests.js b/static/vendor/select2/tests/data/inputData-tests.js new file mode 100644 index 00000000..2ca58a15 --- /dev/null +++ b/static/vendor/select2/tests/data/inputData-tests.js @@ -0,0 +1,173 @@ +module('Data adapters - compatibility'); + +var $ = require('jquery'); + +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var ArrayData = require('select2/data/array'); +var InputData = require('select2/compat/inputData'); + +var InputAdapter = Utils.Decorate(ArrayData, InputData); + +test('test that options can be selected', function (assert) { + var options = new Options({ + data: [ + { + id: 'test', + text: 'Test' + } + ] + }); + var $element = $(''); + + var adapter = new InputAdapter($element, options); + + var container = new MockContainer(); + adapter.bind(container, $('
')); + + adapter.select({ + id: 'test' + }); + + assert.equal( + $element.val(), + 'test', + 'The id of the item should be the value' + ); +}); + +test('unselect the single selected option clears the value', function (assert) { + var options = new Options({ + data: [ + { + id: 'test', + text: 'Test', + selected: true + } + ] + }); + var $element = $(''); + + var adapter = new InputAdapter($element, options); + + var container = new MockContainer(); + adapter.bind(container, $('
')); + + adapter.unselect({ + id: 'test' + }); + + assert.equal( + $element.val(), + '', + 'The id should no longer be in the value' + ); +}); + +test('options can be unselected individually', function (assert) { + var options = new Options({ + data: [ + { + id: 'test', + text: 'Test' + }, + { + id: 'test2', + text: 'Test2' + }, + { + id: 'test3', + text: 'Test3' + } + ] + }); + var $element = $(''); + $element.val('test,test2,test3'); + + var adapter = new InputAdapter($element, options); + + var container = new MockContainer(); + adapter.bind(container, $('
')); + + adapter.unselect({ + id: 'test2' + }); + + assert.equal( + $element.val(), + 'test,test3', + 'The value should contain all the still selected options' + ); +}); + +test('default values can be set', function (assert) { + assert.expect(4); + + var options = new Options({ + data: [ + { + id: 'test', + text: 'Test' + } + ] + }); + var $element = $(''); + + var adapter = new InputAdapter($element, options); + + var container = new MockContainer(); + adapter.bind(container, $('
')); + + adapter.current(function (data) { + assert.equal( + data.length, + 1, + 'There should only be a single selected option' + ); + + var item = data[0]; + + assert.equal(item.id, 'test'); + assert.equal(item.text, 'Test'); + }); + + assert.equal( + $element.val(), + 'test', + 'The value should not have been altered' + ); +}); + +test('no default value', function (assert) { + assert.expect(2); + + var options = new Options({ + data: [ + { + id: 'test', + text: 'Test' + } + ] + }); + var $element = $(''); + + var adapter = new InputAdapter($element, options); + + var container = new MockContainer(); + adapter.bind(container, $('
')); + + adapter.current(function (data) { + assert.equal( + data.length, + 0, + 'There should be no selected options' + ); + }); + + assert.equal( + $element.val(), + '', + 'The value should not have been altered' + ); +}); diff --git a/static/vendor/select2/tests/data/maximumInputLength-tests.js b/static/vendor/select2/tests/data/maximumInputLength-tests.js new file mode 100644 index 00000000..e8557139 --- /dev/null +++ b/static/vendor/select2/tests/data/maximumInputLength-tests.js @@ -0,0 +1,138 @@ +module('Data adapters - Maximum input length'); + +var MaximumInputLength = require('select2/data/maximumInputLength'); +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +function MaximumInputStub () { + this.called = false; +} + +MaximumInputStub.prototype.query = function (params, callback) { + this.called = true; +}; + +var MaximumInputData = Utils.Decorate(MaximumInputStub, MaximumInputLength); + +test('0 never displays the notice', function (assert) { + var zeroOptions = new Options({ + maximumInputLength: 0 + }); + + var data = new MaximumInputData(null, zeroOptions); + + data.trigger = function () { + assert.ok(false, 'No events should be triggered'); + }; + + data.query({ + term: '' + }); + + assert.ok(data.called); + + data = new MaximumInputData(null, zeroOptions); + + data.query({ + term: 'test' + }); + + assert.ok(data.called); +}); + +test('< 0 never displays the notice', function (assert) { + var negativeOptions = new Options({ + maximumInputLength: -1 + }); + + var data = new MaximumInputData(null, negativeOptions); + + data.trigger = function () { + assert.ok(false, 'No events should be triggered'); + }; + + data.query({ + term: '' + }); + + assert.ok(data.called); + + data = new MaximumInputData(null, negativeOptions); + + data.query({ + term: 'test' + }); + + assert.ok(data.called); +}); + +test('triggers when input is too long', function (assert) { + var options = new Options({ + maximumInputLength: 1 + }); + + var data = new MaximumInputData(null, options); + + data.trigger = function () { + assert.ok(true, 'The event should be triggered.'); + }; + + data.query({ + term: 'no' + }); + + assert.ok(!data.called, 'The adapter should not be called'); +}); + +test('does not trigger when equal', function (assert) { + var options = new Options({ + maximumInputLength: 10 + }); + + var data = new MaximumInputData(null, options); + + data.trigger = function () { + assert.ok(false, 'The event should not be triggered.'); + }; + + data.query({ + term: '1234567890' + }); + + assert.ok(data.called); +}); + +test('does not trigger when less', function (assert) { + var options = new Options({ + maximumInputLength: 10 + }); + + var data = new MaximumInputData(null, options); + + data.trigger = function () { + assert.ok(false, 'The event should not be triggered.'); + }; + + data.query({ + term: '123' + }); + + assert.ok(data.called); +}); + +test('works with null term', function (assert) { + var options = new Options({ + maximumInputLength: 1 + }); + + var data = new MaximumInputData(null, options); + + data.trigger = function () { + assert.ok(false, 'The event should not be triggered'); + }; + + data.query({}); + + assert.ok(data.called); +}); diff --git a/static/vendor/select2/tests/data/maximumSelectionLength-tests.js b/static/vendor/select2/tests/data/maximumSelectionLength-tests.js new file mode 100644 index 00000000..f11c7e9a --- /dev/null +++ b/static/vendor/select2/tests/data/maximumSelectionLength-tests.js @@ -0,0 +1,152 @@ +module('Data adapters - Maximum selection length'); + +var SelectData = require('select2/data/select'); +var MaximumSelectionLength = require('select2/data/maximumSelectionLength'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var MaximumSelectionData = Utils.Decorate(SelectData, MaximumSelectionLength); + +test('0 never displays the notice', function (assert) { + assert.expect(3); + + var $select = $('#qunit-fixture .multiple'); + + var zeroOptions = new Options({ + maximumSelectionLength: 0 + }); + + var container = new MockContainer(); + var data = new MaximumSelectionData($select, zeroOptions); + + data.bind(container, null); + + data.on('results:message', function () { + assert.ok(false, 'The message should not be displayed'); + }); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); + + $select.val(['One']); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); + + $select.val(['One', 'Two']); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); +}); + +test('< 0 never displays the notice', function (assert) { + assert.expect(3); + + var $select = $('#qunit-fixture .multiple'); + + var negativeOptions = new Options({ + maximumSelectionLength: -1 + }); + + var container = new MockContainer(); + var data = new MaximumSelectionData($select, negativeOptions); + + data.bind(container, null); + + data.on('results:message', function () { + assert.ok(false, 'The message should not be displayed'); + }); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); + + $select.val(['One']); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); + + $select.val(['One', 'Two']); + + data.query({ + term: '' + }, function () { + assert.ok(true, 'The results should be queried'); + }); +}); + +test('triggers when >= 1 selection' , function (assert) { + assert.expect(2); + + var $select = $('#qunit-fixture .multiple'); + + var maxOfOneOptions = new Options({ + maximumSelectionLength: 1 + }); + + var container = new MockContainer(); + var data = new MaximumSelectionData($select, maxOfOneOptions); + + data.bind(container, null); + + data.on('results:message', function () { + assert.ok(true, 'The message should be displayed'); + }); + + $select.val(['One']); + + data.query({ + term: '' + }, function () { + assert.ok(false, 'The results should not be queried'); + }); + + $select.val(['One', 'Two']); + + data.query({ + term: '' + }, function () { + assert.ok(false, 'The results should not be queried'); + }); +}); + +test('triggers after selection' , function (assert) { + assert.expect(1); + + var $select = $('#qunit-fixture .multiple'); + + var maxOfOneOptions = new Options({ + maximumSelectionLength: 1 + }); + + var container = new MockContainer(); + var data = new MaximumSelectionData($select, maxOfOneOptions); + + data.bind(container, null); + + data.on('results:message', function () { + assert.ok(true, 'The message should be displayed'); + }); + + $select.val(['One']); + + container.trigger('select', { + data: {} + }); +}); diff --git a/static/vendor/select2/tests/data/minimumInputLength-tests.js b/static/vendor/select2/tests/data/minimumInputLength-tests.js new file mode 100644 index 00000000..a67db08d --- /dev/null +++ b/static/vendor/select2/tests/data/minimumInputLength-tests.js @@ -0,0 +1,138 @@ +module('Data adapters - Minimum input length'); + +var MinimumInputLength = require('select2/data/minimumInputLength'); +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +function StubData () { + this.called = false; +} + +StubData.prototype.query = function (params, callback) { + this.called = true; +}; + +var MinimumData = Utils.Decorate(StubData, MinimumInputLength); + +test('0 never displays the notice', function (assert) { + var zeroOptions = new Options({ + minimumInputLength: 0 + }); + + var data = new MinimumData(null, zeroOptions); + + data.trigger = function () { + assert.ok(false, 'No events should be triggered'); + }; + + data.query({ + term: '' + }); + + assert.ok(data.called); + + data = new MinimumData(null, zeroOptions); + + data.query({ + term: 'test' + }); + + assert.ok(data.called); +}); + +test('< 0 never displays the notice', function (assert) { + var negativeOptions = new Options({ + minimumInputLength: -1 + }); + + var data = new MinimumData(null, negativeOptions); + + data.trigger = function () { + assert.ok(false, 'No events should be triggered'); + }; + + data.query({ + term: '' + }); + + assert.ok(data.called); + + data = new MinimumData(null, negativeOptions); + + data.query({ + term: 'test' + }); + + assert.ok(data.called); +}); + +test('triggers when input is not long enough', function (assert) { + var options = new Options({ + minimumInputLength: 10 + }); + + var data = new MinimumData(null, options); + + data.trigger = function () { + assert.ok(true, 'The event should be triggered.'); + }; + + data.query({ + term: 'no' + }); + + assert.ok(!data.called); +}); + +test('does not trigger when equal', function (assert) { + var options = new Options({ + minimumInputLength: 10 + }); + + var data = new MinimumData(null, options); + + data.trigger = function () { + assert.ok(false, 'The event should not be triggered.'); + }; + + data.query({ + term: '1234567890' + }); + + assert.ok(data.called); +}); + +test('does not trigger when greater', function (assert) { + var options = new Options({ + minimumInputLength: 10 + }); + + var data = new MinimumData(null, options); + + data.trigger = function () { + assert.ok(false, 'The event should not be triggered.'); + }; + + data.query({ + term: '12345678901' + }); + + assert.ok(data.called); +}); + +test('works with null term', function (assert) { + var options = new Options({ + minimumInputLength: 1 + }); + + var data = new MinimumData(null, options); + + data.trigger = function () { + assert.ok(true, 'The event should be triggered'); + }; + + data.query({}); + + assert.ok(!data.called); +}); diff --git a/static/vendor/select2/tests/data/select-tests.js b/static/vendor/select2/tests/data/select-tests.js new file mode 100644 index 00000000..b59c6d4b --- /dev/null +++ b/static/vendor/select2/tests/data/select-tests.js @@ -0,0 +1,557 @@ +module('Data adapters - Select - current'); + +var SelectData = require('select2/data/select'); +var $ = require('jquery'); +var Options = require('select2/options'); +var selectOptions = new Options({}); + +test('current gets default for single', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + data.current(function (data) { + assert.equal( + data.length, + 1, + 'There should only be one selected option' + ); + + var option = data[0]; + + assert.equal( + option.id, + 'One', + 'The value of the option tag should be the id' + ); + + assert.equal( + option.text, + 'One', + 'The text within the option tag should be the text' + ); + }); +}); + +test('current gets default for multiple', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var data = new SelectData($select, selectOptions); + + data.current(function (data) { + assert.equal( + data.length, + 0, + 'Multiple selects have no default selection.' + ); + }); +}); + +test('current gets options with explicit value', function (assert) { + var $select = $('#qunit-fixture .single'); + + var $option = $(''); + $select.append($option); + + var data = new SelectData($select, selectOptions); + + $select.val('1'); + + data.current(function (data) { + assert.equal( + data.length, + 1, + 'There should be one selected option' + ); + + var option = data[0]; + + assert.equal( + option.id, + '1', + 'The option value should be the selected id' + ); + + assert.equal( + option.text, + 'One', + 'The text should match the text for the option tag' + ); + }); +}); + +test('current gets options with implicit value', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + $select.val('One'); + + data.current(function (val) { + assert.equal( + val.length, + 1, + 'There should only be one selected value' + ); + + var option = val[0]; + + assert.equal( + option.id, + 'One', + 'The id should be the same as the option text' + ); + + assert.equal( + option.text, + 'One', + 'The text should be the same as the option text' + ); + }); +}); + +test('select works for single', function (assert) { + var $select = $('#qunit-fixture .single-with-placeholder'); + + var data = new SelectData($select, selectOptions); + + assert.equal($select.val(), 'placeholder'); + + data.select({ + id: 'One', + text: 'One' + }); + + assert.equal($select.val(), 'One'); +}); + +test('multiple sets the value', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var data = new SelectData($select, selectOptions); + + assert.ok( + $select.val() == null || $select.val().length == 0, + 'nothing should be selected' + ); + + data.select({ + id: 'Two', + text: 'Two' + }); + + assert.deepEqual($select.val(), ['Two']); +}); + +test('multiple adds to the old value', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var data = new SelectData($select, selectOptions); + + $select.val(['Two']); + + assert.deepEqual($select.val(), ['Two']); + + data.select({ + id: 'One', + text: 'One' + }); + + assert.deepEqual($select.val(), ['One', 'Two']); +}); + +test('duplicates - single - same id on select triggers change', + function (assert) { + var $select = $('#qunit-fixture .duplicates'); + + var data = new SelectData($select, data); + var second = $('#qunit-fixture .duplicates option')[2]; + + var changeTriggered = false; + + assert.equal($select.val(), 'one'); + + $select.on('change', function () { + changeTriggered = true; + }); + + data.select({ + id: 'one', + text: 'Uno', + element: second + }); + + assert.equal( + $select.val(), + 'one', + 'The value never changed' + ); + + assert.ok( + changeTriggered, + 'The change event should be triggered' + ); + + assert.ok( + second.selected, + 'The second duplicate is selected, not the first' + ); +}); + +test('duplicates - single - different id on select triggers change', + function (assert) { + var $select = $('#qunit-fixture .duplicates'); + + var data = new SelectData($select, data); + var second = $('#qunit-fixture .duplicates option')[2]; + + var changeTriggered = false; + + $select.val('two'); + + $select.on('change', function () { + changeTriggered = true; + }); + + data.select({ + id: 'one', + text: 'Uno', + element: second + }); + + assert.equal( + $select.val(), + 'one', + 'The value changed to the duplicate id' + ); + + assert.ok( + changeTriggered, + 'The change event should be triggered' + ); + + assert.ok( + second.selected, + 'The second duplicate is selected, not the first' + ); +}); + +test('duplicates - multiple - same id on select triggers change', +function (assert) { + var $select = $('#qunit-fixture .duplicates-multi'); + + var data = new SelectData($select, data); + var second = $('#qunit-fixture .duplicates-multi option')[2]; + + var changeTriggered = false; + + $select.val(['one']); + + $select.on('change', function () { + changeTriggered = true; + }); + + data.select({ + id: 'one', + text: 'Uno', + element: second + }); + + assert.deepEqual( + $select.val(), + ['one', 'one'], + 'The value now has duplicates' + ); + + assert.ok( + changeTriggered, + 'The change event should be triggered' + ); + + assert.ok( + second.selected, + 'The second duplicate is selected, not the first' + ); +}); + +test('duplicates - multiple - different id on select triggers change', +function (assert) { + var $select = $('#qunit-fixture .duplicates-multi'); + + var data = new SelectData($select, data); + var second = $('#qunit-fixture .duplicates-multi option')[2]; + + var changeTriggered = false; + + $select.val(['two']); + + $select.on('change', function () { + changeTriggered = true; + }); + + data.select({ + id: 'one', + text: 'Uno', + element: second + }); + + assert.deepEqual( + $select.val(), + ['two', 'one'], + 'The value has the new id' + ); + + assert.ok( + changeTriggered, + 'The change event should be triggered' + ); + + assert.ok( + second.selected, + 'The second duplicate is selected, not the first' + ); +}); + +module('Data adapter - Select - query'); + +test('all options are returned with no term', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + data.query({}, function (data) { + assert.equal( + data.results.length, + 1, + 'The number of items returned should be equal to the number of options' + ); + }); +}); + +test('the matcher checks the text', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + data.query({ + term: 'One' + }, function (data) { + assert.equal( + data.results.length, + 1, + 'Only the "One" option should be found' + ); + }); +}); + +test('the matcher ignores case', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + data.query({ + term: 'one' + }, function (data) { + assert.equal( + data.results.length, + 1, + 'The "One" option should still be found' + ); + }); +}); + +test('no options may be returned with no matches', function (assert) { + var $select = $('#qunit-fixture .single'); + + var data = new SelectData($select, selectOptions); + + data.query({ + term: 'qwerty' + }, function (data) { + assert.equal( + data.results.length, + 0, + 'Only matching items should be returned' + ); + }); +}); + +test('optgroup tags are marked with children', function (assert) { + var $select = $('#qunit-fixture .groups'); + + var data = new SelectData($select, selectOptions); + + data.query({}, function (data) { + assert.ok( + 'children' in data.results[0], + 'The optgroup element should have children when queried' + ); + }); +}); + +test('empty optgroups are still shown when queried', function (assert) { + var $select = $('#qunit-fixture .groups'); + + var data = new SelectData($select, selectOptions); + + data.query({}, function (data) { + assert.equal( + data.results.length, + 2, + 'The empty optgroup element should still be returned when queried' + ); + + var item = data.results[1]; + + assert.equal( + item.text, + 'Empty', + 'The text of the empty optgroup should match the label' + ); + + assert.equal( + item.children.length, + 0, + 'There should be no children in the empty opgroup' + ); + }); +}); + +test('multiple options with the same value are returned', function (assert) { + var $select = $('#qunit-fixture .duplicates'); + + var data = new SelectData($select, selectOptions); + + data.query({}, function (data) { + assert.equal( + data.results.length, + 3, + 'The duplicate option should still be returned when queried' + ); + + var first = data.results[0]; + var duplicate = data.results[2]; + + assert.equal( + first.id, + duplicate.id, + 'The duplicates should have the same id' + ); + + assert.notEqual( + first.text, + duplicate.text, + 'The duplicates do not have the same text' + ); + }); +}); + +test('data objects use the text of the option', function (assert) { + var $select = $('#qunit-fixture .duplicates'); + + var data = new SelectData($select, selectOptions); + + var $option = $(''); + + var item = data.item($option); + + assert.equal(item.id, '&'); + assert.equal(item.text, '&'); +}); + +test('select option construction accepts id=0 (zero) value', function (assert) { + var $select = $('#qunit-fixture .single'); + + var selectOptions = [{ id: 0, text: 'Zero Value'}]; + var data = new SelectData($select, selectOptions); + + var optionElem = data.option(selectOptions[0]); + + // If was "Zero Value"", then it ignored id property + assert.equal( + optionElem[0].value, + '0', + 'Built option value should be "0" (zero as a string).' + ); +}); + +test('select option construction accepts id="" (empty string) value', + function (assert) { + var $select = $('#qunit-fixture .single'); + + var selectOptions = [{ id: '', text: 'Empty String'}]; + var data = new SelectData($select, selectOptions); + + var optionElem = data.option(selectOptions[0]); + + assert.equal( + optionElem[0].value, + '', + 'Built option value should be an empty string.' + ); +}); + +test('user-defined types are normalized properly', function (assert) { + var $select = $('#qunit-fixture .user-defined'), + + UserDefinedType = function (id, text) { + var self = this; + + self.id = id; + self.text = text; + + return self; + }; + + var testData = [ + 'Test', + { + id: 4, + text: 'item' + }, + new UserDefinedType(1, 'aaaaaa') + ]; + + var data = new SelectData($select, selectOptions); + + var normalizedItem = data._normalizeItem(testData[0]); + var normalizedItem2 = data._normalizeItem(testData[1]); + var normalizedItem3 = data._normalizeItem(testData[2]); + + assert.equal( + testData[0], + normalizedItem.id, + 'id property should be equal to text after normalize' + ); + + assert.equal( + testData[0], + normalizedItem.text, + 'text property should be equal after normalize' + ); + + assert.equal( + testData[1].id, + normalizedItem2.id, + 'id property should be equal after normalize' + ); + + assert.equal( + testData[1].text, + normalizedItem2.text, + 'text property should be equal after normalize' + ); + + assert.equal( + testData[2].id, + normalizedItem3.id, + 'id property should be equal after normalize' + ); + + assert.equal( + testData[2].text, + normalizedItem3.text, + 'text property should be equal after normalize' + ); + +}); diff --git a/static/vendor/select2/tests/data/tags-tests.js b/static/vendor/select2/tests/data/tags-tests.js new file mode 100644 index 00000000..6af8d8a7 --- /dev/null +++ b/static/vendor/select2/tests/data/tags-tests.js @@ -0,0 +1,276 @@ +module('Data adapters - Tags'); + +var SelectData = require('select2/data/select'); +var Tags = require('select2/data/tags'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var SelectTags = Utils.Decorate(SelectData, Tags); +var options = new Options({ + tags: true +}); + +test('does not trigger on blank or null terms', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: '' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); + + data.query({ + term: null + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); +}); + +test('white space is trimmed by default', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: ' ' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); + + data.query({ + term: ' One ' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); +}); + +test('does not create option if text is same but lowercase', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'one' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); +}); + +test('does not trigger for additional pages', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + page: 2 + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'One'); + assert.equal(item.text, 'One'); + }); +}); + +test('creates tag at beginning', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'o' + }, function (data) { + assert.equal(data.results.length, 2); + + var first = data.results[0]; + + assert.equal(first.id, 'o'); + assert.equal(first.text, 'o'); + }); +}); + +test('tags can be the only result', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'test' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'test'); + assert.equal(item.text, 'test'); + }); +}); + +test('tags are injected as options', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'test' + }, function (data) { + assert.equal(data.results.length, 1); + + var $children = $('#qunit-fixture .single option'); + + assert.equal($children.length, 2); + + var $tag = $children.last(); + + assert.equal($tag.val(), 'test'); + assert.equal($tag.text(), 'test'); + }); +}); + +test('old tags are removed automatically', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'first' + }, function (data) { + assert.equal(data.results.length, 1); + + var $children = $('#qunit-fixture .single option'); + + assert.equal($children.length, 2); + }); + + data.query({ + term: 'second' + }, function (data) { + assert.equal(data.results.length, 1); + + var $children = $('#qunit-fixture .single option'); + + assert.equal($children.length, 2); + + var $tag = $children.last(); + + assert.equal($tag.val(), 'second'); + assert.equal($tag.text(), 'second'); + }); +}); + +test('insertTag controls the tag location', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.insertTag = function (data, tag) { + data.push(tag); + }; + + data.query({ + term: 'o' + }, function (data) { + assert.equal(data.results.length, 2); + + var item = data.results[1]; + + assert.equal(item.id, 'o'); + assert.equal(item.text, 'o'); + }); +}); + +test('insertTag can be controlled through the options', function (assert) { + var options = new Options({ + insertTag: function (data, tag) { + data.push(tag); + } + }); + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.query({ + term: 'o' + }, function (data) { + assert.equal(data.results.length, 2); + + var item = data.results[1]; + + assert.equal(item.id, 'o'); + assert.equal(item.text, 'o'); + }); +}); + +test('createTag controls the tag object', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.createTag = function (params) { + return { + id: 0, + text: params.term + }; + }; + + data.query({ + term: 'test' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 0); + assert.equal(item.text, 'test'); + }); +}); + +test('createTag returns null for no tag', function (assert) { + var data = new SelectTags($('#qunit-fixture .single'), options); + + data.createTag = function (params) { + return null; + }; + + data.query({ + term: 'o' + }, function (data) { + assert.equal(data.results.length, 1); + }); +}); + +test('the createTag options customizes the function', function (assert) { + var data = new SelectTags( + $('#qunit-fixture .single'), + new Options({ + tags: true, + createTag: function (params) { + return { + id: params.term, + text: params.term, + tag: true + }; + } + }) + ); + + data.query({ + term: 'test' + }, function (data) { + assert.equal(data.results.length, 1); + + var item = data.results[0]; + + assert.equal(item.id, 'test'); + assert.equal(item.text, 'test'); + assert.equal(item.tag, true); + }); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/data/tokenizer-tests.js b/static/vendor/select2/tests/data/tokenizer-tests.js new file mode 100644 index 00000000..2fa01211 --- /dev/null +++ b/static/vendor/select2/tests/data/tokenizer-tests.js @@ -0,0 +1,219 @@ +module('Data adaptor - Tokenizer'); + +test('triggers the select event', function (assert) { + assert.expect(2); + + var SelectData = require('select2/data/select'); + var Tokenizer = require('select2/data/tokenizer'); + var Tags = require('select2/data/tags'); + + var Options = require('select2/options'); + var Utils = require('select2/utils'); + + var $ = require('jquery'); + + var TokenizedSelect = Utils.Decorate( + Utils.Decorate(SelectData, Tags), + Tokenizer + ); + var $select = $('#qunit-fixture .single'); + + var options = new Options({ + tags: true, + tokenSeparators: [','] + }); + + var container = new MockContainer(); + container.dropdown = container.selection = {}; + + var $container = $('
'); + + var data = new TokenizedSelect($select, options); + data.bind(container, $container); + + data.on('select', function () { + assert.ok(true, 'The select event should be triggered'); + }); + + data.query({ + term: 'first,second' + }, function () { + assert.ok(true, 'The callback should have succeeded'); + }); +}); + +test('createTag can return null', function (assert) { + assert.expect(3); + + var SelectData = require('select2/data/select'); + var Tokenizer = require('select2/data/tokenizer'); + var Tags = require('select2/data/tags'); + + var Options = require('select2/options'); + var Utils = require('select2/utils'); + + var $ = require('jquery'); + + var TokenizedSelect = Utils.Decorate( + Utils.Decorate(SelectData, Tags), + Tokenizer + ); + var $select = $('#qunit-fixture .single'); + + var options = new Options({ + tags: true, + tokenSeparators: [','], + createTag: function () { + assert.ok(true, 'createTag should have been called'); + + return null; + } + }); + + var container = new MockContainer(); + container.dropdown = container.selection = {}; + + var $container = $('
'); + + var data = new TokenizedSelect($select, options); + data.bind(container, $container); + + data.on('select', function (params) { + if (params.data == null) { + assert.ok(false, 'Null data should never be selected'); + } + }); + + data.query({ + term: 'first,second' + }, function () { + assert.ok(true, 'The callback should have succeeded'); + }); +}); + +test('createTag returning null does not cut the term', function (assert) { + assert.expect(4); + + var SelectData = require('select2/data/select'); + var Tokenizer = require('select2/data/tokenizer'); + var Tags = require('select2/data/tags'); + + var Options = require('select2/options'); + var Utils = require('select2/utils'); + + var $ = require('jquery'); + + var TokenizedSelect = Utils.Decorate( + Utils.Decorate(SelectData, Tags), + Tokenizer + ); + var $select = $('#qunit-fixture .single'); + + var options = new Options({ + tags: true, + tokenSeparators: [',', '"'], + createTag: function (params) { + var term = params.term; + + // Ignore blanks + if (term.length === 0) { + return null; + } + + // Ignore the leading quote + if (term === '"') { + return null; + } + + // If there is a leading quote, check for a second one + if (term[0] === '"' && term[term.length - 1] !== '"') { + return null; + } + + var text = term.substr(1, term.length - 2); + + return { + id: term, + text: text + }; + } + }); + + var container = new MockContainer(); + container.dropdown = container.selection = {}; + + var $container = $('
'); + + var data = new TokenizedSelect($select, options); + data.bind(container, $container); + + data.on('select', function (params) { + assert.ok(params.data, 'Data should not be null'); + + assert.equal( + params.data.id, + '"first, second"', + 'The id should have the quotes' + ); + + assert.equal( + params.data.text, + 'first, second', + 'The text should not have the quotes' + ); + }); + + data.query({ + term: '"first, second",abc' + }, function () { + assert.ok(true, 'The callback should have succeeded'); + }); +}); + +test('works with multiple tokens given', function (assert) { + assert.expect(4); + + var SelectData = require('select2/data/select'); + var Tokenizer = require('select2/data/tokenizer'); + var Tags = require('select2/data/tags'); + + var Options = require('select2/options'); + var Utils = require('select2/utils'); + + var $ = require('jquery'); + + var TokenizedSelect = Utils.Decorate( + Utils.Decorate(SelectData, Tags), + Tokenizer + ); + var $select = $('#qunit-fixture .multiple'); + + var options = new Options({ + tags: true, + tokenSeparators: [','] + }); + + var container = new MockContainer(); + container.dropdown = container.selection = {}; + + var $container = $('
'); + + var data = new TokenizedSelect($select, options); + data.bind(container, $container); + + data.on('select', function () { + assert.ok(true, 'The select event should be triggered'); + }); + + data.query({ + term: 'first,second,third' + }, function () { + assert.ok(true, 'The callback should have succeeded'); + }); + + assert.equal( + $select.children('option').length, + 3, + 'The two new tags should have been created' + ); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/dropdown/dropdownCss-tests.js b/static/vendor/select2/tests/dropdown/dropdownCss-tests.js new file mode 100644 index 00000000..9969335e --- /dev/null +++ b/static/vendor/select2/tests/dropdown/dropdownCss-tests.js @@ -0,0 +1,104 @@ +module('Dropdown - dropdownCssClass compatibility'); + +var $ = require('jquery'); +var Utils = require('select2/utils'); +var Options = require('select2/options'); + +var Dropdown = require('select2/dropdown'); +var DropdownCSS = Utils.Decorate( + Dropdown, + require('select2/compat/dropdownCss') +); + +test('all classes will be copied if :all: is used', function (assert) { + var $element = $(''); + var options = new Options({ + dropdownCssClass: ':all:' + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok($dropdown.hasClass('test')); + assert.ok($dropdown.hasClass('copy')); + assert.ok($dropdown.hasClass('works')); + assert.ok(!$dropdown.hasClass(':all:')); +}); + +test(':all: can be used with other classes', function (assert) { + var $element = $(''); + var options = new Options({ + dropdownCssClass: ':all: other' + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok($dropdown.hasClass('test')); + assert.ok($dropdown.hasClass('copy')); + assert.ok($dropdown.hasClass('works')); + assert.ok($dropdown.hasClass('other')); + assert.ok(!$dropdown.hasClass(':all:')); +}); + +test('classes can be passed in as a string', function (assert) { + var $element = $(''); + var options = new Options({ + dropdownCssClass: 'other' + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok($dropdown.hasClass('other')); +}); + +test('a function can be used based on the element', function (assert){ + var $element = $(''); + var options = new Options({ + dropdownCssClass: function ($element) { + return 'function'; + } + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok($dropdown.hasClass('function')); + assert.ok(!$dropdown.hasClass('test')); +}); + +test(':all: works around custom adapters', function (assert) { + var $element = $(''); + var options = new Options({ + dropdownCssClass: ':all: something', + adaptDropdownCssClass: function (clazz) { + return clazz + '-modified'; + } + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok($dropdown.hasClass('something')); + + assert.ok($dropdown.hasClass('test')); + assert.ok($dropdown.hasClass('test-modified')); +}); + +module('Dropdown - adaptDropdownCss compatibility'); + +test('only return when adapted', function (assert) { + var $element = $(''); + var options = new Options({ + adaptDropdownCssClass: function (clazz) { + return 'modified'; + } + }); + + var select = new DropdownCSS($element, options); + var $dropdown = select.render(); + + assert.ok(!$dropdown.hasClass('original')); + assert.ok($dropdown.hasClass('modified')); +}); diff --git a/static/vendor/select2/tests/dropdown/dropdownParent-tests.js b/static/vendor/select2/tests/dropdown/dropdownParent-tests.js new file mode 100644 index 00000000..1e474bda --- /dev/null +++ b/static/vendor/select2/tests/dropdown/dropdownParent-tests.js @@ -0,0 +1,83 @@ +module('Dropdown - attachBody - dropdownParent option'); + +test('can be a selector string', function (assert) { + assert.expect(1); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + $('#qunit-fixture').append($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: '#parent' + })); + + assert.equal( + dropdown.$dropdownParent[0], + $parent[0], + 'Should be parsed using the selector as a jQuery object' + ); +}); + +test('can be a jQuery object', function (assert) { + assert.expect(1); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + $('#qunit-fixture').append($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: $parent + })); + + assert.equal( + dropdown.$dropdownParent[0], + $parent[0], + 'Should just take the passed in jQuery object' + ); +}); + +test('defaults to the document body', function (assert) { + assert.expect(1); + + var $ = require('jquery'); + + var $select = $(''); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({})); + + assert.equal( + dropdown.$dropdownParent[0], + document.body, + 'Should default to wrapping document.body' + ); +}); diff --git a/static/vendor/select2/tests/dropdown/positioning-tests.js b/static/vendor/select2/tests/dropdown/positioning-tests.js new file mode 100644 index 00000000..2da68982 --- /dev/null +++ b/static/vendor/select2/tests/dropdown/positioning-tests.js @@ -0,0 +1,177 @@ +module('Dropdown - attachBody - positioning'); + +test('appends to the dropdown parent', function (assert) { + assert.expect(4); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: $parent + })); + + assert.equal( + $parent.children().length, + 1, + 'Only the select should be in the container' + ); + + var $dropdown = dropdown.render(); + + dropdown.bind(container, $container); + + dropdown.position($dropdown, $container); + + assert.equal( + $parent.children().length, + 1, + 'The dropdown should not be placed until after it is opened' + ); + + dropdown._showDropdown(); + + assert.equal( + $parent.children().length, + 2, + 'The dropdown should now be in the container as well' + ); + + assert.ok( + $.contains($parent[0], $dropdown[0]), + 'The dropdown should be contained within the parent container' + ); +}); + +test('dropdown is positioned down with static margins', function (assert) { + var $ = require('jquery'); + var $select = $(''); + var $parent = $('
'); + $parent.css({ + position: 'static', + marginTop: '5px', + marginLeft: '10px' + }); + + var $container = $('test'); + var container = new MockContainer(); + + $('#qunit-fixture').empty(); + + $parent.appendTo($('#qunit-fixture')); + $container.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: $parent + })); + + var $dropdown = dropdown.render(); + + assert.equal( + $dropdown[0].style.top, + 0, + 'The drodpown should not have any offset before it is displayed' + ); + + dropdown.bind(container, $container); + dropdown.position($dropdown, $container); + dropdown._showDropdown(); + + assert.ok( + dropdown.$dropdown.hasClass('select2-dropdown--below'), + 'The dropdown should be forced down' + ); + + assert.equal( + $dropdown.css('top').replace(/\D+/, ''), + $container.outerHeight() + 5, + 'The offset should be 5px at the top' + ); + + assert.equal( + $dropdown.css('left'), + '10px', + 'The offset should be 10px on the left' + ); +}); + +test('dropdown is positioned down with absolute offsets', function (assert) { + var $ = require('jquery'); + var $select = $(''); + var $parent = $('
'); + $parent.css({ + position: 'absolute', + top: '10px', + left: '5px' + }); + + var $container = $('test'); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $container.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Dropdown = require('select2/dropdown'); + var AttachBody = require('select2/dropdown/attachBody'); + + var DropdownAdapter = Utils.Decorate(Dropdown, AttachBody); + + var dropdown = new DropdownAdapter($select, new Options({ + dropdownParent: $parent + })); + + var $dropdown = dropdown.render(); + + assert.equal( + $dropdown[0].style.top, + 0, + 'The drodpown should not have any offset before it is displayed' + ); + + dropdown.bind(container, $container); + dropdown.position($dropdown, $container); + dropdown._showDropdown(); + + assert.ok( + dropdown.$dropdown.hasClass('select2-dropdown--below'), + 'The dropdown should be forced down' + ); + + assert.equal( + $dropdown.css('top').replace(/\D+/, ''), + $container.outerHeight(), + 'There should not be an extra top offset' + ); + + assert.equal( + $dropdown.css('left'), + '0px', + 'There should not be an extra left offset' + ); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/dropdown/search-a11y-tests.js b/static/vendor/select2/tests/dropdown/search-a11y-tests.js new file mode 100644 index 00000000..0876de9f --- /dev/null +++ b/static/vendor/select2/tests/dropdown/search-a11y-tests.js @@ -0,0 +1,185 @@ +module('Dropdown - Search - Accessibility'); + +var Utils = require('select2/utils'); + +var Dropdown = require('select2/dropdown'); +var DropdownSearch = Utils.Decorate( + Dropdown, + require('select2/dropdown/search') +); + +var $ = require('jquery'); + +var Options = require('select2/options'); +var options = new Options({}); + +test('role attribute is set to searchbox', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + assert.equal( + $dropdown.find('input').attr('role'), + 'searchbox', + 'The search box is marked as a search box' + ); +}); + +test('aria-autocomplete attribute is present', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + assert.equal( + $dropdown.find('input').attr('aria-autocomplete'), + 'list', + 'The search box is marked as autocomplete' + ); +}); + +test('aria-activedescendant should not be set initiailly', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'The search box should not point to anything when it is first rendered' + ); +}); + +test('aria-activedescendant should be set after highlight', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + container.trigger('results:focus', { + data: { + _resultId: 'test' + } + }); + + var $search = $dropdown.find('input'); + + assert.equal( + $search.attr('aria-activedescendant'), + 'test', + 'The search is pointing to the focused result' + ); +}); + +test('activedescendant should remove if there is no ID', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + $search.attr('aria-activedescendant', 'test'); + + container.trigger('results:focus', { + data: {} + }); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'There is no result for the search to be pointing to' + ); +}); + +test('aria-activedescendant should be removed when closed', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + $search.attr('aria-activedescendant', 'something'); + + container.trigger('close'); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'There is no active descendant when the dropdown is closed' + ); +}); + +test('aria-controls should not be set initiailly', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + + assert.ok( + !$search.attr('aria-controls'), + 'The search box should not point to the results when it is first rendered' + ); +}); + +test('aria-controls should be set when opened', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + + container.trigger('open'); + + assert.ok( + $search.attr('aria-controls'), + 'The search should point to the results when it is opened' + ); +}); + +test('aria-controls should be removed when closed', function (assert) { + var $select = $('#qunit-fixture .single'); + + var dropdown = new DropdownSearch($select, options); + var $dropdown = dropdown.render(); + + var container = new MockContainer(); + dropdown.bind(container, $('')); + + var $search = $dropdown.find('input'); + $search.attr('aria-controls', 'something'); + + container.trigger('close'); + + assert.ok( + !$search.attr('aria-controls'), + 'There are no results for the search box to point to when it is closed' + ); +}); diff --git a/static/vendor/select2/tests/dropdown/selectOnClose-tests.js b/static/vendor/select2/tests/dropdown/selectOnClose-tests.js new file mode 100644 index 00000000..3f1d1d41 --- /dev/null +++ b/static/vendor/select2/tests/dropdown/selectOnClose-tests.js @@ -0,0 +1,137 @@ +module('Dropdown - selectOnClose'); + +var $ = require('jquery'); + +var Utils = require('select2/utils'); +var Options = require('select2/options'); + +var SelectData = require('select2/data/select'); + +var Results = require('select2/results'); +var SelectOnClose = require('select2/dropdown/selectOnClose'); + +var ModifiedResults = Utils.Decorate(Results, SelectOnClose); + +var options = new Options({ + selectOnClose: true +}); + +test('will not trigger if no results were given', function (assert) { + assert.expect(0); + + var $element = $(''); + var select = new ModifiedResults($element, options, new SelectData($element)); + + var $dropdown = select.render(); + + var container = new MockContainer(); + select.bind(container, $('
')); + + select.on('select', function () { + assert.ok(false, 'The select event should not have been triggered'); + }); + + container.trigger('close'); +}); + +test('will not trigger if the results list is empty', function (assert) { + assert.expect(1); + + var $element = $(''); + var select = new ModifiedResults($element, options, new SelectData($element)); + + var $dropdown = select.render(); + + var container = new MockContainer(); + select.bind(container, $('
')); + + select.on('select', function () { + assert.ok(false, 'The select event should not have been triggered'); + }); + + select.append({ + results: [] + }); + + assert.equal( + $dropdown.find('li').length, + 0, + 'There should not be any results in the dropdown' + ); + + container.trigger('close'); +}); + +test('will not trigger if no results here highlighted', function (assert) { + assert.expect(2); + + var $element = $(''); + var select = new ModifiedResults($element, options, new SelectData($element)); + + var $dropdown = select.render(); + + var container = new MockContainer(); + select.bind(container, $('
')); + + select.on('select', function () { + assert.ok(false, 'The select event should not have been triggered'); + }); + + select.append({ + results: [ + { + id: '1', + text: 'Test' + } + ] + }); + + assert.equal( + $dropdown.find('li').length, + 1, + 'There should be one result in the dropdown' + ); + + assert.equal( + $.trim($dropdown.find('li').text()), + 'Test', + 'The result should be the same as the one we appended' + ); + + container.trigger('close'); +}); + +test('will trigger if there is a highlighted result', function (assert) { + assert.expect(2); + + var $element = $(''); + var select = new ModifiedResults($element, options, new SelectData($element)); + + var $dropdown = select.render(); + + var container = new MockContainer(); + select.bind(container, $('
')); + + select.on('select', function () { + assert.ok(true, 'The select event should have been triggered'); + }); + + select.append({ + results: [ + { + id: '1', + text: 'Test' + } + ] + }); + + assert.equal( + $dropdown.find('li').length, + 1, + 'There should be one result in the dropdown' + ); + + $dropdown.find('li').addClass('select2-results__option--highlighted'); + + container.trigger('close'); +}); diff --git a/static/vendor/select2/tests/dropdown/stopPropagation-tests.js b/static/vendor/select2/tests/dropdown/stopPropagation-tests.js new file mode 100644 index 00000000..240a3e66 --- /dev/null +++ b/static/vendor/select2/tests/dropdown/stopPropagation-tests.js @@ -0,0 +1,33 @@ +module('Dropdown - Stoping event propagation'); + +var Dropdown = require('select2/dropdown'); +var StopPropagation = require('select2/dropdown/stopPropagation'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var CustomDropdown = Utils.Decorate(Dropdown, StopPropagation); + +var options = new Options(); + +test('click event does not propagate', function (assert) { + assert.expect(1); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var dropdown = new CustomDropdown($('#qunit-fixture select'), options); + + var $dropdown = dropdown.render(); + dropdown.bind(container, $container); + + $container.append($dropdown); + $container.on('click', function () { + assert.ok(false, 'The click event should have been stopped'); + }); + + $dropdown.trigger('click'); + + assert.ok(true, 'Something went wrong if this failed'); +}); diff --git a/static/vendor/select2/tests/helpers.js b/static/vendor/select2/tests/helpers.js new file mode 100644 index 00000000..9409c8b6 --- /dev/null +++ b/static/vendor/select2/tests/helpers.js @@ -0,0 +1,50 @@ +// Restore the require/define +var require = $.fn.select2.amd.require; +var define = $.fn.select2.amd.define; + +// Disable jQuery's binding to $ +jQuery.noConflict(); + +var Utils = require('select2/utils'); + +function MockContainer () { + MockContainer.__super__.constructor.call(this); +} + +Utils.Extend(MockContainer, Utils.Observable); + +MockContainer.prototype.isOpen = function () { + return this.isOpen; +}; + +var log = []; +var testName; + +QUnit.done(function (test_results) { + var tests = []; + for(var i = 0, len = log.length; i < len; i++) { + var details = log[i]; + tests.push({ + name: details.name, + result: details.result, + expected: details.expected, + actual: details.actual, + source: details.source + }); + } + test_results.tests = tests; + + window.global_test_results = test_results; +}); +QUnit.testStart(function(testDetails){ + QUnit.log(function(details){ + if (!details.result) { + details.name = testDetails.name; + log.push(details); + } + }); +}); + +define('qunit', function () { + return QUnit; +}) \ No newline at end of file diff --git a/static/vendor/select2/tests/integration-jq1.html b/static/vendor/select2/tests/integration-jq1.html new file mode 100644 index 00000000..d8d0ef55 --- /dev/null +++ b/static/vendor/select2/tests/integration-jq1.html @@ -0,0 +1,21 @@ + + + + + + + +
+
+ + + + + + + + + + + + diff --git a/static/vendor/select2/tests/integration-jq2.html b/static/vendor/select2/tests/integration-jq2.html new file mode 100644 index 00000000..97f73828 --- /dev/null +++ b/static/vendor/select2/tests/integration-jq2.html @@ -0,0 +1,21 @@ + + + + + + + +
+
+ + + + + + + + + + + + diff --git a/static/vendor/select2/tests/integration-jq3.html b/static/vendor/select2/tests/integration-jq3.html new file mode 100644 index 00000000..2f99fb5b --- /dev/null +++ b/static/vendor/select2/tests/integration-jq3.html @@ -0,0 +1,21 @@ + + + + + + + +
+
+ + + + + + + + + + + + diff --git a/static/vendor/select2/tests/integration/dom-changes.js b/static/vendor/select2/tests/integration/dom-changes.js new file mode 100644 index 00000000..65f3fb91 --- /dev/null +++ b/static/vendor/select2/tests/integration/dom-changes.js @@ -0,0 +1,288 @@ +module('DOM integration'); + +test('adding a new unselected option changes nothing', function (assert) { + // Any browsers which support mutation observers will not trigger the event + var expected = 4; + if (window.MutationObserver) { + expected = 2; + } else if (!window.addEventListener) { + expected = 2; + } + + assert.expect(expected); + + var asyncDone = null; + var syncDone = assert.async(); + + if (expected != 2) { + asyncDone = assert.async(); + } + + var $ = require('jquery'); + var Options = require('select2/options'); + var Select2 = require('select2/core'); + + var $select = $( + '' + ); + + $('#qunit-fixture').append($select); + + var select = new Select2($select); + + select.on('selection:update', function (args) { + assert.equal( + args.data.length, + 1, + 'There was more than one selection' + ); + + assert.equal( + args.data[0].id, + 'One', + 'The selection changed to something other than One' + ); + + if (expected != 2) { + asyncDone(); + } + }); + + assert.equal( + $select.val(), + 'One' + ); + + var $option = $(''); + + $select.append($option); + + assert.equal( + $select.val(), + 'One' + ); + + syncDone(); +}); + +test('adding a new selected option changes the value', function (assert) { + // handle IE 8 not being supported + var expected = 4; + if (!window.MutationObserver && !window.addEventListener) { + expected = 2; + } + + assert.expect(expected); + + var asyncDone = null; + var syncDone = assert.async(); + + if (expected != 2) { + asyncDone = assert.async(); + } + + var $ = require('jquery'); + var Options = require('select2/options'); + var Select2 = require('select2/core'); + + var $select = $( + '' + ); + + $('#qunit-fixture').append($select); + + var select = new Select2($select); + + select.on('selection:update', function (args) { + assert.equal( + args.data.length, + 1, + 'There was more than one selection' + ); + + assert.equal( + args.data[0].id, + 'Three', + 'The selection did not change to Three' + ); + + if (expected != 2) { + asyncDone(); + } + }); + + assert.equal( + $select.val(), + 'One' + ); + + var $option = $(''); + + $select.append($option); + + assert.equal( + $select.val(), + 'Three' + ); + + syncDone(); +}); + +test('removing an unselected option changes nothing', function (assert) { + // Any browsers which support mutation observers will not trigger the event + var expected = 4; + if (!window.MutationObserver && !window.addEventListener) { + expected = 2; + } + + assert.expect(expected); + + var asyncDone = null; + var syncDone = assert.async(); + + if (expected != 2) { + asyncDone = assert.async(); + } + + var $ = require('jquery'); + var Options = require('select2/options'); + var Select2 = require('select2/core'); + + var $select = $( + '' + ); + + $('#qunit-fixture').append($select); + + var select = new Select2($select); + + select.on('selection:update', function (args) { + assert.equal( + args.data.length, + 1, + 'There was more than one selection' + ); + + assert.equal( + args.data[0].id, + 'One', + 'The selection changed to something other than One' + ); + + if (expected != 2) { + asyncDone(); + } + }); + + assert.equal( + $select.val(), + 'One' + ); + + $select.children().eq(1).remove(); + + assert.equal( + $select.val(), + 'One' + ); + + syncDone(); +}); + +test('removing a selected option changes the value', function (assert) { + // handle IE 8 not being supported + var expected = 3; + if (!window.MutationObserver && !window.addEventListener) { + expected = 2; + } + + assert.expect(expected); + + var asyncDone = null; + var syncDone = assert.async(); + + if (expected != 2) { + asyncDone = assert.async(); + } + + var $ = require('jquery'); + var Options = require('select2/options'); + var Select2 = require('select2/core'); + + var $select = $( + '' + ); + + $('#qunit-fixture').append($select); + + var select = new Select2($select); + + select.on('selection:update', function (args) { + assert.equal( + args.data.length, + 1, + 'There was more than one selection' + ); + + if (expected != 2) { + asyncDone(); + } + }); + + assert.equal( + $select.val(), + 'One' + ); + + $select.children().eq(0).remove(); + + assert.equal( + $select.val(), + 'Two' + ); + + syncDone(); +}); + +test('searching tags does not loose focus', function (assert) { + assert.expect(1); + + var asyncDone = assert.async(); + var $ = require('jquery'); + var Options = require('select2/options'); + var Select2 = require('select2/core'); + + var $select = $( + '' + ); + + $('#qunit-fixture').append($select); + + var select = new Select2($select, {tags: true}); + + var inputEl = select.selection.$search[0]; + inputEl.focus(); + + select.on('selection:update', function() { + assert.equal(document.activeElement, inputEl); + asyncDone(); + }); + + select.selection.trigger('query', {term: 'f'}); + select.selection.trigger('query', {term: 'ff'}); +}); diff --git a/static/vendor/select2/tests/integration/jquery-calls.js b/static/vendor/select2/tests/integration/jquery-calls.js new file mode 100644 index 00000000..d7c3926f --- /dev/null +++ b/static/vendor/select2/tests/integration/jquery-calls.js @@ -0,0 +1,98 @@ +module('select2(val)'); + +var Utils = require('select2/utils'); + +test('multiple elements with arguments works', function (assert) { + var $ = require('jquery'); + require('jquery.select2'); + + var $first = $( + '' + ); + var $second = $first.clone(); + + var $both = $first.add($second); + $both.select2(); + + $both.select2('val', '2'); + + assert.equal( + $first.val(), + '2', + 'The call should change the value on the first element' + ); + assert.equal( + $second.val(), + '2', + 'The call should also change the value on the second element' + ); +}); + +test('initializes when jQuery $.data contains' + + ' cyclic reference', function (assert) { + var $ = require('jquery'); + require('jquery.select2'); + + var $select = $( + '' + ); + + // Add a circular reference object using jQuery. + var recursiveObject = {}; + + recursiveObject.same = recursiveObject; + + $select.data('same', recursiveObject); + + $select.select2(); + + assert.equal( + $select.val(), + '3', + 'The option value should be pulled correctly' + ); +}); + +test('$element.data returns instance and options correctly', + function (assert) { + var $ = require('jquery'); + require('jquery.select2'); + + var $select = $( + '' + ); + + // Initialize. + $select.select2({maximumSelectionLength: 2, multiple: true}); + + assert.equal( + $select.val(), + '3', + 'Only 1 option should be pulled.' + ); + + // Try to resolve instance via .data('select2'). + var $instance = $select.data('select2'); + assert.ok($instance); + assert.ok($instance.options); + + // Ensure $select.data('select2') is the same instance + // created by .select2() + assert.equal($instance, Utils.GetData($instance.$element[0], + 'select2')); + + // Ensure initialized property matches. + assert.equal($instance.options.options.maximumSelectionLength, + 2); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/integration/select2-methods.js b/static/vendor/select2/tests/integration/select2-methods.js new file mode 100644 index 00000000..b1e344a5 --- /dev/null +++ b/static/vendor/select2/tests/integration/select2-methods.js @@ -0,0 +1,139 @@ +module('select2(data)'); + +var $ = require('jquery'); +var Select2 = require('select2/core'); +var Options = require('select2/options'); + +test('single default selection returned', function (assert) { + var $select = $( + '' + ); + var options = new Options({}); + + var select = new Select2($select, options); + + var items = select.data(); + + assert.equal( + items.length, + 1, + 'The one selected item should be returned' + ); + + var first = items[0]; + + assert.equal( + first.id, + '3', + 'The first option was correct' + ); + + assert.equal( + first.text, + 'Three', + 'The first option was correct' + ); +}); + +test('multiple default selections returned', function (assert) { + var $select = $( + '' + ); + var options = new Options({}); + + var select = new Select2($select, options); + + var items = select.data(); + + assert.equal( + items.length, + 2, + 'The two selected items should be returned' + ); + + var first = items[0]; + + assert.equal( + first.id, + 'One', + 'The first option was correct' + ); + + var second = items[1]; + + assert.equal( + second.id, + '3', + 'The option value should be pulled correctly' + ); +}); + +module('select2(val)'); + +test('single value matches jquery value', function (assert) { + var $select = $( + '' + ); + var options = new Options({}); + + var select = new Select2($select, options); + + var value = select.val(); + + assert.equal( + value, + '3', + 'The value should match the option tag attribute' + ); + + assert.equal( + value, + $select.val(), + 'The value should match the jquery value' + ); +}); + +test('multiple value matches the jquery value', function (assert) { + var $select = $( + '' + ); + var options = new Options({}); + + var select = new Select2($select, options); + + var value = select.val(); + + assert.equal( + value.length, + 2, + 'Two options should be selected' + ); + + assert.deepEqual( + value, + ['One', '3'], + 'The values should match the option tag attribute' + ); + + assert.deepEqual( + value, + $select.val(), + 'The values should match the jquery values' + ); +}); diff --git a/static/vendor/select2/tests/options/ajax-tests.js b/static/vendor/select2/tests/options/ajax-tests.js new file mode 100644 index 00000000..eb65e9ef --- /dev/null +++ b/static/vendor/select2/tests/options/ajax-tests.js @@ -0,0 +1,50 @@ +module('Defaults - Ajax'); + +test('options are merged recursively with default options', function (assert) { + var defaults = require('select2/defaults'); + + var ajaxDelay = 250; + var ajaxUrl = 'http://www.test.com'; + + var mergedOptions; + + defaults.set('ajax--delay', ajaxDelay); + + mergedOptions = defaults.apply({ + ajax: { + url: ajaxUrl + } + }); + + assert.equal( + mergedOptions.ajax.delay, + ajaxDelay, + 'Ajax default options are present on the merged options' + ); + + assert.equal( + mergedOptions.ajax.url, + ajaxUrl, + 'Ajax provided options are present on the merged options' + ); + + defaults.reset(); +}); + +test('more than one default option can be changed via set()', function(assert) { + var defaults = require('select2/defaults'); + var ajaxDelay = 123; + var dataDataType = 'xml'; + defaults.set('ajax--delay', ajaxDelay); + defaults.set('ajax--data-type', dataDataType); + + assert.equal( + defaults.defaults.ajax.delay, + ajaxDelay, + 'Both ajax.delay and ajax.dataType present in defaults'); + assert.equal( + defaults.defaults.ajax.dataType, + dataDataType, + 'Both ajax.delay and ajax.dataType present in defaults'); + defaults.reset(); +}); diff --git a/static/vendor/select2/tests/options/data-tests.js b/static/vendor/select2/tests/options/data-tests.js new file mode 100644 index 00000000..107a2f0c --- /dev/null +++ b/static/vendor/select2/tests/options/data-tests.js @@ -0,0 +1,44 @@ +module('Options - Attributes'); + +var $ = require('jquery'); + +var Options = require('select2/options'); + +test('no nesting', function (assert) { + var $test = $(''); + + var options = new Options({}, $test); + + assert.equal(options.get('test'), 'test'); +}); + +test('with nesting', function (assert) { + var $test = $(''); + + if ($test[0].dataset == null) { + assert.ok( + true, + 'We can not run this test with jQuery 1.x if dataset is not implemented' + ); + + return; + } + + var options = new Options({}, $test); + + assert.ok(!(options.get('first-Second'))); + assert.equal(options.get('first').second, 'test'); +}); + +test('overrides initialized data', function (assert) { + var $test = $(''); + + var options = new Options({ + options: 'yes', + override: 'no' + }, $test); + + assert.equal(options.get('options'), 'yes'); + assert.equal(options.get('override'), 'yes'); + assert.equal(options.get('data'), 'yes'); +}); diff --git a/static/vendor/select2/tests/options/deprecated-tests.js b/static/vendor/select2/tests/options/deprecated-tests.js new file mode 100644 index 00000000..a51bba31 --- /dev/null +++ b/static/vendor/select2/tests/options/deprecated-tests.js @@ -0,0 +1,250 @@ +module('Options - Deprecated - initSelection'); + +var $ = require('jquery'); +var Options = require('select2/options'); + +test('converted into dataAdapter.current', function (assert) { + assert.expect(5); + + var $test = $(''); + var called = false; + + var options = new Options({ + initSelection: function ($element, callback) { + called = true; + + callback([{ + id: '1', + text: '2' + }]); + } + }, $test); + + assert.ok(!called, 'initSelection should not have been called'); + + var DataAdapter = options.get('dataAdapter'); + var data = new DataAdapter($test, options); + + data.current(function (data) { + assert.equal( + data.length, + 1, + 'There should have only been one object selected' + ); + + var item = data[0]; + + assert.equal( + item.id, + '1', + 'The id should have been set by initSelection' + ); + + assert.equal( + item.text, + '2', + 'The text should have been set by initSelection' + ); + }); + + assert.ok(called, 'initSelection should have been called'); +}); + +test('single option converted to array automatically', function (assert) { + assert.expect(2); + + var $test = $(''); + var called = false; + + var options = new Options({ + initSelection: function ($element, callback) { + called = true; + + callback({ + id: '1', + text: '2' + }); + } + }, $test); + + var DataAdapter = options.get('dataAdapter'); + var data = new DataAdapter($test, options); + + data.current(function (data) { + assert.ok( + $.isArray(data), + 'The data should have been converted to an array' + ); + }); + + assert.ok(called, 'initSelection should have been called'); +}); + +test('only called once', function (assert) { + assert.expect(8); + + var $test = $(''); + var called = 0; + + var options = new Options({ + initSelection: function ($element, callback) { + called++; + + callback([{ + id: '1', + text: '2' + }]); + } + }, $test); + + var DataAdapter = options.get('dataAdapter'); + var data = new DataAdapter($test, options); + + data.current(function (data) { + assert.equal( + data.length, + 1, + 'There should have only been a single option' + ); + + var item = data[0]; + + assert.equal( + item.id, + '1', + 'The id should match the one given by initSelection' + ); + + assert.equal( + item.text, + '2', + 'The text should match the one given by initSelection' + ); + }); + + assert.equal( + called, + 1, + 'initSelection should have been called' + ); + + data.current(function (data) { + assert.equal( + data.length, + 1, + 'There should have only been a single option' + ); + + var item = data[0]; + + assert.equal( + item.id, + '3', + 'The id should match the value given in the DOM' + ); + + assert.equal( + item.text, + '4', + 'The text should match the text given in the DOM' + ); + }); + + assert.equal( + called, + 1, + 'initSelection should have only been called once' + ); +}); + +module('Options - Deprecated - query'); + +test('converted into dataAdapter.query automatically', function (assert) { + assert.expect(6); + + var $test = $(''); + var called = false; + + var options = new Options({ + query: function (params) { + called = true; + + params.callback({ + results: [ + { + id: 'test', + text: params.term + } + ] + }); + } + }, $test); + + assert.ok(!called, 'The query option should not have been called'); + + var DataAdapter = options.get('dataAdapter'); + var data = new DataAdapter($test, options); + + data.query({ + term: 'term' + }, function (data) { + assert.ok( + 'results' in data, + 'It should have included the results key' + ); + + assert.equal( + data.results.length, + 1, + 'There should have only been a single result returned' + ); + + var item = data.results[0]; + + assert.equal( + item.id, + 'test', + 'The id should have been returned from the query function' + ); + + assert.equal( + item.text, + 'term', + 'The text should have matched the term that was passed in' + ); + }); + + assert.ok(called, 'The query function should have been called'); +}); + +module('Options - deprecated - data-ajax-url'); + +test('converted ajax-url to ajax--url automatically', function (assert) { + var $test = $(''); + var options = new Options({}, $test); + + assert.ok( + options.get('ajax'), + 'The `ajax` key was automatically created' + ); + assert.equal( + options.get('ajax').url, + 'test://url', + 'The `url` property for the `ajax` option was filled in correctly' + ); +}); + +test('converted select2-tags to data/tags automatically', function (assert) { + var $test = $(''); + var options = new Options({}, $test); + + assert.ok( + options.get('tags'), + 'The `tags` key is automatically set to true' + ); + assert.equal( + options.get('data'), + 'original data', + 'The `data` key is created with the original data' + ); +}); diff --git a/static/vendor/select2/tests/options/translation-tests.js b/static/vendor/select2/tests/options/translation-tests.js new file mode 100644 index 00000000..34b86d33 --- /dev/null +++ b/static/vendor/select2/tests/options/translation-tests.js @@ -0,0 +1,288 @@ +var $ = require('jquery'); +var Options = require('select2/options'); +var Defaults = require('select2/defaults'); + +module('Options - Translations', { + beforeEach: function () { + Defaults.reset(); + }, + afterEach: function () { + Defaults.reset(); + } +}); + +test('partial dictonaries are reset when default reset', function (assert) { + Defaults.set('language', { + test: 'testing' + }); + + Defaults.reset(); + + assert.ok( + !Defaults.defaults.language.test, + 'The partial dictionary should have been reset' + ); +}); + +test('default language chain is English', function (assert) { + var $element = $(''); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['en'] + ); +}); + +test( + 'default translation includes all of the required messages', + function (assert) { + var $element = $(''); + + var options = new Options({}, $element); + + assert.deepEqual( + Object.keys(options.get('translations').all()), + [ + 'errorLoading', + 'inputTooLong', + 'inputTooShort', + 'loadingMore', + 'maximumSelected', + 'noResults', + 'searching', + 'removeAllItems' + ] + ); + } +); + +test('partial dictionaries can be passed', function (assert) { + var $element = $(''); + + var options = new Options({ + language: { + searching: function () { + return 'Something'; + } + } + }, $element); + + var translations = options.get('translations'); + + assert.equal( + translations.get('searching')(), + 'Something', + 'The partial dictionary still overrides translations' + ); + + assert.equal( + translations.get('noResults')(), + 'No results found', + 'You can still get English translations for keys not passed in' + ); +}); + +test('partial dictionaries can be combined with defaults', function (assert) { + var $element = $(''); + + Defaults.set('language', { + test: function () { + return 'Testing'; + } + }); + + var options = new Options({ + language: { + searching: function () { + return 'Something'; + } + } + }, $element); + + var translations = options.get('translations'); + + assert.equal( + translations.get('searching')(), + 'Something', + 'The partial dictionary still overrides translations' + ); + + assert.equal( + translations.get('test')(), + 'Testing', + 'The defaults were included in the fallback chain' + ); + + assert.equal( + translations.get('noResults')(), + 'No results found', + 'You can still get English translations for keys not passed in' + ); +}); + +test('partial dictionaries can used in fallback chains', function (assert) { + var $element = $(''); + + var options = new Options({ + language: [ + { + searching: function () { + return 'Something'; + } + }, + { + test: function () { + return 'Testing'; + } + } + ] + }, $element); + + var translations = options.get('translations'); + + assert.equal( + translations.get('searching')(), + 'Something', + 'The partial dictionary still overrides translations' + ); + + assert.equal( + translations.get('test')(), + 'Testing', + 'The defaults were included in the fallback chain' + ); + + assert.equal( + translations.get('noResults')(), + 'No results found', + 'You can still get English translations for keys not passed in' + ); +}); + +test('language can be set via the options', function (assert) { + var $element = $(''); + + var options = new Options({ + language: 'es' + }, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'en'] + ); +}); + +test('multi-part language is broken out', function (assert) { + var $element = $(''); + + var options = new Options({ + language: 'pt-BR' + }, $element); + + assert.deepEqual( + options.get('language'), + ['pt-BR', 'pt', 'en'] + ); +}); + +test('default language can be set', function (assert) { + var $element = $(''); + + Defaults.set('language', 'es'); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'en'] + ); +}); + +test('lanugage set via options adds to default chain', function (assert) { + var $element = $(''); + + Defaults.set('language', 'es'); + + var options = new Options({ + language: 'it' + }, $element); + + assert.deepEqual( + options.get('language'), + ['it', 'es', 'en'] + ); +}); + +test('default language chain can be set', function (assert) { + var $element = $(''); + + Defaults.set('language', ['es', 'it', 'en']); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'it', 'en'] + ); +}); + +test('language can be set by lang attr', function (assert) { + var $element = $(''); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'en'] + ); +}); + +test('language can be inherited by lang attr', function (assert) { + var $element = $('
').find('select'); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'en'] + ); +}); + +test('multi-part language can be inherited by lang attr', function (assert) { + var $element = $('
').find('select'); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['pt-BR', 'pt', 'en'] + ); +}); + +test('lang attr overrides default language', function (assert) { + var $element = $(''); + + Defaults.set('language', 'es'); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['it', 'es', 'en'] + ); +}); + +test('default language overrides inherited lang attr', function (assert) { + var $element = $('
').find('select'); + + Defaults.set('language', 'es'); + + var options = new Options({}, $element); + + assert.deepEqual( + options.get('language'), + ['es', 'it', 'en'] + ); +}); diff --git a/static/vendor/select2/tests/options/width-tests.js b/static/vendor/select2/tests/options/width-tests.js new file mode 100644 index 00000000..4f774b9c --- /dev/null +++ b/static/vendor/select2/tests/options/width-tests.js @@ -0,0 +1,84 @@ +module('Options - Width'); + +var $ = require('jquery'); + +var Select2 = require('select2/core'); +var select = new Select2($('')); + +test('string passed as width', function (assert) { + var $test = $(''); + + var width = select._resolveWidth($test, '80%'); + + assert.equal(width, '80%'); +}); + +test('width from style attribute', function (assert) { + var $test = $(''); + + var width = select._resolveWidth($test, 'style'); + + assert.equal(width, null); +}); + +test('width from computed element width', function (assert) { + var $style = $( + '' + ); + var $test = $(''); + + $('#qunit-fixture').append($style); + $('#qunit-fixture').append($test); + + var width = select._resolveWidth($test, 'element'); + + assert.equal(width, '500px'); +}); + +test('resolve gets the style if it is there', function (assert) { + var $test = $(''); + + $('#qunit-fixture').append($style); + $('#qunit-fixture').append($test); + + var width = select._resolveWidth($test, 'resolve'); + + assert.equal(width, '500px'); +}); + +test('computedstyle gets the style if parent is invisible', function (assert) { + var $style = $( + '' + ); + var $test = $( + '
' + + '' + + '
' + ); + + $('#qunit-fixture').append($style); + $('#qunit-fixture').append($test); + + var width = select._resolveWidth($test.find('select'), 'computedstyle'); + + assert.equal(width, '500px'); +}); diff --git a/static/vendor/select2/tests/results/a11y-tests.js b/static/vendor/select2/tests/results/a11y-tests.js new file mode 100644 index 00000000..ca01f21f --- /dev/null +++ b/static/vendor/select2/tests/results/a11y-tests.js @@ -0,0 +1,25 @@ +module('Results - Accessibility'); + +var $ = require('jquery'); + +var Options = require('select2/options'); + +var Results = require('select2/results'); + +test('role of results should be a listbox', function (assert) { + var results = new Results($(''), new Options({})); + + var $results = results.render(); + + assert.equal($results.attr('role'), 'listbox'); +}); + +test('multiple select should have aria-multiselectable', function (assert) { + var results = new Results($(''), new Options({ + multiple: true + })); + + var $results = results.render(); + + assert.equal($results.attr('aria-multiselectable'), 'true'); +}); diff --git a/static/vendor/select2/tests/results/focusing-tests.js b/static/vendor/select2/tests/results/focusing-tests.js new file mode 100644 index 00000000..08a2ef3c --- /dev/null +++ b/static/vendor/select2/tests/results/focusing-tests.js @@ -0,0 +1,241 @@ +module('Results - highlighting results'); + +test('results:all with no data skips results:focus', function (assert) { + assert.expect(0); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + + var results = new Results($select, new Options({})); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + results.render(); + + results.bind(container, $container); + + results.on('results:focus', function (params) { + assert.ok(false, 'The results:focus event was triggered'); + }); + + container.trigger('results:all', { + data: { + results: [] + } + }); +}); + +test('results:all triggers results:focus on the first item', function (assert) { + assert.expect(2); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + + var results = new Results($select, new Options({})); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + results.render(); + + results.bind(container, $container); + + results.on('results:focus', function (params) { + assert.equal(params.data.id, 'test'); + assert.equal(params.data.text, 'Test'); + }); + + container.trigger('results:all', { + data: { + results: [ + { + id: 'test', + text: 'Test' + } + ] + } + }); +}); + +test('results:append does not trigger results:focus', function (assert) { + assert.expect(0); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + + var results = new Results($select, new Options({})); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + results.render(); + + results.bind(container, $container); + + results.on('results:focus', function () { + assert.ok(false, 'The results:focus event was triggered'); + }); + + container.trigger('results:append', { + data: { + results: [ + { + id: 'test', + text: 'Test' + } + ] + } + }); +}); + +test('scrollAfterSelect triggers results:focus', function (assert) { + assert.expect(3); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + + var options = new Options({ scrollAfterSelect: true }); + var results = new Results($select, options); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + results.render(); + + results.bind(container, $container); + + // check that default for scrollAfterSelect is true + assert.equal(options.get('scrollAfterSelect'), true); + + results.append({ + results: [ + { + id: 'test', + text: 'Test' + } + ] + }); + + results.on('results:focus', function (params) { + assert.equal(params.data.id, 'test'); + assert.equal(params.data.text, 'Test'); + }); + + container.trigger('select', {}); +}); + +test('!scrollAfterSelect does not trigger results:focus', function (assert) { + assert.expect(1); + + var $ = require('jquery'); + + var $select = $(''); + var $parent = $('
'); + + var $container = $(''); + var container = new MockContainer(); + + $parent.appendTo($('#qunit-fixture')); + $select.appendTo($parent); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + + var options = new Options({ scrollAfterSelect: false }); + var results = new Results($select, options); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + results.render(); + + results.bind(container, $container); + + // check that default for scrollAfterSelect is false + assert.equal(options.get('scrollAfterSelect'), false); + + results.append({ + results: [ + { + id: 'test', + text: 'Test' + } + ] + }); + + results.on('results:focus', function () { + assert.ok(false, 'The results:focus event was triggered'); + }); + + container.trigger('select', {}); +}); diff --git a/static/vendor/select2/tests/results/infiniteScroll-tests.js b/static/vendor/select2/tests/results/infiniteScroll-tests.js new file mode 100644 index 00000000..89bece63 --- /dev/null +++ b/static/vendor/select2/tests/results/infiniteScroll-tests.js @@ -0,0 +1,126 @@ +module('Results - Infinite scrolling'); + +test('loadingMore is triggered even without a scrollbar', function (assert) { + assert.expect(1); + + var $ = require('jquery'); + + var $select = $(''); + + var $container = $(''); + var container = new MockContainer(); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + var InfiniteScroll = require('select2/dropdown/infiniteScroll'); + + var InfiniteScrollResults = Utils.Decorate(Results, InfiniteScroll); + + var results = new InfiniteScrollResults($select, new Options({})); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + $('#qunit-fixture').append(results.render()); + + results.bind(container, $container); + + results.on('query:append', function () { + assert.ok(true, 'It tried to load more immediately'); + }); + + container.trigger('results:all', { + data: { + results: [ + { + id: 'test', + text: 'Test' + } + ], + pagination: { + more: true + } + } + }); +}); + +test('loadingMore is not triggered without scrolling', function (assert) { + assert.expect(0); + + var $ = require('jquery'); + + var $select = $(''); + + var $container = $(''); + var container = new MockContainer(); + + var Utils = require('select2/utils'); + var Options = require('select2/options'); + + var Results = require('select2/results'); + var InfiniteScroll = require('select2/dropdown/infiniteScroll'); + + var InfiniteScrollResults = Utils.Decorate(Results, InfiniteScroll); + + var results = new InfiniteScrollResults($select, new Options({})); + + // Fake the data adapter for the `setClasses` method + results.data = {}; + results.data.current = function (callback) { + callback([{ id: 'test' }]); + }; + + var $results = results.render(); + + $('#qunit-fixture').append($results); + $results.css('max-height', '100px'); + + results.bind(container, $container); + + results.on('query:append', function () { + assert.ok(false, 'It tried to load more immediately'); + }); + + container.trigger('results:all', { + data: { + results: [ + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + }, + { + id: 'test', + text: 'Test' + } + ], + pagination: { + more: true + } + } + }); +}); diff --git a/static/vendor/select2/tests/results/option-tests.js b/static/vendor/select2/tests/results/option-tests.js new file mode 100644 index 00000000..96570501 --- /dev/null +++ b/static/vendor/select2/tests/results/option-tests.js @@ -0,0 +1,116 @@ +module('Results - option'); + +var $ = require('jquery'); + +var Options = require('select2/options'); + +var Results = require('select2/results'); + +test('disabled property on option is respected - enabled', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + element: $option[0] + }); + + assert.notEqual(option.getAttribute('aria-disabled'), 'true'); +}); + +test('disabled property on option is respected - disabled', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + element: $option[0] + }); + + assert.equal(option.getAttribute('aria-disabled'), 'true'); +}); + +test('disabled property on enabled optgroup is respected', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + element: $option[0] + }); + + assert.notEqual(option.getAttribute('aria-disabled'), 'true'); +}); + +test('disabled property on disabled optgroup is respected', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + element: $option[0] + }); + + assert.equal(option.getAttribute('aria-disabled'), 'true'); +}); + +test('option in disabled optgroup is disabled', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $('') + .find('option'); + var option = results.option({ + element: $option[0] + }); + + assert.equal(option.getAttribute('aria-disabled'), 'true'); +}); + +test('options are not selected by default', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + id: 'test', + element: $option[0] + }); + + assert.equal(option.getAttribute('aria-selected'), 'false'); +}); + +test('options with children are given the group role', function(assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + children: [{ + id: 'test' + }], + element: $option[0] + }); + + assert.equal(option.getAttribute('role'), 'group'); +}); + +test('options with children have the aria-label set', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + children: [{ + id: 'test' + }], + element: $option[0], + text: 'test' + }); + + assert.equal(option.getAttribute('aria-label'), 'test'); +}); + +test('non-group options are given the option role', function (assert) { + var results = new Results($(''), new Options({})); + + var $option = $(''); + var option = results.option({ + id: 'test', + element: $option[0] + }); + + assert.equal(option.getAttribute('role'), 'option'); +}); diff --git a/static/vendor/select2/tests/selection/allowClear-tests.js b/static/vendor/select2/tests/selection/allowClear-tests.js new file mode 100644 index 00000000..273f80fd --- /dev/null +++ b/static/vendor/select2/tests/selection/allowClear-tests.js @@ -0,0 +1,400 @@ +module('Selection containers - Placeholders - Allow clear'); + +var Placeholder = require('select2/selection/placeholder'); +var AllowClear = require('select2/selection/allowClear'); + +var SingleSelection = require('select2/selection/single'); +var MultipleSelection = require('select2/selection/multiple'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var AllowClearPlaceholder = Utils.Decorate( + Utils.Decorate(SingleSelection, Placeholder), + AllowClear +); + +var allowClearOptions = new Options({ + placeholder: { + id: 'placeholder', + text: 'This is the placeholder' + }, + allowClear: true +}); + +test('clear is not displayed for single placeholder', function (assert) { + var selection = new AllowClearPlaceholder( + $('#qunit-fixture .single-with-placeholder'), + allowClearOptions + ); + + var $selection = selection.render(); + + selection.update([{ + id: 'placeholder' + }]); + + assert.equal( + $selection.find('.select2-selection__clear').length, + 0, + 'The clear icon should not be displayed' + ); +}); + +test('clear is not displayed for multiple placeholder', function (assert) { + var selection = new AllowClearPlaceholder( + $('#qunit-fixture .multiple'), + allowClearOptions + ); + + var $selection = selection.render(); + + selection.update([]); + + assert.equal( + $selection.find('.select2-selection__clear').length, + 0, + 'The clear icon should not be displayed' + ); +}); + + +test('clear is displayed for placeholder', function (assert) { + var selection = new AllowClearPlaceholder( + $('#qunit-fixture .single-with-placeholder'), + allowClearOptions + ); + + var $selection = selection.render(); + + selection.update([{ + id: 'one', + test: 'one' + }]); + + assert.equal( + $selection.find('.select2-selection__clear').length, + 1, + 'The clear icon should be displayed' + ); +}); + +test('clear icon should have title displayed', function (assert) { + var selection = new AllowClearPlaceholder( + $('#qunit-fixture .single-with-placeholder'), + allowClearOptions + ); + + var $selection = selection.render(); + + selection.update([{ + id: 'one', + test: 'one' + }]); + + assert.equal( + $selection.find('.select2-selection__clear').attr('title'), + 'Remove all items', + 'The clear icon should have title displayed' + ); +}); + +test('clicking clear will set the placeholder value', function (assert) { + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); + + assert.equal( + $element.val(), + 'placeholder', + 'The value should have been reset to the placeholder' + ); +}); + +test('clicking clear will trigger the unselect event', function (assert) { + assert.expect(4); + + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('unselect', function (ev) { + assert.ok( + 'data' in ev && ev.data, + 'The event should have been triggered with the data property' + ); + + assert.ok( + $.isPlainObject(ev.data), + 'The data should be an object' + ); + + assert.equal( + ev.data.id, + 'One', + 'The data should be the unselected object' + ); + + assert.equal( + $element.val(), + 'placeholder', + 'The previous value should be unselected' + ); + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); +}); + +test('preventing the unselect event cancels the clearing', function (assert) { + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('unselect', function (ev) { + ev.prevented = true; + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); + + assert.equal( + $element.val(), + 'One', + 'The placeholder should not have been set' + ); +}); + +test('clicking clear will trigger the clear event', function (assert) { + assert.expect(5); + + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('clear', function (ev) { + assert.ok( + 'data' in ev && ev.data, + 'The event should have been triggered with the data property' + ); + + assert.ok( + $.isArray(ev.data), + 'The data should be an array' + ); + + assert.equal( + ev.data.length, + 1, + 'The data should contain one item for each value' + ); + + assert.equal( + ev.data[0].id, + 'One', + 'The data should contain unselected objects' + ); + + assert.equal( + $element.val(), + 'placeholder', + 'The previous value should be unselected' + ); + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); +}); + +test('preventing the clear event cancels the clearing', function (assert) { + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + $element.val('One'); + selection.update([{ + id: 'One', + text: 'One' + }]); + + selection.on('clear', function (ev) { + ev.prevented = true; + }); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); + + assert.equal( + $element.val(), + 'One', + 'The placeholder should not have been set' + ); +}); + +test('clear does not work when disabled', function (assert) { + var $element = $('#qunit-fixture .single-with-placeholder'); + + var selection = new AllowClearPlaceholder( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $selection = selection.render(); + + selection.bind(container, $('
')); + + selection.update([{ + id: 'One', + text: 'One' + }]); + + $element.val('One'); + selection.options.set('disabled', true); + + var $remove = $selection.find('.select2-selection__clear'); + $remove.trigger('mousedown'); + + assert.equal( + $element.val(), + 'One', + 'The placeholder should not have been set' + ); +}); + +test('clear button doesnt visually break selected options', function (assert) { + var $element = $(''); + + var Selection = Utils.Decorate( + Utils.Decorate(MultipleSelection, Placeholder), + AllowClear + ); + + var selection = new Selection( + $element, + allowClearOptions + ); + var container = new MockContainer(); + + var $container = $( + '' + ); + $('#qunit-fixture').append($container); + + var $selection = selection.render(); + $container.append($selection); + $container.css('width', '100px'); + + selection.bind(container, $container); + + selection.update([{ + id: '1', + text: '1' + }]); + + var singleHeight = $container.height(); + + selection.update([ + { + id: '10', + text: '10' + }, + { + id: '20', + text: '20' + } + ]); + + var doubleHeight = $container.height(); + + selection.update([ + { + id: '1', + text: '1' + }, + { + id: '2', + text: '2' + } + ]); + + assert.notEqual( + singleHeight, + doubleHeight, + 'The height of the two different rows should be different' + ); + + assert.equal( + $container.height(), + doubleHeight, + 'There should be two full lines of selections' + ); +}); diff --git a/static/vendor/select2/tests/selection/containerCss-tests.js b/static/vendor/select2/tests/selection/containerCss-tests.js new file mode 100644 index 00000000..522703a2 --- /dev/null +++ b/static/vendor/select2/tests/selection/containerCss-tests.js @@ -0,0 +1,104 @@ +module('Dropdown - containerCssClass compatibility'); + +var $ = require('jquery'); +var Utils = require('select2/utils'); +var Options = require('select2/options'); + +var SingleSelection = require('select2/selection/single'); +var ContainerCSS = Utils.Decorate( + SingleSelection, + require('select2/compat/containerCss') +); + +test('all classes will be copied if :all: is used', function (assert) { + var $element = $(''); + var options = new Options({ + containerCssClass: ':all:' + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok($container.hasClass('test')); + assert.ok($container.hasClass('copy')); + assert.ok($container.hasClass('works')); + assert.ok(!$container.hasClass(':all:')); +}); + +test(':all: can be used with other classes', function (assert) { + var $element = $(''); + var options = new Options({ + containerCssClass: ':all: other' + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok($container.hasClass('test')); + assert.ok($container.hasClass('copy')); + assert.ok($container.hasClass('works')); + assert.ok($container.hasClass('other')); + assert.ok(!$container.hasClass(':all:')); +}); + +test('classes can be passed in as a string', function (assert) { + var $element = $(''); + var options = new Options({ + containerCssClass: 'other' + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok($container.hasClass('other')); +}); + +test('a function can be used based on the element', function (assert){ + var $element = $(''); + var options = new Options({ + containerCssClass: function ($element) { + return 'function'; + } + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok($container.hasClass('function')); + assert.ok(!$container.hasClass('test')); +}); + +test(':all: works around custom adapters', function (assert) { + var $element = $(''); + var options = new Options({ + containerCssClass: ':all: something', + adaptContainerCssClass: function (clazz) { + return clazz + '-modified'; + } + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok($container.hasClass('something')); + + assert.ok($container.hasClass('test')); + assert.ok($container.hasClass('test-modified')); +}); + +module('Selection - adaptContainerCss compatibility'); + +test('only return when adapted', function (assert) { + var $element = $(''); + var options = new Options({ + adaptContainerCssClass: function (clazz) { + return 'modified'; + } + }); + + var select = new ContainerCSS($element, options); + var $container = select.render(); + + assert.ok(!$container.hasClass('original')); + assert.ok($container.hasClass('modified')); +}); diff --git a/static/vendor/select2/tests/selection/focusing-tests.js b/static/vendor/select2/tests/selection/focusing-tests.js new file mode 100644 index 00000000..fcb2c6e7 --- /dev/null +++ b/static/vendor/select2/tests/selection/focusing-tests.js @@ -0,0 +1,41 @@ +module('Selection containers - Managing focus'); + +var SingleSelection = require('select2/selection/single'); + +var $ = require('jquery'); +var Options = require('select2/options'); + +var options = new Options({}); + +test('close sets the focus to the selection', function (assert) { + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + selection.bind(container, $container); + + selection.update([{ + id: 'test', + text: 'test' + }]); + + $container.append($selection); + + assert.notEqual( + document.activeElement, + $selection[0], + 'The selection had focus originally' + ); + + container.trigger('close'); + + assert.equal( + document.activeElement, + $selection[0], + 'After close, focus must be set to selection' + ); +}); diff --git a/static/vendor/select2/tests/selection/multiple-tests.js b/static/vendor/select2/tests/selection/multiple-tests.js new file mode 100644 index 00000000..ddc7c9c9 --- /dev/null +++ b/static/vendor/select2/tests/selection/multiple-tests.js @@ -0,0 +1,258 @@ +module('Selection containers - Multiple'); + +var MultipleSelection = require('select2/selection/multiple'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var options = new Options({}); + +test('display uses templateSelection', function (assert) { + var called = false; + + var templateOptions = new Options({ + templateSelection: function (data) { + called = true; + + return data.text; + } + }); + + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + templateOptions + ); + + var out = selection.display({ + text: 'test' + }); + + assert.ok(called); + + assert.equal(out, 'test'); +}); + +test('templateSelection can addClass', function (assert) { + var called = false; + + var templateOptions = new Options({ + templateSelection: function (data, container) { + called = true; + container.addClass('testclass'); + return data.text; + } + }); + + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + templateOptions + ); + + var $container = selection.selectionContainer(); + + var out = selection.display({ + text: 'test' + }, $container); + + assert.ok(called); + + assert.equal(out, 'test'); + + assert.ok($container.hasClass('testclass')); +}); + +test('empty update clears the selection', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + $rendered.text('testing'); + + selection.update([]); + + assert.equal( + $rendered.text(), + '', + 'There should have been nothing rendered' + ); +}); + +test('empty update clears the selection title', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + + selection.update([]); + + var $rendered = $selection.find('.select2-selection__rendered li'); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if nothing is rendered' + ); +}); + +test('update sets the title to the data text', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + + selection.update([{ + text: 'test' + }]); + + var $rendered = $selection.find('.select2-selection__rendered li'); + + assert.equal( + $rendered.attr('title'), + 'test', + 'The title should have been set to the text' + ); +}); + +test('update sets the title to the data title', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + + selection.update([{ + text: 'test', + title: 'correct' + }]); + + var $rendered = $selection.find('.select2-selection__rendered li'); + + assert.equal( + $rendered.attr('title'), + 'correct', + 'The title should have taken precedence over the text' + ); +}); + +test('update should clear title for placeholder options', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + + selection.update([{ + id: '', + text: '' + }]); + + var $rendered = $selection.find('.select2-selection__rendered li'); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if a placeholder is rendered' + ); +}); + +test('update should clear title for options without text', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + + selection.update([{ + id: '' + }]); + + var $rendered = $selection.find('.select2-selection__rendered li'); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if there is no text or title property' + ); +}); + +test('escapeMarkup is being used', function (assert) { + var selection = new MultipleSelection( + $('#qunit-fixture .multiple'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + var unescapedText = ''; + + selection.update([{ + text: unescapedText + }]); + + assert.equal( + $rendered.text().substr(1), + unescapedText, + 'The text should be escaped by default to prevent injection' + ); +}); + +test('clear button respects the disabled state', function (assert) { + var options = new Options({ + disabled: true + }); + + var $select = $('#qunit-fixture .multiple'); + + var container = new MockContainer(); + var $container = $('
'); + + var selection = new MultipleSelection( + $select, + options + ); + + var $selection = selection.render(); + $container.append($selection); + + selection.bind(container, $container); + + // Select an option + selection.update([{ + text: 'Test' + }]); + + var $rendered = $selection.find('.select2-selection__rendered'); + + var $pill = $rendered.find('.select2-selection__choice'); + + assert.equal($pill.length, 1, 'There should only be one selection'); + + var $remove = $pill.find('.select2-selection__choice__remove'); + + assert.equal( + $remove.length, + 1, + 'The remove icon is displayed for the selection' + ); + + // Set up the unselect handler + selection.on('unselect', function (params) { + assert.ok(false, 'The unselect handler should not be triggered'); + }); + + // Trigger the handler for the remove icon + $remove.trigger('click'); +}); diff --git a/static/vendor/select2/tests/selection/placeholder-tests.js b/static/vendor/select2/tests/selection/placeholder-tests.js new file mode 100644 index 00000000..8a436ff3 --- /dev/null +++ b/static/vendor/select2/tests/selection/placeholder-tests.js @@ -0,0 +1,74 @@ +module('Selection containers - Placeholders'); + +var Placeholder = require('select2/selection/placeholder'); +var SingleSelection = require('select2/selection/single'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var SinglePlaceholder = Utils.Decorate(SingleSelection, Placeholder); + +var placeholderOptions = new Options({ + placeholder: { + id: 'placeholder', + text: 'This is the placeholder' + } +}); + +test('normalizing placeholder ignores objects', function (assert) { + var selection = new SinglePlaceholder( + $('#qunit-fixture .single'), + placeholderOptions + ); + + var original = { + id: 'test', + text: 'testing' + }; + + var normalized = selection.normalizePlaceholder(original); + + assert.equal(original, normalized); +}); + +test('normalizing placeholder gives object for string', function (assert) { + var selection = new SinglePlaceholder( + $('#qunit-fixture .single'), + placeholderOptions + ); + + var normalized = selection.normalizePlaceholder('placeholder'); + + assert.equal(normalized.id, ''); + assert.equal(normalized.text, 'placeholder'); +}); + + +test('text is shown for placeholder option on single', function (assert) { + var selection = new SinglePlaceholder( + $('#qunit-fixture .single'), + placeholderOptions + ); + + var $selection = selection.render(); + + selection.update([{ + id: 'placeholder' + }]); + + assert.equal($selection.text(), 'This is the placeholder'); +}); + +test('placeholder is shown when no options are selected', function (assert) { + var selection = new SinglePlaceholder( + $('#qunit-fixture .multiple'), + placeholderOptions + ); + + var $selection = selection.render(); + + selection.update([]); + + assert.equal($selection.text(), 'This is the placeholder'); +}); diff --git a/static/vendor/select2/tests/selection/search-a11y-tests.js b/static/vendor/select2/tests/selection/search-a11y-tests.js new file mode 100644 index 00000000..b2628df5 --- /dev/null +++ b/static/vendor/select2/tests/selection/search-a11y-tests.js @@ -0,0 +1,217 @@ +module('Selection containers - Inline search - Accessibility'); + +var MultipleSelection = require('select2/selection/multiple'); +var InlineSearch = require('select2/selection/search'); + +var $ = require('jquery'); + +var Utils = require('select2/utils'); +var Options = require('select2/options'); +var options = new Options({}); + +test('role attribute is set to searchbox', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + assert.equal( + $selection.find('input').attr('role'), + 'searchbox', + 'The search box is marked as a search box' + ); +}); + +test('aria-autocomplete attribute is present', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + assert.equal( + $selection.find('input').attr('aria-autocomplete'), + 'list', + 'The search box is marked as autocomplete' + ); +}); + +test('aria-activedescendant should not be set initiailly', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'The search box should not point to anything when it is first rendered' + ); +}); + +test('aria-activedescendant should be set after highlight', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + container.trigger('results:focus', { + data: { + _resultId: 'test' + } + }); + + var $search = $selection.find('input'); + + assert.equal( + $search.attr('aria-activedescendant'), + 'test', + 'The search is pointing to the focused result' + ); +}); + +test('activedescendant should remove if there is no ID', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + $search.attr('aria-activedescendant', 'test'); + + container.trigger('results:focus', { + data: {} + }); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'There is no result for the search to be pointing to' + ); +}); + +test('aria-activedescendant should be removed when closed', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + $search.attr('aria-activedescendant', 'something'); + + container.trigger('close'); + + assert.ok( + !$search.attr('aria-activedescendant'), + 'There is no active descendant when the dropdown is closed' + ); +}); + +test('aria-controls should not be set initiailly', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + + assert.ok( + !$search.attr('aria-controls'), + 'The search box should not point to the results when it is first rendered' + ); +}); + +test('aria-controls should be set when opened', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + + container.trigger('open'); + + assert.ok( + $search.attr('aria-controls'), + 'The search should point to the results when it is opened' + ); +}); + +test('aria-controls should be removed when closed', function (assert) { + var $select = $('#qunit-fixture .multiple'); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + var selection = new CustomSelection($select, options); + var $selection = selection.render(); + + var container = new MockContainer(); + selection.bind(container, $('')); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + $search.attr('aria-controls', 'something'); + + container.trigger('close'); + + assert.ok( + !$search.attr('aria-controls'), + 'There are no results for the search box to point to when it is closed' + ); +}); diff --git a/static/vendor/select2/tests/selection/search-placeholder-tests.js b/static/vendor/select2/tests/selection/search-placeholder-tests.js new file mode 100644 index 00000000..cea761ba --- /dev/null +++ b/static/vendor/select2/tests/selection/search-placeholder-tests.js @@ -0,0 +1,55 @@ +module('Selection containers - Inline search - Placeholder'); + +var MultipleSelection = require('select2/selection/multiple'); +var InlineSearch = require('select2/selection/search'); +var SelectionPlaceholder = require('select2/selection/placeholder'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var CustomSelection = Utils.Decorate( + Utils.Decorate(MultipleSelection, SelectionPlaceholder), + InlineSearch +); + +test('width does not extend the search box', function (assert) { + assert.expect(2); + + var $container = $( + '
' + + '
' + + '
' + ); + var container = new MockContainer(); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, new Options({ + placeholder: 'Test placeholder' + })); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + $('#qunit-fixture').append($container); + + // Update the selection so the search is rendered + selection.update([]); + + var $search = $selection.find('input'); + + assert.equal( + $search.outerWidth(), + 60, + 'The search should not be the entire width of the container' + ); + + assert.equal( + $container.children().outerWidth(), + 100, + 'The container should be the width assigned to the parent in CSS' + ); + }); diff --git a/static/vendor/select2/tests/selection/search-tests.js b/static/vendor/select2/tests/selection/search-tests.js new file mode 100644 index 00000000..7a86cfba --- /dev/null +++ b/static/vendor/select2/tests/selection/search-tests.js @@ -0,0 +1,277 @@ +module('Selection containers - Inline search'); + +var MultipleSelection = require('select2/selection/multiple'); +var InlineSearch = require('select2/selection/search'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var options = new Options({}); + +test('backspace will remove a choice', function (assert) { + assert.expect(3); + + var KEYS = require('select2/keys'); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // The unselect event should be triggered at some point + selection.on('unselect', function () { + assert.ok(true, 'A choice was unselected'); + }); + + // Add some selections and render the search + selection.update([ + { + id: '1', + text: 'One' + } + ]); + + var $search = $selection.find('input'); + var $choices = $selection.find('.select2-selection__choice'); + + assert.equal($search.length, 1, 'The search was visible'); + assert.equal($choices.length, 1, 'The choice was rendered'); + + // Trigger the backspace on the search + var backspace = $.Event('keydown', { + which: KEYS.BACKSPACE + }); + $search.trigger(backspace); +}); + +test('backspace will set the search text', function (assert) { + assert.expect(3); + + var KEYS = require('select2/keys'); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Add some selections and render the search + selection.update([ + { + id: '1', + text: 'One' + } + ]); + + var $search = $selection.find('input'); + var $choices = $selection.find('.select2-selection__choice'); + + assert.equal($search.length, 1, 'The search was visible'); + assert.equal($choices.length, 1, 'The choice was rendered'); + + // Trigger the backspace on the search + var backspace = $.Event('keydown', { + which: KEYS.BACKSPACE + }); + $search.trigger(backspace); + + assert.equal($search.val(), 'One', 'The search text was set'); +}); + +test('updating selection does not shift the focus', function (assert) { + // Check for IE 8, which triggers a false negative during testing + if (window.attachEvent && !window.addEventListener) { + // We must expect 0 assertions or the test will fail + assert.expect(0); + return; + } + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Update the selection so the search is rendered + selection.update([]); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + + var $search = $selection.find('input'); + $search.trigger('focus'); + + assert.equal($search.length, 1, 'The search was not visible'); + + assert.equal( + document.activeElement, + $search[0], + 'The search did not have focus originally' + ); + + // Trigger an update, this should redraw the search box + selection.update([]); + + assert.equal($search.length, 1, 'The search box disappeared'); + + assert.equal( + document.activeElement, + $search[0], + 'The search did not have focus after the selection was updated' + ); +}); + +test('the focus event shifts the focus', function (assert) { + // Check for IE 8, which triggers a false negative during testing + if (window.attachEvent && !window.addEventListener) { + // We must expect 0 assertions or the test will fail + assert.expect(0); + return; + } + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Update the selection so the search is rendered + selection.update([]); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + + // The search should not be automatically focused + + var $search = $selection.find('input'); + + assert.notEqual( + document.activeElement, + $search[0], + 'The search had focus originally' + ); + + assert.equal($search.length, 1, 'The search was not visible'); + + // Focus the container + + container.trigger('focus'); + + // Make sure it focuses the search + + assert.equal($search.length, 1, 'The search box disappeared'); + + assert.equal( + document.activeElement, + $search[0], + 'The search did not have focus originally' + ); +}); + +test('search box without text should propagate click', function (assert) { + assert.expect(1); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Update the selection so the search is rendered + selection.update([]); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + + $selection.on('click', function () { + assert.ok(true, 'The click event should not have been trapped'); + }); + + var $search = $selection.find('input'); + $search.trigger('click'); +}); + +test('search box with text should not propagate click', function (assert) { + assert.expect(0); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Update the selection so the search is rendered + selection.update([]); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + + $selection.on('click', function () { + assert.ok(false, 'The click event should have been trapped'); + }); + + var $search = $selection.find('input'); + $search.val('test'); + $search.trigger('click'); +}); + +test('search box with text should not close dropdown', function (assert) { + assert.expect(0); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); + + var $element = $('#qunit-fixture .multiple'); + var selection = new CustomSelection($element, options); + + var $selection = selection.render(); + selection.bind(container, $container); + + // Update the selection so the search is rendered + selection.update([]); + + // Make it visible so the browser can place focus on the search + $container.append($selection); + + container.on('close', function () { + assert.ok(false, 'The dropdown should not have closed'); + }); + + var $search = $selection.find('input'); + $search.val('test'); + $search.trigger('click'); +}); diff --git a/static/vendor/select2/tests/selection/single-tests.js b/static/vendor/select2/tests/selection/single-tests.js new file mode 100644 index 00000000..99b37e66 --- /dev/null +++ b/static/vendor/select2/tests/selection/single-tests.js @@ -0,0 +1,227 @@ +module('Selection containers - Single'); + +var SingleSelection = require('select2/selection/single'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var options = new Options({}); + +test('display uses templateSelection', function (assert) { + var called = false; + + var templateOptions = new Options({ + templateSelection: function (data) { + called = true; + + return data.text; + } + }); + + var selection = new SingleSelection( + $('#qunit-fixture .single'), + templateOptions + ); + + var out = selection.display({ + text: 'test' + }); + + assert.ok(called); + + assert.equal(out, 'test'); +}); + +test('templateSelection can addClass', function (assert) { + var called = false; + + var templateOptions = new Options({ + templateSelection: function (data, container) { + called = true; + container.addClass('testclass'); + return data.text; + } + }); + + var selection = new SingleSelection( + $('#qunit-fixture .single'), + templateOptions + ); + + var $container = selection.selectionContainer(); + + var out = selection.display({ + text: 'test' + }, $container); + + assert.ok(called); + + assert.equal(out, 'test'); + + assert.ok($container.hasClass('testclass')); +}); + +test('empty update clears the selection', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + $rendered.text('testing'); + + selection.update([]); + + assert.equal( + $rendered.text(), + '', + 'There should have been nothing rendered' + ); +}); + +test('empty update clears the selection title', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + $rendered.attr('title', 'testing'); + + selection.update([]); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if nothing is rendered' + ); +}); + +test('update renders the data text', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + selection.update([{ + text: 'test' + }]); + + assert.equal($rendered.text(), 'test'); +}); + +test('update sets the title to the data text', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + selection.update([{ + text: 'test' + }]); + + assert.equal( + $rendered.attr('title'), + 'test', + 'The title should have been set to the text' + ); +}); + +test('update sets the title to the data title', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + selection.update([{ + text: 'test', + title: 'correct' + }]); + + assert.equal( + $rendered.attr('title'), + 'correct', + 'The title should have taken precedence over the text' + ); +}); + +test('update should clear title for placeholder options', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + $rendered.attr('title', 'testing'); + + selection.update([{ + id: '', + text: '' + }]); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if a placeholder is rendered' + ); +}); + +test('update should clear title for options without text', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + $rendered.attr('title', 'testing'); + + selection.update([{ + id: '' + }]); + + assert.equal( + $rendered.attr('title'), + undefined, + 'The title should be removed if there is no text or title property' + ); +}); + +test('escapeMarkup is being used', function (assert) { + var selection = new SingleSelection( + $('#qunit-fixture .single'), + options + ); + + var $selection = selection.render(); + var $rendered = $selection.find('.select2-selection__rendered'); + + var unescapedText = ''; + + selection.update([{ + text: unescapedText + }]); + + assert.equal( + $rendered.text(), + unescapedText, + 'The text should be escaped by default to prevent injection' + ); +}); diff --git a/static/vendor/select2/tests/selection/stopPropagation-tests.js b/static/vendor/select2/tests/selection/stopPropagation-tests.js new file mode 100644 index 00000000..d8d8897b --- /dev/null +++ b/static/vendor/select2/tests/selection/stopPropagation-tests.js @@ -0,0 +1,33 @@ +module('Selection containers - Stoping event propagation'); + +var SingleSelection = require('select2/selection/single'); +var StopPropagation = require('select2/selection/stopPropagation'); + +var $ = require('jquery'); +var Options = require('select2/options'); +var Utils = require('select2/utils'); + +var CutomSelection = Utils.Decorate(SingleSelection, StopPropagation); + +var options = new Options(); + +test('click event does not propagate', function (assert) { + assert.expect(1); + + var $container = $('#qunit-fixture .event-container'); + var container = new MockContainer(); + + var selection = new CutomSelection($('#qunit-fixture select'), options); + + var $selection = selection.render(); + selection.bind(container, $container); + + $container.append($selection); + $container.on('click', function () { + assert.ok(false, 'The click event should have been stopped'); + }); + + $selection.trigger('click'); + + assert.ok(true, 'Something went wrong if this failed'); +}); diff --git a/static/vendor/select2/tests/unit-jq1.html b/static/vendor/select2/tests/unit-jq1.html new file mode 100644 index 00000000..b5ec3461 --- /dev/null +++ b/static/vendor/select2/tests/unit-jq1.html @@ -0,0 +1,105 @@ + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/vendor/select2/tests/unit-jq2.html b/static/vendor/select2/tests/unit-jq2.html new file mode 100644 index 00000000..7eca5057 --- /dev/null +++ b/static/vendor/select2/tests/unit-jq2.html @@ -0,0 +1,105 @@ + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/vendor/select2/tests/unit-jq3.html b/static/vendor/select2/tests/unit-jq3.html new file mode 100644 index 00000000..a34f771c --- /dev/null +++ b/static/vendor/select2/tests/unit-jq3.html @@ -0,0 +1,105 @@ + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/vendor/select2/tests/utils/data-tests.js b/static/vendor/select2/tests/utils/data-tests.js new file mode 100644 index 00000000..90f0f8b9 --- /dev/null +++ b/static/vendor/select2/tests/utils/data-tests.js @@ -0,0 +1,36 @@ +module('Utils - RemoveData'); + +var $ = require('jquery'); +var Utils = require('select2/utils'); + +test('The data-select2-id attribute is removed', function (assert) { + var $element = $(''); + + Utils.RemoveData($element[0]); + + assert.notEqual( + $element.attr('data-select2-id'), + 'test', + 'The internal attribute was not removed when the data was cleared' + ); +}); + +test('The internal cache for the element is cleared', function (assert) { + var $element = $(''); + + Utils.__cache.test = { + 'foo': 'bar' + }; + + Utils.RemoveData($element[0]); + + assert.equal(Utils.__cache.test, null, 'The cache should now be empty'); +}); + +test('Calling it on an element without data works', function (assert) { + assert.expect(0); + + var $element = $(''); + + Utils.RemoveData($element[0]); +}); \ No newline at end of file diff --git a/static/vendor/select2/tests/utils/decorator-tests.js b/static/vendor/select2/tests/utils/decorator-tests.js new file mode 100644 index 00000000..4888991f --- /dev/null +++ b/static/vendor/select2/tests/utils/decorator-tests.js @@ -0,0 +1,189 @@ +module('Decorators'); + +var Utils = require('select2/utils'); + +test('overridden - method', function (assert) { + function BaseClass () {} + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass () {} + + DecoratorClass.prototype.hello = function () { + return 'B'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.strictEqual(inst.hello(), 'B'); +}); + +test('overridden - constructor', function (assert) { + function BaseClass () { + this.inherited = true; + } + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass (decorated) { + this.called = true; + } + + DecoratorClass.prototype.other = function () { + return 'B'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.ok(inst.called); + assert.ok(!inst.inherited); +}); + +test('not overridden - method', function (assert) { + function BaseClass () {} + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass () {} + + DecoratorClass.prototype.other = function () { + return 'B'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.strictEqual(inst.hello(), 'A'); +}); + +test('not overridden - constructor', function (assert) { + function BaseClass () { + this.called = true; + } + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass () {} + + DecoratorClass.prototype.other = function () { + return 'B'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.ok(inst.called); +}); + +test('inherited - method', function (assert) { + function BaseClass () {} + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass (decorated) {} + + DecoratorClass.prototype.hello = function (decorated) { + return 'B' + decorated.call(this) + 'C'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.strictEqual(inst.hello(), 'BAC'); +}); + +test('inherited - constructor', function (assert) { + function BaseClass () { + this.inherited = true; + } + + BaseClass.prototype.hello = function () { + return 'A'; + }; + + function DecoratorClass (decorated) { + this.called = true; + + decorated.call(this); + } + + DecoratorClass.prototype.other = function () { + return 'B'; + }; + + var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); + + var inst = new DecoratedClass(); + + assert.ok(inst.called); + assert.ok(inst.inherited); +}); + +test('inherited - three levels', function (assert) { + function BaseClass (testArgument) { + this.baseCalled = true; + this.baseTestArgument = testArgument; + } + + BaseClass.prototype.test = function (a) { + return a + 'c'; + }; + + function MiddleClass (decorated, testArgument) { + this.middleCalled = true; + this.middleTestArgument = testArgument; + + decorated.call(this, testArgument); + } + + MiddleClass.prototype.test = function (decorated, a) { + return decorated.call(this, a + 'b'); + }; + + function DecoratorClass (decorated, testArgument) { + this.decoratorCalled = true; + this.decoratorTestArgument = testArgument; + + decorated.call(this, testArgument); + } + + DecoratorClass.prototype.test = function (decorated, a) { + return decorated.call(this, a + 'a'); + }; + + var DecoratedClass = Utils.Decorate( + Utils.Decorate(BaseClass, MiddleClass), + DecoratorClass + ); + + var inst = new DecoratedClass('test'); + + assert.ok(inst.baseCalled, 'The base class contructor was called'); + assert.ok(inst.middleCalled, 'The middle class constructor was called'); + assert.ok(inst.decoratorCalled, 'The decorator constructor was called'); + + assert.strictEqual(inst.baseTestArgument, 'test'); + assert.strictEqual(inst.middleTestArgument, 'test'); + assert.strictEqual(inst.decoratorTestArgument, 'test'); + + var out = inst.test('test'); + + assert.strictEqual(out, 'testabc'); +}); diff --git a/static/vendor/select2/tests/utils/escapeMarkup-tests.js b/static/vendor/select2/tests/utils/escapeMarkup-tests.js new file mode 100644 index 00000000..726f09de --- /dev/null +++ b/static/vendor/select2/tests/utils/escapeMarkup-tests.js @@ -0,0 +1,36 @@ +module('Utils - escapeMarkup'); + +var Utils = require('select2/utils'); + +test('text passes through', function (assert) { + var text = 'testing this'; + var escaped = Utils.escapeMarkup(text); + + assert.equal(text, escaped); +}); + +test('html tags are escaped', function (assert) { + var text = ''; + var escaped = Utils.escapeMarkup(text); + + assert.notEqual(text, escaped); + assert.equal(escaped.indexOf('