Переглянути джерело

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 роки тому
батько
коміт
8ecc35d504

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

@@ -261,8 +261,10 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'aria-selected': 'false'
     };
@@ -277,7 +279,7 @@ define('select2/results',[
     }
 
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
 
     if (data.children) {
@@ -286,21 +288,15 @@ define('select2/results',[
       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) {
-      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 = [];
 
@@ -316,10 +312,10 @@ define('select2/results',[
 
       $childrenContainer.append($children);
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
 
     $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');
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
 
   return Results;
@@ -1125,12 +1121,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
     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')) {
@@ -1811,33 +1805,44 @@ define('select2/defaults',[
 
   Defaults.prototype.reset = function () {
     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--) {
           var child = data.children[c];
 
           var matches = matcher(params, child);
 
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
           }
         }
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
           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) {
-        return match;
+        return data;
       }
 
+      // If it doesn't contain the term, don't return anything
       return null;
     }
 

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

@@ -261,8 +261,10 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'aria-selected': 'false'
     };
@@ -277,7 +279,7 @@ define('select2/results',[
     }
 
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
 
     if (data.children) {
@@ -286,21 +288,15 @@ define('select2/results',[
       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) {
-      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 = [];
 
@@ -316,10 +312,10 @@ define('select2/results',[
 
       $childrenContainer.append($children);
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
 
     $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');
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
 
   return Results;
@@ -1125,12 +1121,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
     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')) {
@@ -1811,33 +1805,44 @@ define('select2/defaults',[
 
   Defaults.prototype.reset = function () {
     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--) {
           var child = data.children[c];
 
           var matches = matcher(params, child);
 
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
           }
         }
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
           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) {
-        return match;
+        return data;
       }
 
+      // If it doesn't contain the term, don't return anything
       return null;
     }
 

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

@@ -9796,8 +9796,10 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'aria-selected': 'false'
     };
@@ -9812,7 +9814,7 @@ define('select2/results',[
     }
 
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
 
     if (data.children) {
@@ -9821,21 +9823,15 @@ define('select2/results',[
       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) {
-      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 = [];
 
@@ -9851,10 +9847,10 @@ define('select2/results',[
 
       $childrenContainer.append($children);
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
 
     $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');
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
 
   return Results;
@@ -10660,12 +10656,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
     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')) {
@@ -11346,33 +11340,44 @@ define('select2/defaults',[
 
   Defaults.prototype.reset = function () {
     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--) {
           var child = data.children[c];
 
           var matches = matcher(params, child);
 
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
           }
         }
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
           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) {
-        return match;
+        return data;
       }
 
+      // If it doesn't contain the term, don't return anything
       return null;
     }
 

Різницю між файлами не показано, бо вона завелика
+ 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) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'aria-selected': 'false'
     };
@@ -705,7 +707,7 @@ define('select2/results',[
     }
 
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
 
     if (data.children) {
@@ -714,21 +716,15 @@ define('select2/results',[
       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) {
-      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 = [];
 
@@ -744,10 +740,10 @@ define('select2/results',[
 
       $childrenContainer.append($children);
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
 
     $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');
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
 
   return Results;
@@ -1553,12 +1549,10 @@ define('select2/data/select',[
   SelectAdapter.prototype.item = function ($option) {
     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')) {
@@ -2239,33 +2233,44 @@ define('select2/defaults',[
 
   Defaults.prototype.reset = function () {
     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--) {
           var child = data.children[c];
 
           var matches = matcher(params, child);
 
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
           }
         }
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
           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) {
-        return match;
+        return data;
       }
 
+      // If it doesn't contain the term, don't return anything
       return null;
     }
 

Різницю між файлами не показано, бо вона завелика
+ 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) {
     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')) {

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

@@ -130,33 +130,44 @@ define([
 
   Defaults.prototype.reset = function () {
     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--) {
           var child = data.children[c];
 
           var matches = matcher(params, child);
 
           // If there wasn't a match, remove the object in the array
-          if (matches === null) {
+          if (matches == null) {
             match.children.splice(c, 1);
           }
         }
 
+        // If any children matched, return the new object
         if (match.children.length > 0) {
           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) {
-        return match;
+        return data;
       }
 
+      // If it doesn't contain the term, don't return anything
       return null;
     }
 

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

@@ -107,8 +107,10 @@ define([
   };
 
   Results.prototype.option = function (data) {
+    var option = document.createElement('li');
+    option.className = 'option';
+
     var attrs = {
-      'class': 'option',
       'role': 'treeitem',
       'aria-selected': 'false'
     };
@@ -123,7 +125,7 @@ define([
     }
 
     if (data._resultId != null) {
-      attrs.id = data._resultId;
+      option.id = data._resultId;
     }
 
     if (data.children) {
@@ -132,21 +134,15 @@ define([
       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) {
-      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 = [];
 
@@ -162,10 +158,10 @@ define([
 
       $childrenContainer.append($children);
 
-      $option.append($label);
+      $option.append(label);
       $option.append($childrenContainer);
     } else {
-      this.template(data, $option);
+      this.template(data, option);
     }
 
     $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');
 
-    $container.html(template(result));
+    container.innerHTML = template(result);
   };
 
   return Results;

Деякі файли не було показано, через те що забагато файлів було змінено