Przeglądaj źródła

Fix caching when querying

This fixes caching when querying, so the data object no longer
needs to be completely regenerated whenever the `<option>` is
queried.

While this does not fix the speed issues on the first opening of
the instance, it does fix the speed issues during searching.
Kevin Brown 10 lat temu
rodzic
commit
8ecc35d504

+ 36 - 31
dist/js/select2.amd.full.js

@@ -261,8 +261,10 @@ define('select2/results',[
   };
   };
 
 
   Results.prototype.option = function (data) {
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'role': 'treeitem',
       'aria-selected': 'false'
       'aria-selected': 'false'
     };
     };
@@ -277,7 +279,7 @@ define('select2/results',[
     }
     }
 
 
     if (data._resultId != null) {
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
     }
 
 
     if (data.children) {
     if (data.children) {
@@ -286,21 +288,15 @@ define('select2/results',[
       delete attrs['aria-selected'];
       delete attrs['aria-selected'];
     }
     }
 
 
-    var html = '<li';
-
-    for (var attr in attrs) {
-      var val = attrs[attr];
-
-      html += ' ' + attr + '="' + val + '"';
-    }
-
-    html += '></li>';
-
-    var $option = $(html);
+    var $option = $(option);
+    $option.attr(attrs);
 
 
     if (data.children) {
     if (data.children) {
-      var $label = $('<strong class="group-label"></strong>');
-      this.template(data, $label);
+      var label = document.createElement('strong');
+      label.className = 'group-label';
+
+      var $label = $(label);
+      this.template(data, label);
 
 
       var $children = [];
       var $children = [];
 
 
@@ -316,10 +312,10 @@ define('select2/results',[
 
 
       $childrenContainer.append($children);
       $childrenContainer.append($children);
 
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
       $option.append($childrenContainer);
     } else {
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
     }
 
 
     $option.data('data', data);
     $option.data('data', data);
@@ -543,10 +539,10 @@ define('select2/results',[
     }
     }
   };
   };
 
 
-  Results.prototype.template = function (result, $container) {
+  Results.prototype.template = function (result, container) {
     var template = this.options.get('templateResult');
     var template = this.options.get('templateResult');
 
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
   };
 
 
   return Results;
   return Results;
@@ -1125,12 +1121,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
   SelectAdapter.prototype.item = function ($option) {
     var data = {};
     var data = {};
 
 
-    if ($.hasData($option)) {
-      data = $option.data('data');
+    data = $option.data('data');
 
 
-      if (data != null) {
-        return data;
-      }
+    if (data != null) {
+      return data;
     }
     }
 
 
     if ($option.is('option')) {
     if ($option.is('option')) {
@@ -1811,33 +1805,44 @@ define('select2/defaults',[
 
 
   Defaults.prototype.reset = function () {
   Defaults.prototype.reset = function () {
     function matcher (params, data) {
     function matcher (params, data) {
-      var match = $.extend(true, {}, data);
+      // Always return the object if there is nothing to compare
+      if ($.trim(params.term) === '') {
+        return data;
+      }
 
 
-      if (data.children) {
+      // Do a recursive check for options with children
+      if (data.children && data.children.length > 0) {
+        // Clone the data object if there are children
+        // This is required as we modify the object to remove any non-matches
+        var match = $.extend(true, {}, data);
+
+        // Check each child of the option
         for (var c = data.children.length - 1; c >= 0; c--) {
         for (var c = data.children.length - 1; c >= 0; c--) {
           var child = data.children[c];
           var child = data.children[c];
 
 
           var matches = matcher(params, child);
           var matches = matcher(params, child);
 
 
           // If there wasn't a match, remove the object in the array
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
             match.children.splice(c, 1);
           }
           }
         }
         }
 
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
         if (match.children.length > 0) {
           return match;
           return match;
         }
         }
-      }
 
 
-      if ($.trim(params.term) === '') {
-        return match;
+        // If there were no matching children, check just the plain object
+        return matcher(params, match);
       }
       }
 
 
+      // Check if the text contains the term
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
-        return match;
+        return data;
       }
       }
 
 
+      // If it doesn't contain the term, don't return anything
       return null;
       return null;
     }
     }
 
 

+ 36 - 31
dist/js/select2.amd.js

@@ -261,8 +261,10 @@ define('select2/results',[
   };
   };
 
 
   Results.prototype.option = function (data) {
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'role': 'treeitem',
       'aria-selected': 'false'
       'aria-selected': 'false'
     };
     };
@@ -277,7 +279,7 @@ define('select2/results',[
     }
     }
 
 
     if (data._resultId != null) {
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
     }
 
 
     if (data.children) {
     if (data.children) {
@@ -286,21 +288,15 @@ define('select2/results',[
       delete attrs['aria-selected'];
       delete attrs['aria-selected'];
     }
     }
 
 
-    var html = '<li';
-
-    for (var attr in attrs) {
-      var val = attrs[attr];
-
-      html += ' ' + attr + '="' + val + '"';
-    }
-
-    html += '></li>';
-
-    var $option = $(html);
+    var $option = $(option);
+    $option.attr(attrs);
 
 
     if (data.children) {
     if (data.children) {
-      var $label = $('<strong class="group-label"></strong>');
-      this.template(data, $label);
+      var label = document.createElement('strong');
+      label.className = 'group-label';
+
+      var $label = $(label);
+      this.template(data, label);
 
 
       var $children = [];
       var $children = [];
 
 
@@ -316,10 +312,10 @@ define('select2/results',[
 
 
       $childrenContainer.append($children);
       $childrenContainer.append($children);
 
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
       $option.append($childrenContainer);
     } else {
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
     }
 
 
     $option.data('data', data);
     $option.data('data', data);
@@ -543,10 +539,10 @@ define('select2/results',[
     }
     }
   };
   };
 
 
-  Results.prototype.template = function (result, $container) {
+  Results.prototype.template = function (result, container) {
     var template = this.options.get('templateResult');
     var template = this.options.get('templateResult');
 
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
   };
 
 
   return Results;
   return Results;
@@ -1125,12 +1121,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
   SelectAdapter.prototype.item = function ($option) {
     var data = {};
     var data = {};
 
 
-    if ($.hasData($option)) {
-      data = $option.data('data');
+    data = $option.data('data');
 
 
-      if (data != null) {
-        return data;
-      }
+    if (data != null) {
+      return data;
     }
     }
 
 
     if ($option.is('option')) {
     if ($option.is('option')) {
@@ -1811,33 +1805,44 @@ define('select2/defaults',[
 
 
   Defaults.prototype.reset = function () {
   Defaults.prototype.reset = function () {
     function matcher (params, data) {
     function matcher (params, data) {
-      var match = $.extend(true, {}, data);
+      // Always return the object if there is nothing to compare
+      if ($.trim(params.term) === '') {
+        return data;
+      }
 
 
-      if (data.children) {
+      // Do a recursive check for options with children
+      if (data.children && data.children.length > 0) {
+        // Clone the data object if there are children
+        // This is required as we modify the object to remove any non-matches
+        var match = $.extend(true, {}, data);
+
+        // Check each child of the option
         for (var c = data.children.length - 1; c >= 0; c--) {
         for (var c = data.children.length - 1; c >= 0; c--) {
           var child = data.children[c];
           var child = data.children[c];
 
 
           var matches = matcher(params, child);
           var matches = matcher(params, child);
 
 
           // If there wasn't a match, remove the object in the array
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
             match.children.splice(c, 1);
           }
           }
         }
         }
 
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
         if (match.children.length > 0) {
           return match;
           return match;
         }
         }
-      }
 
 
-      if ($.trim(params.term) === '') {
-        return match;
+        // If there were no matching children, check just the plain object
+        return matcher(params, match);
       }
       }
 
 
+      // Check if the text contains the term
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
-        return match;
+        return data;
       }
       }
 
 
+      // If it doesn't contain the term, don't return anything
       return null;
       return null;
     }
     }
 
 

+ 36 - 31
dist/js/select2.full.js

@@ -9796,8 +9796,10 @@ define('select2/results',[
   };
   };
 
 
   Results.prototype.option = function (data) {
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'role': 'treeitem',
       'aria-selected': 'false'
       'aria-selected': 'false'
     };
     };
@@ -9812,7 +9814,7 @@ define('select2/results',[
     }
     }
 
 
     if (data._resultId != null) {
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
     }
 
 
     if (data.children) {
     if (data.children) {
@@ -9821,21 +9823,15 @@ define('select2/results',[
       delete attrs['aria-selected'];
       delete attrs['aria-selected'];
     }
     }
 
 
-    var html = '<li';
-
-    for (var attr in attrs) {
-      var val = attrs[attr];
-
-      html += ' ' + attr + '="' + val + '"';
-    }
-
-    html += '></li>';
-
-    var $option = $(html);
+    var $option = $(option);
+    $option.attr(attrs);
 
 
     if (data.children) {
     if (data.children) {
-      var $label = $('<strong class="group-label"></strong>');
-      this.template(data, $label);
+      var label = document.createElement('strong');
+      label.className = 'group-label';
+
+      var $label = $(label);
+      this.template(data, label);
 
 
       var $children = [];
       var $children = [];
 
 
@@ -9851,10 +9847,10 @@ define('select2/results',[
 
 
       $childrenContainer.append($children);
       $childrenContainer.append($children);
 
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
       $option.append($childrenContainer);
     } else {
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
     }
 
 
     $option.data('data', data);
     $option.data('data', data);
@@ -10078,10 +10074,10 @@ define('select2/results',[
     }
     }
   };
   };
 
 
-  Results.prototype.template = function (result, $container) {
+  Results.prototype.template = function (result, container) {
     var template = this.options.get('templateResult');
     var template = this.options.get('templateResult');
 
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
   };
 
 
   return Results;
   return Results;
@@ -10660,12 +10656,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
   SelectAdapter.prototype.item = function ($option) {
     var data = {};
     var data = {};
 
 
-    if ($.hasData($option)) {
-      data = $option.data('data');
+    data = $option.data('data');
 
 
-      if (data != null) {
-        return data;
-      }
+    if (data != null) {
+      return data;
     }
     }
 
 
     if ($option.is('option')) {
     if ($option.is('option')) {
@@ -11346,33 +11340,44 @@ define('select2/defaults',[
 
 
   Defaults.prototype.reset = function () {
   Defaults.prototype.reset = function () {
     function matcher (params, data) {
     function matcher (params, data) {
-      var match = $.extend(true, {}, data);
+      // Always return the object if there is nothing to compare
+      if ($.trim(params.term) === '') {
+        return data;
+      }
 
 
-      if (data.children) {
+      // Do a recursive check for options with children
+      if (data.children && data.children.length > 0) {
+        // Clone the data object if there are children
+        // This is required as we modify the object to remove any non-matches
+        var match = $.extend(true, {}, data);
+
+        // Check each child of the option
         for (var c = data.children.length - 1; c >= 0; c--) {
         for (var c = data.children.length - 1; c >= 0; c--) {
           var child = data.children[c];
           var child = data.children[c];
 
 
           var matches = matcher(params, child);
           var matches = matcher(params, child);
 
 
           // If there wasn't a match, remove the object in the array
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
             match.children.splice(c, 1);
           }
           }
         }
         }
 
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
         if (match.children.length > 0) {
           return match;
           return match;
         }
         }
-      }
 
 
-      if ($.trim(params.term) === '') {
-        return match;
+        // If there were no matching children, check just the plain object
+        return matcher(params, match);
       }
       }
 
 
+      // Check if the text contains the term
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
-        return match;
+        return data;
       }
       }
 
 
+      // If it doesn't contain the term, don't return anything
       return null;
       return null;
     }
     }
 
 

Plik diff jest za duży
+ 0 - 0
dist/js/select2.full.min.js


+ 36 - 31
dist/js/select2.js

@@ -689,8 +689,10 @@ define('select2/results',[
   };
   };
 
 
   Results.prototype.option = function (data) {
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'role': 'treeitem',
       'aria-selected': 'false'
       'aria-selected': 'false'
     };
     };
@@ -705,7 +707,7 @@ define('select2/results',[
     }
     }
 
 
     if (data._resultId != null) {
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
     }
 
 
     if (data.children) {
     if (data.children) {
@@ -714,21 +716,15 @@ define('select2/results',[
       delete attrs['aria-selected'];
       delete attrs['aria-selected'];
     }
     }
 
 
-    var html = '<li';
-
-    for (var attr in attrs) {
-      var val = attrs[attr];
-
-      html += ' ' + attr + '="' + val + '"';
-    }
-
-    html += '></li>';
-
-    var $option = $(html);
+    var $option = $(option);
+    $option.attr(attrs);
 
 
     if (data.children) {
     if (data.children) {
-      var $label = $('<strong class="group-label"></strong>');
-      this.template(data, $label);
+      var label = document.createElement('strong');
+      label.className = 'group-label';
+
+      var $label = $(label);
+      this.template(data, label);
 
 
       var $children = [];
       var $children = [];
 
 
@@ -744,10 +740,10 @@ define('select2/results',[
 
 
       $childrenContainer.append($children);
       $childrenContainer.append($children);
 
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
       $option.append($childrenContainer);
     } else {
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
     }
 
 
     $option.data('data', data);
     $option.data('data', data);
@@ -971,10 +967,10 @@ define('select2/results',[
     }
     }
   };
   };
 
 
-  Results.prototype.template = function (result, $container) {
+  Results.prototype.template = function (result, container) {
     var template = this.options.get('templateResult');
     var template = this.options.get('templateResult');
 
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
   };
 
 
   return Results;
   return Results;
@@ -1553,12 +1549,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
   SelectAdapter.prototype.item = function ($option) {
     var data = {};
     var data = {};
 
 
-    if ($.hasData($option)) {
-      data = $option.data('data');
+    data = $option.data('data');
 
 
-      if (data != null) {
-        return data;
-      }
+    if (data != null) {
+      return data;
     }
     }
 
 
     if ($option.is('option')) {
     if ($option.is('option')) {
@@ -2239,33 +2233,44 @@ define('select2/defaults',[
 
 
   Defaults.prototype.reset = function () {
   Defaults.prototype.reset = function () {
     function matcher (params, data) {
     function matcher (params, data) {
-      var match = $.extend(true, {}, data);
+      // Always return the object if there is nothing to compare
+      if ($.trim(params.term) === '') {
+        return data;
+      }
 
 
-      if (data.children) {
+      // Do a recursive check for options with children
+      if (data.children && data.children.length > 0) {
+        // Clone the data object if there are children
+        // This is required as we modify the object to remove any non-matches
+        var match = $.extend(true, {}, data);
+
+        // Check each child of the option
         for (var c = data.children.length - 1; c >= 0; c--) {
         for (var c = data.children.length - 1; c >= 0; c--) {
           var child = data.children[c];
           var child = data.children[c];
 
 
           var matches = matcher(params, child);
           var matches = matcher(params, child);
 
 
           // If there wasn't a match, remove the object in the array
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
             match.children.splice(c, 1);
           }
           }
         }
         }
 
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
         if (match.children.length > 0) {
           return match;
           return match;
         }
         }
-      }
 
 
-      if ($.trim(params.term) === '') {
-        return match;
+        // If there were no matching children, check just the plain object
+        return matcher(params, match);
       }
       }
 
 
+      // Check if the text contains the term
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
-        return match;
+        return data;
       }
       }
 
 
+      // If it doesn't contain the term, don't return anything
       return null;
       return null;
     }
     }
 
 

Plik diff jest za duży
+ 0 - 0
dist/js/select2.min.js


+ 3 - 5
src/js/select2/data/select.js

@@ -148,12 +148,10 @@ define([
   SelectAdapter.prototype.item = function ($option) {
   SelectAdapter.prototype.item = function ($option) {
     var data = {};
     var data = {};
 
 
-    if ($.hasData($option)) {
-      data = $option.data('data');
+    data = $option.data('data');
 
 
-      if (data != null) {
-        return data;
-      }
+    if (data != null) {
+      return data;
     }
     }
 
 
     if ($option.is('option')) {
     if ($option.is('option')) {

+ 18 - 7
src/js/select2/defaults.js

@@ -130,33 +130,44 @@ define([
 
 
   Defaults.prototype.reset = function () {
   Defaults.prototype.reset = function () {
     function matcher (params, data) {
     function matcher (params, data) {
-      var match = $.extend(true, {}, data);
+      // Always return the object if there is nothing to compare
+      if ($.trim(params.term) === '') {
+        return data;
+      }
+
+      // Do a recursive check for options with children
+      if (data.children && data.children.length > 0) {
+        // Clone the data object if there are children
+        // This is required as we modify the object to remove any non-matches
+        var match = $.extend(true, {}, data);
 
 
-      if (data.children) {
+        // Check each child of the option
         for (var c = data.children.length - 1; c >= 0; c--) {
         for (var c = data.children.length - 1; c >= 0; c--) {
           var child = data.children[c];
           var child = data.children[c];
 
 
           var matches = matcher(params, child);
           var matches = matcher(params, child);
 
 
           // If there wasn't a match, remove the object in the array
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
             match.children.splice(c, 1);
           }
           }
         }
         }
 
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
         if (match.children.length > 0) {
           return match;
           return match;
         }
         }
-      }
 
 
-      if ($.trim(params.term) === '') {
-        return match;
+        // If there were no matching children, check just the plain object
+        return matcher(params, match);
       }
       }
 
 
+      // Check if the text contains the term
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
       if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
-        return match;
+        return data;
       }
       }
 
 
+      // If it doesn't contain the term, don't return anything
       return null;
       return null;
     }
     }
 
 

+ 15 - 19
src/js/select2/results.js

@@ -107,8 +107,10 @@ define([
   };
   };
 
 
   Results.prototype.option = function (data) {
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'role': 'treeitem',
       'aria-selected': 'false'
       'aria-selected': 'false'
     };
     };
@@ -123,7 +125,7 @@ define([
     }
     }
 
 
     if (data._resultId != null) {
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
     }
 
 
     if (data.children) {
     if (data.children) {
@@ -132,21 +134,15 @@ define([
       delete attrs['aria-selected'];
       delete attrs['aria-selected'];
     }
     }
 
 
-    var html = '<li';
-
-    for (var attr in attrs) {
-      var val = attrs[attr];
-
-      html += ' ' + attr + '="' + val + '"';
-    }
-
-    html += '></li>';
-
-    var $option = $(html);
+    var $option = $(option);
+    $option.attr(attrs);
 
 
     if (data.children) {
     if (data.children) {
-      var $label = $('<strong class="group-label"></strong>');
-      this.template(data, $label);
+      var label = document.createElement('strong');
+      label.className = 'group-label';
+
+      var $label = $(label);
+      this.template(data, label);
 
 
       var $children = [];
       var $children = [];
 
 
@@ -162,10 +158,10 @@ define([
 
 
       $childrenContainer.append($children);
       $childrenContainer.append($children);
 
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
       $option.append($childrenContainer);
     } else {
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
     }
 
 
     $option.data('data', data);
     $option.data('data', data);
@@ -389,10 +385,10 @@ define([
     }
     }
   };
   };
 
 
-  Results.prototype.template = function (result, $container) {
+  Results.prototype.template = function (result, container) {
     var template = this.options.get('templateResult');
     var template = this.options.get('templateResult');
 
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
   };
 
 
   return Results;
   return Results;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików