Skip to content

Commit f3f1b31

Browse files
committed
Add back *css* options through an adapter
The old functionality where classes were directly copied to the container can be done by setting `dropdownCssClass: ':all:'` when initializing Select2. This closes select2#2879.
1 parent 4fc874a commit f3f1b31

12 files changed

+633
-29
lines changed

Gruntfile.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ module.exports = function (grunt) {
1010
fullIncludes = [
1111
'jquery',
1212

13-
'select2/compat/matcher',
13+
'select2/compat/containerCss',
14+
'select2/compat/dropdownCss',
15+
1416
'select2/compat/initSelection',
1517
'select2/compat/inputData',
18+
'select2/compat/matcher',
1619
'select2/compat/query',
1720

1821
'select2/dropdown/attachContainer',

dist/js/select2.full.js

+209-25
Original file line numberDiff line numberDiff line change
@@ -4428,6 +4428,19 @@ S2.define('select2/defaults',[
44284428
);
44294429
}
44304430

4431+
if (
4432+
options.dropdownCssClass != null ||
4433+
options.dropdownCss != null ||
4434+
options.adaptDropdownCssClass != null
4435+
) {
4436+
var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4437+
4438+
options.dropdownAdapter = Utils.Decorate(
4439+
options.dropdownAdapter,
4440+
DropdownCSS
4441+
);
4442+
}
4443+
44314444
options.dropdownAdapter = Utils.Decorate(
44324445
options.dropdownAdapter,
44334446
AttachBody
@@ -4463,6 +4476,19 @@ S2.define('select2/defaults',[
44634476
);
44644477
}
44654478

4479+
if (
4480+
options.containerCssClass != null ||
4481+
options.containerCss != null ||
4482+
options.adaptContainerCssClass != null
4483+
) {
4484+
var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4485+
4486+
options.selectionAdapter = Utils.Decorate(
4487+
options.selectionAdapter,
4488+
ContainerCSS
4489+
);
4490+
}
4491+
44664492
options.selectionAdapter = Utils.Decorate(
44674493
options.selectionAdapter,
44684494
EventRelay
@@ -5283,47 +5309,162 @@ S2.define('select2/core',[
52835309
return Select2;
52845310
});
52855311

5286-
S2.define('select2/compat/matcher',[
5312+
S2.define('select2/compat/utils',[
52875313
'jquery'
52885314
], function ($) {
5289-
function oldMatcher (matcher) {
5290-
function wrappedMatcher (params, data) {
5291-
var match = $.extend(true, {}, data);
5315+
function syncCssClasses ($dest, $src, adapter) {
5316+
var classes, replacements = [], adapted;
52925317

5293-
if (params.term == null || $.trim(params.term) === '') {
5294-
return match;
5295-
}
5318+
classes = $.trim($dest.attr('class'));
52965319

5297-
if (data.children) {
5298-
for (var c = data.children.length - 1; c >= 0; c--) {
5299-
var child = data.children[c];
5320+
if (classes) {
5321+
classes = '' + classes; // for IE which returns object
53005322

5301-
// Check if the child object matches
5302-
// The old matcher returned a boolean true or false
5303-
var doesMatch = matcher(params.term, child.text, child);
5323+
$(classes.split(/\s+/)).each(function () {
5324+
// Save all Select2 classes
5325+
if (this.indexOf('select2-') === 0) {
5326+
replacements.push(this);
5327+
}
5328+
});
5329+
}
53045330

5305-
// If the child didn't match, pop it off
5306-
if (!doesMatch) {
5307-
match.children.splice(c, 1);
5331+
classes = $.trim($src.attr('class'));
5332+
5333+
if (classes) {
5334+
classes = '' + classes; // for IE which returns object
5335+
5336+
$(classes.split(/\s+/)).each(function () {
5337+
// Only adapt non-Select2 classes
5338+
if (this.indexOf('select2-') !== 0) {
5339+
adapted = adapter(this);
5340+
5341+
if (adapted != null) {
5342+
replacements.push(adapted);
53085343
}
53095344
}
5345+
});
5346+
}
53105347

5311-
if (match.children.length > 0) {
5312-
return match;
5348+
$dest.attr('class', replacements.join(' '));
5349+
}
5350+
5351+
return {
5352+
syncCssClasses: syncCssClasses
5353+
};
5354+
});
5355+
5356+
S2.define('select2/compat/containerCss',[
5357+
'jquery',
5358+
'./utils'
5359+
], function ($, CompatUtils) {
5360+
// No-op CSS adapter that discards all classes by default
5361+
function _containerAdapter (clazz) {
5362+
return null;
5363+
}
5364+
5365+
function ContainerCSS () { }
5366+
5367+
ContainerCSS.prototype.render = function (decorated) {
5368+
var $container = decorated.call(this);
5369+
5370+
var containerCssClass = this.options.get('containerCssClass') || '';
5371+
5372+
if ($.isFunction(containerCssClass)) {
5373+
containerCssClass = containerCssClass(this.$element);
5374+
}
5375+
5376+
var containerCssAdapter = this.options.get('adaptContainerCssClass');
5377+
containerCssAdapter = containerCssAdapter || _containerAdapter;
5378+
5379+
if (containerCssClass.indexOf(':all:') !== -1) {
5380+
containerCssClass = containerCssClass.replace(':all', '');
5381+
5382+
var _cssAdapter = containerCssAdapter;
5383+
5384+
containerCssAdapter = function (clazz) {
5385+
var adapted = _cssAdapter(clazz);
5386+
5387+
if (adapted != null) {
5388+
// Append the old one along with the adapted one
5389+
return adapted + ' ' + clazz;
53135390
}
5314-
}
53155391

5316-
if (matcher(params.term, data.text, data)) {
5317-
return match;
5318-
}
5392+
return clazz;
5393+
};
5394+
}
53195395

5320-
return null;
5396+
var containerCss = this.options.get('containerCss') || {};
5397+
5398+
if ($.isFunction(containerCss)) {
5399+
containerCss = containerCss(this.$element);
53215400
}
53225401

5323-
return wrappedMatcher;
5402+
CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
5403+
5404+
$container.css(containerCss);
5405+
$container.addClass(containerCssClass);
5406+
5407+
return $container;
5408+
};
5409+
5410+
return ContainerCSS;
5411+
});
5412+
5413+
S2.define('select2/compat/dropdownCss',[
5414+
'jquery',
5415+
'./utils'
5416+
], function ($, CompatUtils) {
5417+
// No-op CSS adapter that discards all classes by default
5418+
function _dropdownAdapter (clazz) {
5419+
return null;
53245420
}
53255421

5326-
return oldMatcher;
5422+
function DropdownCSS () { }
5423+
5424+
DropdownCSS.prototype.render = function (decorated) {
5425+
var $dropdown = decorated.call(this);
5426+
5427+
var dropdownCssClass = this.options.get('dropdownCssClass') || '';
5428+
5429+
if ($.isFunction(dropdownCssClass)) {
5430+
dropdownCssClass = dropdownCssClass(this.$element);
5431+
}
5432+
5433+
var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
5434+
dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
5435+
5436+
if (dropdownCssClass.indexOf(':all:') !== -1) {
5437+
dropdownCssClass = dropdownCssClass.replace(':all', '');
5438+
5439+
var _cssAdapter = dropdownCssAdapter;
5440+
5441+
dropdownCssAdapter = function (clazz) {
5442+
var adapted = _cssAdapter(clazz);
5443+
5444+
if (adapted != null) {
5445+
// Append the old one along with the adapted one
5446+
return adapted + ' ' + clazz;
5447+
}
5448+
5449+
return clazz;
5450+
};
5451+
}
5452+
5453+
var dropdownCss = this.options.get('dropdownCss') || {};
5454+
5455+
if ($.isFunction(dropdownCss)) {
5456+
dropdownCss = dropdownCss(this.$element);
5457+
}
5458+
5459+
CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
5460+
5461+
$dropdown.css(dropdownCss);
5462+
$dropdown.addClass(dropdownCssClass);
5463+
5464+
return $dropdown;
5465+
};
5466+
5467+
return DropdownCSS;
53275468
});
53285469

53295470
S2.define('select2/compat/initSelection',[
@@ -5497,6 +5638,49 @@ S2.define('select2/compat/inputData',[
54975638
return InputData;
54985639
});
54995640

5641+
S2.define('select2/compat/matcher',[
5642+
'jquery'
5643+
], function ($) {
5644+
function oldMatcher (matcher) {
5645+
function wrappedMatcher (params, data) {
5646+
var match = $.extend(true, {}, data);
5647+
5648+
if (params.term == null || $.trim(params.term) === '') {
5649+
return match;
5650+
}
5651+
5652+
if (data.children) {
5653+
for (var c = data.children.length - 1; c >= 0; c--) {
5654+
var child = data.children[c];
5655+
5656+
// Check if the child object matches
5657+
// The old matcher returned a boolean true or false
5658+
var doesMatch = matcher(params.term, child.text, child);
5659+
5660+
// If the child didn't match, pop it off
5661+
if (!doesMatch) {
5662+
match.children.splice(c, 1);
5663+
}
5664+
}
5665+
5666+
if (match.children.length > 0) {
5667+
return match;
5668+
}
5669+
}
5670+
5671+
if (matcher(params.term, data.text, data)) {
5672+
return match;
5673+
}
5674+
5675+
return null;
5676+
}
5677+
5678+
return wrappedMatcher;
5679+
}
5680+
5681+
return oldMatcher;
5682+
});
5683+
55005684
S2.define('select2/compat/query',[
55015685

55025686
], function () {

dist/js/select2.full.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/js/select2.js

+26
Original file line numberDiff line numberDiff line change
@@ -4428,6 +4428,19 @@ S2.define('select2/defaults',[
44284428
);
44294429
}
44304430

4431+
if (
4432+
options.dropdownCssClass != null ||
4433+
options.dropdownCss != null ||
4434+
options.adaptDropdownCssClass != null
4435+
) {
4436+
var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4437+
4438+
options.dropdownAdapter = Utils.Decorate(
4439+
options.dropdownAdapter,
4440+
DropdownCSS
4441+
);
4442+
}
4443+
44314444
options.dropdownAdapter = Utils.Decorate(
44324445
options.dropdownAdapter,
44334446
AttachBody
@@ -4463,6 +4476,19 @@ S2.define('select2/defaults',[
44634476
);
44644477
}
44654478

4479+
if (
4480+
options.containerCssClass != null ||
4481+
options.containerCss != null ||
4482+
options.adaptContainerCssClass != null
4483+
) {
4484+
var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4485+
4486+
options.selectionAdapter = Utils.Decorate(
4487+
options.selectionAdapter,
4488+
ContainerCSS
4489+
);
4490+
}
4491+
44664492
options.selectionAdapter = Utils.Decorate(
44674493
options.selectionAdapter,
44684494
EventRelay

dist/js/select2.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/js/select2/compat/containerCss.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
define([
2+
'jquery',
3+
'./utils'
4+
], function ($, CompatUtils) {
5+
// No-op CSS adapter that discards all classes by default
6+
function _containerAdapter (clazz) {
7+
return null;
8+
}
9+
10+
function ContainerCSS () { }
11+
12+
ContainerCSS.prototype.render = function (decorated) {
13+
var $container = decorated.call(this);
14+
15+
var containerCssClass = this.options.get('containerCssClass') || '';
16+
17+
if ($.isFunction(containerCssClass)) {
18+
containerCssClass = containerCssClass(this.$element);
19+
}
20+
21+
var containerCssAdapter = this.options.get('adaptContainerCssClass');
22+
containerCssAdapter = containerCssAdapter || _containerAdapter;
23+
24+
if (containerCssClass.indexOf(':all:') !== -1) {
25+
containerCssClass = containerCssClass.replace(':all', '');
26+
27+
var _cssAdapter = containerCssAdapter;
28+
29+
containerCssAdapter = function (clazz) {
30+
var adapted = _cssAdapter(clazz);
31+
32+
if (adapted != null) {
33+
// Append the old one along with the adapted one
34+
return adapted + ' ' + clazz;
35+
}
36+
37+
return clazz;
38+
};
39+
}
40+
41+
var containerCss = this.options.get('containerCss') || {};
42+
43+
if ($.isFunction(containerCss)) {
44+
containerCss = containerCss(this.$element);
45+
}
46+
47+
CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
48+
49+
$container.css(containerCss);
50+
$container.addClass(containerCssClass);
51+
52+
return $container;
53+
};
54+
55+
return ContainerCSS;
56+
});

0 commit comments

Comments
 (0)