From fe3f95e569b61ddbd18bad5a2930115988eefcdc Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Mon, 12 Oct 2015 12:08:01 +1100 Subject: [PATCH 1/5] Update internal.js there is no need to clone() here, it creates a memory leak as it's not attached the to DOM and therefore isn't removed by remove() --- src/internal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal.js b/src/internal.js index 9b9bba4..1d7984e 100644 --- a/src/internal.js +++ b/src/internal.js @@ -873,7 +873,7 @@ function replacePlaceHolder(placeholder, element) placeholder.each(function (index, item) { // todo: check how append is implemented. Perhaps cloning here is superfluous. - $(item).before(element.clone(true)).remove(); + $(item).before(element).remove(); }); } @@ -945,4 +945,4 @@ function sortRows() this.rows.sort(sort); } } -} \ No newline at end of file +} From 1225b4a0475bcf57fc88dc9f98d284299f466ff2 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 30 Oct 2015 14:29:05 +1100 Subject: [PATCH 2/5] Add an event columnToggle Trigger an event when columns are toggled on or off --- src/internal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/internal.js b/src/internal.js index 1d7984e..5ed0af8 100644 --- a/src/internal.js +++ b/src/internal.js @@ -393,6 +393,7 @@ function renderColumnSelection(actions) that.element.find("tbody").empty(); // Fixes an column visualization bug renderTableHeader.call(that); loadData.call(that); + that.element.trigger("columnToggle" + namespace, column); } }); dropDown.find(getCssSelector(css.dropDownMenuItems)).append(item); From 2d26feab84017344a679b45f5bbfdb54149941ae Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 15 Sep 2016 11:48:17 +0200 Subject: [PATCH 3/5] Drastically faster templating approach The current templating approach is really inefficient, as it recursively loops thru every passed available variable for substituion and applies a regex for each one. It's much faster to initially parse the template and then only process those strings which are actually present in the template. This revised implementation both caches the parsed templates and then only processes the string which are present. The performance improvement is quite drastic, especially with large tables. A large table was previously taking 15s to render in Chrome, now takes less than 1s with this approach --- src/extensions.js | 74 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/src/extensions.js b/src/extensions.js index cb37139..4956360 100644 --- a/src/extensions.js +++ b/src/extensions.js @@ -65,32 +65,66 @@ if (!String.prototype.resolve) return value; } }; + + var _templateCache = {}; + var getTemplate = function(template){ + if (!_templateCache.hasOwnProperty(template)){ + var str = template.split(/{([^{}]+)}/g); + + for (var i = 0; i < str.length; i++){ + var s = str[i]; + var hasStart = (s.charAt(0) === "}"); + var hasEnd = (s.charAt(s.length - 1) === "{"); + if (hasStart) + s = s.substr(1); + if (hasEnd) + s = s.substr(0, s.length - 1); + + if (hasStart || hasEnd){ + str[i] = s; //plain old html + } else { + str[i] = { + token: str[i], + key: s.split(".") + }; + } + } + _templateCache[template] = str; + } + return _templateCache[template]; + }; String.prototype.resolve = function (substitutes, prefixes) { - var result = this; - $.each(substitutes, function (key, value) - { - if (value != null && typeof value !== "function") - { - if (typeof value === "object") - { - var keys = (prefixes) ? $.extend([], prefixes) : []; - keys.push(key); - result = result.resolve(value, keys) + ""; - } + var str = getTemplate(this); + var result = ""; + for (var i = 0; i < str.length; i++){ + if (typeof str[i] === "object"){ + var key = str[i].key; + // now we have a variable to be substitued + if (substitutes.hasOwnProperty(key[0])) + var v = substitutes[key[0]]; else - { - if (formatter && formatter[key] && typeof formatter[key] === "function") - { - value = formatter[key](value); + continue; + + for (var k = 1; k < key.length; k++){ + if (v.hasOwnProperty(key[k])){ + v = v[key[k]]; + } else { + v = null; + break; } - key = (prefixes) ? prefixes.join(".") + "." + key : key; - var pattern = new RegExp("\\{\\{" + key + "\\}\\}", "gm"); - result = result.replace(pattern, (value.replace) ? value.replace(/\$/gi, "$") : value); } + var formatter_key = key[key.length-1]; + if (formatter && formatter[formatter_key] && typeof formatter[formatter_key] === "function"){ + result += formatter[formatter_key](v); + } else { + result += v; + } + } else { + result += str[i]; // plain old html } - }); + } return result; }; } @@ -167,4 +201,4 @@ if (!Array.prototype.propValues) } return result; }; -} \ No newline at end of file +} From d33185db250f7e109d80ba0cb49b69d1bffc0f1a Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 15 Sep 2016 11:55:46 +0200 Subject: [PATCH 4/5] Update extensions.js --- src/extensions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/extensions.js b/src/extensions.js index 4956360..968da4d 100644 --- a/src/extensions.js +++ b/src/extensions.js @@ -101,9 +101,10 @@ if (!String.prototype.resolve) for (var i = 0; i < str.length; i++){ if (typeof str[i] === "object"){ var key = str[i].key; + var v = ""; // now we have a variable to be substitued if (substitutes.hasOwnProperty(key[0])) - var v = substitutes[key[0]]; + v = substitutes[key[0]]; else continue; From 8d11d27a72c6b5d73d9a4d0c686296c457456802 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 15 Sep 2016 12:00:50 +0200 Subject: [PATCH 5/5] lint clean up --- src/extensions.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/extensions.js b/src/extensions.js index 968da4d..cab961c 100644 --- a/src/extensions.js +++ b/src/extensions.js @@ -76,11 +76,16 @@ if (!String.prototype.resolve) var hasStart = (s.charAt(0) === "}"); var hasEnd = (s.charAt(s.length - 1) === "{"); if (hasStart) + { s = s.substr(1); + } if (hasEnd) + { s = s.substr(0, s.length - 1); + } - if (hasStart || hasEnd){ + if (hasStart || hasEnd) + { str[i] = s; //plain old html } else { str[i] = { @@ -104,9 +109,13 @@ if (!String.prototype.resolve) var v = ""; // now we have a variable to be substitued if (substitutes.hasOwnProperty(key[0])) + { v = substitutes[key[0]]; + } else + { continue; + } for (var k = 1; k < key.length; k++){ if (v.hasOwnProperty(key[k])){