Commit 4bbe4f9b authored by platyhouse's avatar platyhouse

- encrypted

parent e8ec6a4e
define( [
"../core",
"../core/camelCase",
"../var/rnothtmlwhite",
"./var/acceptData"
], function( jQuery, camelCase, rnothtmlwhite, acceptData ) {
"use strict";
function Data() {
this.expando = jQuery.expando + Data.uid++;
}
Data.uid = 1;
Data.prototype = {
cache: function( owner ) {
// Check if the owner object already has a cache
var value = owner[ this.expando ];
// If not, create one
if ( !value ) {
value = {};
// We can accept data for non-element nodes in modern browsers,
// but we should not, see #8335.
// Always return an empty object.
if ( acceptData( owner ) ) {
// If it is a node unlikely to be stringify-ed or looped over
// use plain assignment
if ( owner.nodeType ) {
owner[ this.expando ] = value;
// Otherwise secure it in a non-enumerable property
// configurable must be true to allow the property to be
// deleted when data is removed
} else {
Object.defineProperty( owner, this.expando, {
value: value,
configurable: true
} );
}
}
}
return value;
},
set: function( owner, data, value ) {
var prop,
cache = this.cache( owner );
// Handle: [ owner, key, value ] args
// Always use camelCase key (gh-2257)
if ( typeof data === "string" ) {
cache[ camelCase( data ) ] = value;
// Handle: [ owner, { properties } ] args
} else {
// Copy the properties one-by-one to the cache object
for ( prop in data ) {
cache[ camelCase( prop ) ] = data[ prop ];
}
}
return cache;
},
get: function( owner, key ) {
return key === undefined ?
this.cache( owner ) :
// Always use camelCase key (gh-2257)
owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
},
access: function( owner, key, value ) {
// In cases where either:
//
// 1. No key was specified
// 2. A string key was specified, but no value provided
//
// Take the "read" path and allow the get method to determine
// which value to return, respectively either:
//
// 1. The entire cache object
// 2. The data stored at the key
//
if ( key === undefined ||
( ( key && typeof key === "string" ) && value === undefined ) ) {
return this.get( owner, key );
}
// When the key is not a string, or both a key and value
// are specified, set or extend (existing objects) with either:
//
// 1. An object of properties
// 2. A key and value
//
this.set( owner, key, value );
// Since the "set" path can have two possible entry points
// return the expected data based on which path was taken[*]
return value !== undefined ? value : key;
},
remove: function( owner, key ) {
var i,
cache = owner[ this.expando ];
if ( cache === undefined ) {
return;
}
if ( key !== undefined ) {
// Support array or space separated string of keys
if ( Array.isArray( key ) ) {
// If key is an array of keys...
// We always set camelCase keys, so remove that.
key = key.map( camelCase );
} else {
key = camelCase( key );
// If a key with the spaces exists, use it.
// Otherwise, create an array by matching non-whitespace
key = key in cache ?
[ key ] :
( key.match( rnothtmlwhite ) || [] );
}
i = key.length;
while ( i-- ) {
delete cache[ key[ i ] ];
}
}
// Remove the expando if there's no more data
if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
// Support: Chrome <=35 - 45
// Webkit & Blink performance suffers when deleting properties
// from DOM nodes, so set to undefined instead
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
if ( owner.nodeType ) {
owner[ this.expando ] = undefined;
} else {
delete owner[ this.expando ];
}
}
},
hasData: function( owner ) {
var cache = owner[ this.expando ];
return cache !== undefined && !jQuery.isEmptyObject( cache );
}
};
return Data;
} );
define( function() {
"use strict";
/**
* Determines whether an object can have data
*/
return function( owner ) {
// Accepts only:
// - Node
// - Node.ELEMENT_NODE
// - Node.DOCUMENT_NODE
// - Object
// - Any
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};
} );
define( [
"../Data"
], function( Data ) {
"use strict";
return new Data();
} );
define( [
"../Data"
], function( Data ) {
"use strict";
return new Data();
} );
define([
'./array',
'../utils',
'jquery'
], function (ArrayAdapter, Utils, $) {
function AjaxAdapter ($element, options) {
this.ajaxOptions = this._applyDefaults(options.get('ajax'));
if (this.ajaxOptions.processResults != null) {
this.processResults = this.ajaxOptions.processResults;
}
AjaxAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(AjaxAdapter, ArrayAdapter);
AjaxAdapter.prototype._applyDefaults = function (options) {
var defaults = {
data: function (params) {
return $.extend({}, params, {
q: params.term
});
},
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(failure);
return $request;
}
};
return $.extend({}, defaults, options, true);
};
AjaxAdapter.prototype.processResults = function (results) {
return results;
};
AjaxAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;
if (this._request != null) {
// JSONP requests cannot always be aborted
if ($.isFunction(this._request.abort)) {
this._request.abort();
}
this._request = null;
}
var options = $.extend({
type: 'GET'
}, this.ajaxOptions);
if (typeof options.url === 'function') {
options.url = options.url.call(this.$element, params);
}
if (typeof options.data === 'function') {
options.data = options.data.call(this.$element, params);
}
function request () {
var $request = options.transport(options, function (data) {
var results = self.processResults(data, params);
if (self.options.get('debug') && window.console && console.error) {
// Check to make sure that the response included a `results` key.
if (!results || !results.results || !$.isArray(results.results)) {
console.error(
'Select2: The AJAX results did not return an array in the ' +
'`results` key of the response.'
);
}
}
callback(results);
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
if ($request.status && $request.status === '0') {
return;
}
self.trigger('results:message', {
message: 'errorLoading'
});
});
self._request = $request;
}
if (this.ajaxOptions.delay && params.term != null) {
if (this._queryTimeout) {
window.clearTimeout(this._queryTimeout);
}
this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
} else {
request();
}
};
return AjaxAdapter;
});
define([
'./select',
'../utils',
'jquery'
], function (SelectAdapter, Utils, $) {
function ArrayAdapter ($element, options) {
var data = options.get('data') || [];
ArrayAdapter.__super__.constructor.call(this, $element, options);
this.addOptions(this.convertToOptions(data));
}
Utils.Extend(ArrayAdapter, SelectAdapter);
ArrayAdapter.prototype.select = function (data) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
});
if ($option.length === 0) {
$option = this.option(data);
this.addOptions($option);
}
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.convertToOptions = function (data) {
var self = this;
var $existing = this.$element.find('option');
var existingIds = $existing.map(function () {
return self.item($(this)).id;
}).get();
var $options = [];
// Filter out all items except for the one passed in the argument
function onlyItem (item) {
return function () {
return $(this).val() == item.id;
};
}
for (var d = 0; d < data.length; d++) {
var item = this._normalizeItem(data[d]);
// Skip items which were pre-loaded, only merge the data
if ($.inArray(item.id, existingIds) >= 0) {
var $existingOption = $existing.filter(onlyItem(item));
var existingData = this.item($existingOption);
var newData = $.extend(true, {}, item, existingData);
var $newOption = this.option(newData);
$existingOption.replaceWith($newOption);
continue;
}
var $option = this.option(item);
if (item.children) {
var $children = this.convertToOptions(item.children);
Utils.appendMany($option, $children);
}
$options.push($option);
}
return $options;
};
return ArrayAdapter;
});
define([
'../utils'
], function (Utils) {
function BaseAdapter ($element, options) {
BaseAdapter.__super__.constructor.call(this);
}
Utils.Extend(BaseAdapter, Utils.Observable);
BaseAdapter.prototype.current = function (callback) {
throw new Error('The `current` method must be defined in child classes.');
};
BaseAdapter.prototype.query = function (params, callback) {
throw new Error('The `query` method must be defined in child classes.');
};
BaseAdapter.prototype.bind = function (container, $container) {
// Can be implemented in subclasses
};
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-';
id += Utils.generateChars(4);
if (data.id != null) {
id += '-' + data.id.toString();
} else {
id += '-' + Utils.generateChars(4);
}
return id;
};
return BaseAdapter;
});
define([
], function () {
function MaximumInputLength (decorated, $e, options) {
this.maximumInputLength = options.get('maximumInputLength');
decorated.call(this, $e, options);
}
MaximumInputLength.prototype.query = function (decorated, params, callback) {
params.term = params.term || '';
if (this.maximumInputLength > 0 &&
params.term.length > this.maximumInputLength) {
this.trigger('results:message', {
message: 'inputTooLong',
args: {
maximum: this.maximumInputLength,
input: params.term,
params: params
}
});
return;
}
decorated.call(this, params, callback);
};
return MaximumInputLength;
});
define([
], function (){
function MaximumSelectionLength (decorated, $e, options) {
this.maximumSelectionLength = options.get('maximumSelectionLength');
decorated.call(this, $e, options);
}
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
count >= self.maximumSelectionLength) {
self.trigger('results:message', {
message: 'maximumSelected',
args: {
maximum: self.maximumSelectionLength
}
});
return;
}
decorated.call(self, params, callback);
});
};
return MaximumSelectionLength;
});
define([
], function () {
function MinimumInputLength (decorated, $e, options) {
this.minimumInputLength = options.get('minimumInputLength');
decorated.call(this, $e, options);
}
MinimumInputLength.prototype.query = function (decorated, params, callback) {
params.term = params.term || '';
if (params.term.length < this.minimumInputLength) {
this.trigger('results:message', {
message: 'inputTooShort',
args: {
minimum: this.minimumInputLength,
input: params.term,
params: params
}
});
return;
}
decorated.call(this, params, callback);
};
return MinimumInputLength;
});
define([
'./base',
'../utils',
'jquery'
], function (BaseAdapter, Utils, $) {
function SelectAdapter ($element, options) {
this.$element = $element;
this.options = options;
SelectAdapter.__super__.constructor.call(this);
}
Utils.Extend(SelectAdapter, BaseAdapter);
SelectAdapter.prototype.current = function (callback) {
var data = [];
var self = this;
this.$element.find(':selected').each(function () {
var $option = $(this);
var option = self.item($option);
data.push(option);
});
callback(data);
};
SelectAdapter.prototype.select = function (data) {
var self = this;
data.selected = true;
// If data.element is a DOM node, use it instead
if ($(data.element).is('option')) {
data.element.selected = true;
this.$element.trigger('change');
return;
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
data = [data];
data.push.apply(data, currentData);
for (var d = 0; d < data.length; d++) {
var id = data[d].id;
if ($.inArray(id, val) === -1) {
val.push(id);
}
}
self.$element.val(val);
self.$element.trigger('change');
});
} else {
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
SelectAdapter.prototype.unselect = function (data) {
var self = this;
if (!this.$element.prop('multiple')) {
return;
}
data.selected = false;
if ($(data.element).is('option')) {
data.element.selected = false;
this.$element.trigger('change');
return;
}
this.current(function (currentData) {
var val = [];
for (var d = 0; d < currentData.length; d++) {
var id = currentData[d].id;
if (id !== data.id && $.inArray(id, val) === -1) {
val.push(id);
}
}
self.$element.val(val);
self.$element.trigger('change');
});
};
SelectAdapter.prototype.bind = function (container, $container) {
var self = this;
this.container = container;
container.on('select', function (params) {
self.select(params.data);
});
container.on('unselect', function (params) {
self.unselect(params.data);
});
};
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) {
var data = [];
var self = this;
var $options = this.$element.children();
$options.each(function () {
var $option = $(this);
if (!$option.is('option') && !$option.is('optgroup')) {
return;
}
var option = self.item($option);
var matches = self.matches(params, option);
if (matches !== null) {
data.push(matches);
}
});
callback({
results: data
});
};
SelectAdapter.prototype.addOptions = function ($options) {
Utils.appendMany(this.$element, $options);
};
SelectAdapter.prototype.option = function (data) {
var option;
if (data.children) {
option = document.createElement('optgroup');
option.label = data.text;
} else {
option = document.createElement('option');
if (option.textContent !== undefined) {
option.textContent = data.text;
} else {
option.innerText = data.text;
}
}
if (data.id !== undefined) {
option.value = data.id;
}
if (data.disabled) {
option.disabled = true;
}
if (data.selected) {
option.selected = true;
}
if (data.title) {
option.title = data.title;
}
var $option = $(option);
var normalizedData = this._normalizeItem(data);
normalizedData.element = option;
// Override the option's data with the combined data
$.data(option, 'data', normalizedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = {};
data = $.data($option[0], 'data');
if (data != null) {
return data;
}
if ($option.is('option')) {
data = {
id: $option.val(),
text: $option.text(),
disabled: $option.prop('disabled'),
selected: $option.prop('selected'),
title: $option.prop('title')
};
} else if ($option.is('optgroup')) {
data = {
text: $option.prop('label'),
children: [],
title: $option.prop('title')
};
var $children = $option.children('option');
var children = [];
for (var c = 0; c < $children.length; c++) {
var $child = $($children[c]);
var child = this.item($child);
children.push(child);
}
data.children = children;
}
data = this._normalizeItem(data);
data.element = $option[0];
$.data($option[0], 'data', data);
return data;
};
SelectAdapter.prototype._normalizeItem = function (item) {
if (!$.isPlainObject(item)) {
item = {
id: item,
text: item
};
}
item = $.extend({}, {
text: ''
}, item);
var defaults = {
selected: false,
disabled: false
};
if (item.id != null) {
item.id = item.id.toString();
}
if (item.text != null) {
item.text = item.text.toString();
}
if (item._resultId == null && item.id && this.container != null) {
item._resultId = this.generateResultId(this.container, item);
}
return $.extend({}, defaults, item);
};
SelectAdapter.prototype.matches = function (params, data) {
var matcher = this.options.get('matcher');
return matcher(params, data);
};
return SelectAdapter;
});
define([
'jquery'
], function ($) {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
var createTag = options.get('createTag');
if (createTag !== undefined) {
this.createTag = createTag;
}
var insertTag = options.get('insertTag');
if (insertTag !== undefined) {
this.insertTag = insertTag;
}
decorated.call(this, $element, options);
if ($.isArray(tags)) {
for (var t = 0; t < tags.length; t++) {
var tag = tags[t];
var item = this._normalizeItem(tag);
var $option = this.option(item);
this.$element.append($option);
}
}
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
this._removeOldTags();
if (params.term == null || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (obj, child) {
var data = obj.results;
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null &&
!wrapper({
results: option.children
}, true)
);
var optionText = (option.text || '').toUpperCase();
var paramsTerm = (params.term || '').toUpperCase();
var checkText = optionText === paramsTerm;
if (checkText || checkChildren) {
if (child) {
return false;
}
obj.data = data;
callback(obj);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
if (tag != null) {
var $option = self.option(tag);
$option.attr('data-select2-tag', true);
self.addOptions([$option]);
self.insertTag(data, tag);
}
obj.results = data;
callback(obj);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
var term = $.trim(params.term);
if (term === '') {
return null;
}
return {
id: term,
text: term
};
};
Tags.prototype.insertTag = function (_, data, tag) {
data.unshift(tag);
};
Tags.prototype._removeOldTags = function (_) {
var tag = this._lastTag;
var $options = this.$element.find('option[data-select2-tag]');
$options.each(function () {
if (this.selected) {
return;
}
$(this).remove();
});
};
return Tags;
});
define([
'jquery'
], function ($) {
function Tokenizer (decorated, $element, options) {
var tokenizer = options.get('tokenizer');
if (tokenizer !== undefined) {
this.tokenizer = tokenizer;
}
decorated.call(this, $element, options);
}
Tokenizer.prototype.bind = function (decorated, container, $container) {
decorated.call(this, container, $container);
this.$search = container.dropdown.$search || container.selection.$search ||
$container.find('.select2-search__field');
};
Tokenizer.prototype.query = function (decorated, params, callback) {
var self = this;
function createAndSelect (data) {
// Normalize the data object so we can use it for checks
var item = self._normalizeItem(data);
// Check if the data object already exists as a tag
// Select it if it doesn't
var $existingOptions = self.$element.find('option').filter(function () {
return $(this).val() === item.id;
});
// If an existing option wasn't found for it, create the option
if (!$existingOptions.length) {
var $option = self.option(item);
$option.attr('data-select2-tag', true);
self._removeOldTags();
self.addOptions([$option]);
}
// Select the item, now that we know there is an option for it
select(item);
}
function select (data) {
self.trigger('select', {
data: data
});
}
params.term = params.term || '';
var tokenData = this.tokenizer(params, this.options, createAndSelect);
if (tokenData.term !== params.term) {
// Replace the search term if we have the search box
if (this.$search.length) {
this.$search.val(tokenData.term);
this.$search.focus();
}
params.term = tokenData.term;
}
decorated.call(this, params, callback);
};
Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
var separators = options.get('tokenSeparators') || [];
var term = params.term;
var i = 0;
var createTag = this.createTag || function (params) {
return {
id: params.term,
text: params.term
};
};
while (i < term.length) {
var termChar = term[i];
if ($.inArray(termChar, separators) === -1) {
i++;
continue;
}
var part = term.substr(0, i);
var partParams = $.extend({}, params, {
term: part
});
var data = createTag(partParams);
if (data == null) {
i++;
continue;
}
callback(data);
// Reset the term to not include the tokenized portion
term = term.substr(i + 1) || '';
i = 0;
}
return {
term: term
};
};
return Tokenizer;
});
module('Data adapters - Array');
var ArrayData = require('select2/data/array');
var $ = require('jquery');
var Options = require('select2/options');
var arrayOptions = new Options({
data: [
{
id: 'default',
text: 'Default'
},
{
id: '1',
text: 'One'
},
{
id: '2',
text: '2'
}
]
});
var extraOptions = new Options ({
data: [
{
id: 'default',
text: 'Default',
extra: true
},
{
id: 'One',
text: 'One',
extra: true
}
]
});
var nestedOptions = new Options({
data: [
{
text: 'Default',
children: [
{
text: 'Next',
children: [
{
id: 'a',
text: 'Option'
}
]
}
]
}
]
});
test('current gets default for single', function (assert) {
var $select = $('#qunit-fixture .single-empty');
var data = new ArrayData($select, arrayOptions);
data.current(function (val) {
assert.equal(
val.length,
1,
'There should always be a selected item for array data.'
);
var item = val[0];
assert.equal(
item.id,
'default',
'The first item should be selected'
);
});
});
test('current gets default for multiple', function (assert) {
var $select = $('#qunit-fixture .multiple');
var data = new ArrayData($select, arrayOptions);
data.current(function (val) {
assert.equal(
val.length,
0,
'There should be no default selection.'
);
});
});
test('current works with existing selections', function (assert) {
var $select = $('#qunit-fixture .multiple');
var data = new ArrayData($select, arrayOptions);
$select.val(['One']);
data.current(function (val) {
assert.equal(
val.length,
1,
'There should only be one existing selection.'
);
var option = val[0];
assert.equal(
option.id,
'One',
'The id should be equal to the value of the option tag.'
);
assert.equal(
option.text,
'One',
'The text should be equal to the text of the option tag.'
);
});
});
test('current works with selected data', function (assert) {
var $select = $('#qunit-fixture .single-empty');
var data = new ArrayData($select, arrayOptions);
data.select({
id: '2',
text: '2'
});
data.current(function (val) {
assert.equal(
val.length,
1,
'There should only be one option selected.'
);
var option = val[0];
assert.equal(
option.id,
'2',
'The id should match the original id from the array.'
);
assert.equal(
option.text,
'2',
'The text should match the original text from the array.'
);
});
});
test('select works for single', function (assert) {
var $select = $('#qunit-fixture .single-empty');
var data = new ArrayData($select, arrayOptions);
assert.equal(
$select.val(),
'default',
'There should already be a selection'
);
data.select({
id: '1',
text: 'One'
});
assert.equal(
$select.val(),
'1',
'The selected value should be the same as the selected id'
);
});
test('multiple sets the value', function (assert) {
var $select = $('#qunit-fixture .multiple');
var data = new ArrayData($select, arrayOptions);
assert.equal($select.val(), null);
data.select({
id: 'default',
text: 'Default'
});
assert.deepEqual($select.val(), ['default']);
});
test('multiple adds to the old value', function (assert) {
var $select = $('#qunit-fixture .multiple');
var data = new ArrayData($select, arrayOptions);
$select.val(['One']);
assert.deepEqual($select.val(), ['One']);
data.select({
id: 'default',
text: 'Default'
});
assert.deepEqual($select.val(), ['One', 'default']);
});
test('option tags are automatically generated', function (assert) {
var $select = $('#qunit-fixture .single-empty');
var data = new ArrayData($select, arrayOptions);
assert.equal(
$select.find('option').length,
3,
'An <option> element should be created for each object'
);
});
test('option tags can receive new data', function(assert) {
var $select = $('#qunit-fixture .single');
var data = new ArrayData($select, extraOptions);
assert.equal(
$select.find('option').length,
2,
'Only one more <option> element should be created'
);
data.select({
id: 'default'
});
assert.ok(
$select.find(':selected').data('data').extra,
'<option> default should have new data'
);
data.select({
id: 'One'
});
assert.ok(
$select.find(':selected').data('data').extra,
'<option> One should have new data'
);
});
test('optgroup tags can also be generated', function (assert) {
var $select = $('#qunit-fixture .single-empty');
var data = new ArrayData($select, nestedOptions);
assert.equal(
$select.find('option').length,
1,
'An <option> element should be created for the one selectable object'
);
assert.equal(
$select.find('optgroup').length,
2,
'An <optgroup> 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 $group = $select.children('optgroup');
assert.equal(
$group.prop('label'),
'Default',
'An `<optgroup>` label should match the text property'
);
assert.equal(
$group.children().length,
1,
'The <optgroup> should have one child under it'
);
});
test('existing selections are respected on initialization', function (assert) {
var $select = $(
'<select>' +
'<option>First</option>' +
'<option selected>Second</option>' +
'</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);
assert.equal($select.val(), 'Second');
});
\ No newline at end of file
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'
);
});
module('Data adapters - <input> 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 = $('<input />');
var adapter = new InputAdapter($element, options);
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 = $('<input />');
var adapter = new InputAdapter($element, options);
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 = $('<input />');
$element.val('test,test2,test3');
var adapter = new InputAdapter($element, options);
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 = $('<input value="test" />');
var adapter = new InputAdapter($element, options);
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 = $('<input />');
var adapter = new InputAdapter($element, options);
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'
);
});
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);
});
module('Data adapters - Maximum selection length');
var MaximumSelectionLength = require('select2/data/maximumSelectionLength');
var $ = require('jquery');
var Options = require('select2/options');
var Utils = require('select2/utils');
function MaximumSelectionStub () {
this.called = false;
this.currentData = [];
}
MaximumSelectionStub.prototype.current = function (callback) {
callback(this.currentData);
};
MaximumSelectionStub.prototype.val = function (val) {
this.currentData.push(val);
};
MaximumSelectionStub.prototype.query = function (params, callback) {
this.called = true;
};
var MaximumSelectionData = Utils.Decorate(
MaximumSelectionStub,
MaximumSelectionLength
);
test('0 never displays the notice', function (assert) {
var zeroOptions = new Options({
maximumSelectionLength: 0
});
var data = new MaximumSelectionData(null, zeroOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, zeroOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.val('1');
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, zeroOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.val('1');
data.val('2');
data.query({
term: ''
});
assert.ok(data.called);
});
test('< 0 never displays the notice', function (assert) {
var negativeOptions = new Options({
maximumSelectionLength: -1
});
var data = new MaximumSelectionData(null, negativeOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, negativeOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.val('1');
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, negativeOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.val('1');
data.val('2');
data.query({
term: ''
});
assert.ok(data.called);
});
test('triggers when >= 1 selection' , function (assert) {
var maxOfOneOptions = new Options({
maximumSelectionLength: 1
});
var data = new MaximumSelectionData(null, maxOfOneOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, maxOfOneOptions);
data.trigger = function () {
assert.ok(true, 'The event should be triggered.');
};
data.val('1');
data.query({
term: ''
});
assert.ok(!data.called);
});
test('triggers when >= 2 selections' , function (assert) {
var maxOfTwoOptions = new Options({
maximumSelectionLength: 2
});
var data = new MaximumSelectionData(null, maxOfTwoOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, maxOfTwoOptions);
data.trigger = function () {
assert.ok(false, 'No events should be triggered');
};
data.val('1');
data.query({
term: ''
});
assert.ok(data.called);
data = new MaximumSelectionData(null, maxOfTwoOptions);
data.trigger = function () {
assert.ok(true, 'The event should be triggered.');
};
data.val('1');
data.val('2');
data.query({
term: ''
});
assert.ok(!data.called);
});
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);
});
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
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 = $('<div></div>');
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 = $('<div></div>');
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 = $('<div></div>');
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 = $('<div></div>');
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment