Jelajahi Sumber

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 tahun lalu
induk
melakukan
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;
     }
 

File diff ditekan karena terlalu besar
+ 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;
     }
 

File diff ditekan karena terlalu besar
+ 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;

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini