Browse Source

Added backwards compatibility for `initSelection`

Now if the old `initSelection` method is used, a warning will be
triggered in the console informing the user that it has now been
changed to `DataAdapter.current`, and they should create a custom
data adapter instead. We will still only call `initSelection` once,
and then default back to the old data adapter for calls after that.
This allows for mostly transparent support between versions.

This adds tests to ensure that `initSelection` operates the same as
it previously did, but now patches the `current` method of the
default data adapter.
Kevin Brown 10 years ago
parent
commit
e04188c85a

+ 34 - 0
dist/js/select2.amd.full.js

@@ -3528,6 +3528,40 @@ define('select2/defaults',[
           Tokenizer
         );
       }
+
+      if (options.initSelection != null) {
+        if (console && console.warn) {
+          console.warn(
+            'Select2: The `initSelection` option has been deprecated in favor' +
+            ' of a custom data adapter that overrides the `current` method. ' +
+            'This method is now called multiple times instead of a single ' +
+            'time when the instance is initialized.'
+          );
+        }
+
+        var oldCurrent = options.dataAdapter.prototype.current;
+        var newCurrent = function (callback) {
+          var self = this;
+
+          if (this._isInitialized) {
+            oldCurrent.call(this, callback);
+
+            return;
+          }
+
+          options.initSelection.call(null, this.$element, function (data) {
+            self._isInitialized = true;
+
+            if (!$.isArray(data)) {
+              data = [data];
+            }
+
+            callback(data);
+          });
+        };
+
+        options.dataAdapter.prototype.current = newCurrent;
+      }
     }
 
     if (options.resultsAdapter == null) {

+ 34 - 0
dist/js/select2.amd.js

@@ -3528,6 +3528,40 @@ define('select2/defaults',[
           Tokenizer
         );
       }
+
+      if (options.initSelection != null) {
+        if (console && console.warn) {
+          console.warn(
+            'Select2: The `initSelection` option has been deprecated in favor' +
+            ' of a custom data adapter that overrides the `current` method. ' +
+            'This method is now called multiple times instead of a single ' +
+            'time when the instance is initialized.'
+          );
+        }
+
+        var oldCurrent = options.dataAdapter.prototype.current;
+        var newCurrent = function (callback) {
+          var self = this;
+
+          if (this._isInitialized) {
+            oldCurrent.call(this, callback);
+
+            return;
+          }
+
+          options.initSelection.call(null, this.$element, function (data) {
+            self._isInitialized = true;
+
+            if (!$.isArray(data)) {
+              data = [data];
+            }
+
+            callback(data);
+          });
+        };
+
+        options.dataAdapter.prototype.current = newCurrent;
+      }
     }
 
     if (options.resultsAdapter == null) {

+ 34 - 0
dist/js/select2.full.js

@@ -13063,6 +13063,40 @@ define('select2/defaults',[
           Tokenizer
         );
       }
+
+      if (options.initSelection != null) {
+        if (console && console.warn) {
+          console.warn(
+            'Select2: The `initSelection` option has been deprecated in favor' +
+            ' of a custom data adapter that overrides the `current` method. ' +
+            'This method is now called multiple times instead of a single ' +
+            'time when the instance is initialized.'
+          );
+        }
+
+        var oldCurrent = options.dataAdapter.prototype.current;
+        var newCurrent = function (callback) {
+          var self = this;
+
+          if (this._isInitialized) {
+            oldCurrent.call(this, callback);
+
+            return;
+          }
+
+          options.initSelection.call(null, this.$element, function (data) {
+            self._isInitialized = true;
+
+            if (!$.isArray(data)) {
+              data = [data];
+            }
+
+            callback(data);
+          });
+        };
+
+        options.dataAdapter.prototype.current = newCurrent;
+      }
     }
 
     if (options.resultsAdapter == null) {

File diff suppressed because it is too large
+ 0 - 0
dist/js/select2.full.min.js


+ 34 - 0
dist/js/select2.js

@@ -3956,6 +3956,40 @@ define('select2/defaults',[
           Tokenizer
         );
       }
+
+      if (options.initSelection != null) {
+        if (console && console.warn) {
+          console.warn(
+            'Select2: The `initSelection` option has been deprecated in favor' +
+            ' of a custom data adapter that overrides the `current` method. ' +
+            'This method is now called multiple times instead of a single ' +
+            'time when the instance is initialized.'
+          );
+        }
+
+        var oldCurrent = options.dataAdapter.prototype.current;
+        var newCurrent = function (callback) {
+          var self = this;
+
+          if (this._isInitialized) {
+            oldCurrent.call(this, callback);
+
+            return;
+          }
+
+          options.initSelection.call(null, this.$element, function (data) {
+            self._isInitialized = true;
+
+            if (!$.isArray(data)) {
+              data = [data];
+            }
+
+            callback(data);
+          });
+        };
+
+        options.dataAdapter.prototype.current = newCurrent;
+      }
     }
 
     if (options.resultsAdapter == null) {

File diff suppressed because it is too large
+ 0 - 0
dist/js/select2.min.js


+ 34 - 0
src/js/select2/defaults.js

@@ -92,6 +92,40 @@ define([
           Tokenizer
         );
       }
+
+      if (options.initSelection != null) {
+        if (console && console.warn) {
+          console.warn(
+            'Select2: The `initSelection` option has been deprecated in favor' +
+            ' of a custom data adapter that overrides the `current` method. ' +
+            'This method is now called multiple times instead of a single ' +
+            'time when the instance is initialized.'
+          );
+        }
+
+        var oldCurrent = options.dataAdapter.prototype.current;
+        var newCurrent = function (callback) {
+          var self = this;
+
+          if (this._isInitialized) {
+            oldCurrent.call(this, callback);
+
+            return;
+          }
+
+          options.initSelection.call(null, this.$element, function (data) {
+            self._isInitialized = true;
+
+            if (!$.isArray(data)) {
+              data = [data];
+            }
+
+            callback(data);
+          });
+        };
+
+        options.dataAdapter.prototype.current = newCurrent;
+      }
     }
 
     if (options.resultsAdapter == null) {

+ 158 - 0
tests/options/deprecated-tests.js

@@ -0,0 +1,158 @@
+module('Options - Deprecated - initSelection');
+
+var $ = require('jquery');
+var Options = require('select2/options');
+
+test('converted into dataAdapter.current', function (assert) {
+  expect(5);
+
+  var $test = $('<select></select>');
+  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) {
+  expect(2);
+
+  var $test = $('<select></select>');
+  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) {
+  expect(8);
+
+  var $test = $('<select><option value="3" selected>4</option></select>');
+  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'
+  );
+});

+ 18 - 0
tests/options/deprecated.html

@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+  <head>
+    <link rel="stylesheet" href="../vendor/qunit-1.14.0.css" type="text/css" />
+    <link rel="stylesheet" href="../../dist/css/select2.css" type="text/css" />
+  </head>
+  <body>
+    <div id="qunit"></div>
+    <div id="qunit-fixture"></div>
+
+    <script src="../vendor/qunit-1.14.0.js" type="text/javascript"></script>
+    <script src="../../vendor/almond-0.2.9.js" type="text/javascript"></script>
+    <script src="../../vendor/jquery-2.1.0.js" type="text/javascript"></script>
+    <script src="../../dist/js/select2.amd.js" type="text/javascript"></script>
+
+    <script src="deprecated-tests.js" type="text/javascript"></script>
+  </body>
+</html>

Some files were not shown because too many files changed in this diff