ソースを参照

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;

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません