From bae238794a6e3778f2abbb58bf1b2cb8334b0d59 Mon Sep 17 00:00:00 2001
From: rr- <rr-@sakuya.pl>
Date: Sat, 21 May 2016 08:07:16 +0200
Subject: [PATCH] client/general: reduce lodash usages

---
 client/js/controls/auto_complete_control.js   | 58 +++++++++----------
 .../js/controls/tag_auto_complete_control.js  | 15 ++---
 client/js/util/views.js                       |  2 +-
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/client/js/controls/auto_complete_control.js b/client/js/controls/auto_complete_control.js
index 75327593..c707c6c6 100644
--- a/client/js/controls/auto_complete_control.js
+++ b/client/js/controls/auto_complete_control.js
@@ -1,6 +1,5 @@
 'use strict';
 
-const lodash = require('lodash');
 const views = require('../util/views.js');
 
 const KEY_TAB = 9;
@@ -27,7 +26,8 @@ function _getSelectionStart(input) {
 class AutoCompleteControl {
     constructor(sourceInputNode, options) {
         this._sourceInputNode = sourceInputNode;
-        this._options = lodash.extend({}, {
+        this._options = {};
+        Object.assign(this._options, {
             verticalShift: 2,
             source: null,
             maxResults: 15,
@@ -202,7 +202,9 @@ class AutoCompleteControl {
         this._results =
             this._options.getMatches(textToFind)
             .slice(0, this._options.maxResults);
-        if (!lodash.isEqual(oldResults, this._results)) {
+        const oldResultsHash = JSON.stringify(oldResults);
+        const newResultsHash = JSON.stringify(this._results);
+        if (oldResultsHash !== newResultsHash) {
             this._activeResult = -1;
         }
     }
@@ -216,32 +218,30 @@ class AutoCompleteControl {
         while (this._suggestionList.firstChild) {
             this._suggestionList.removeChild(this._suggestionList.firstChild);
         }
-        lodash.each(
-            this._results,
-            (resultItem, resultIndex) => {
-                const listItem = document.createElement('li');
-                const link = document.createElement('a');
-                link.href = '#';
-                link.innerHTML = resultItem.caption;
-                link.setAttribute('data-key', resultItem.value);
-                link.addEventListener(
-                    'mouseenter',
-                    e => {
-                        e.preventDefault();
-                        this._activeResult = resultIndex;
-                        this._refreshActiveResult();
-                    });
-                link.addEventListener(
-                    'mousedown',
-                    e => {
-                        e.preventDefault();
-                        this._activeResult = resultIndex;
-                        this._options.confirm(this._getActiveSuggestion());
-                        this.hide();
-                    });
-                listItem.appendChild(link);
-                this._suggestionList.appendChild(listItem);
-            });
+        for (let [resultIndex, resultItem] of this._results.entries()) {
+            const listItem = document.createElement('li');
+            const link = document.createElement('a');
+            link.href = '#';
+            link.innerHTML = resultItem.caption;
+            link.setAttribute('data-key', resultItem.value);
+            link.addEventListener(
+                'mouseenter',
+                e => {
+                    e.preventDefault();
+                    this._activeResult = resultIndex;
+                    this._refreshActiveResult();
+                });
+            link.addEventListener(
+                'mousedown',
+                e => {
+                    e.preventDefault();
+                    this._activeResult = resultIndex;
+                    this._options.confirm(this._getActiveSuggestion());
+                    this.hide();
+                });
+            listItem.appendChild(link);
+            this._suggestionList.appendChild(listItem);
+        }
         this._refreshActiveResult();
 
         // display the suggestions offscreen to get the height
diff --git a/client/js/controls/tag_auto_complete_control.js b/client/js/controls/tag_auto_complete_control.js
index 6bbe8d87..a9fb7f0a 100644
--- a/client/js/controls/tag_auto_complete_control.js
+++ b/client/js/controls/tag_auto_complete_control.js
@@ -1,7 +1,6 @@
 'use strict';
 
 const unindent = require('../util/misc.js').unindent;
-const lodash = require('lodash');
 const tags = require('../tags.js');
 const AutoCompleteControl = require('./auto_complete_control.js');
 
@@ -16,13 +15,15 @@ class TagAutoCompleteControl extends AutoCompleteControl {
         }
 
         options.getMatches = text => {
-            const regex = new RegExp(
-                text.length < minLengthForPartialSearch ?
-                    '^' + lodash.escapeRegExp(text) :
-                    lodash.escapeRegExp(text),
-                caseSensitive ? '' : 'i');
+            const transform = caseSensitive ?
+                x => x :
+                x => x.toLowerCase();
+            const match = text.length < minLengthForPartialSearch ?
+                (a, b) => a.startsWith(b) :
+                (a, b) => a.includes(b);
+            text = transform(text);
             return Array.from(allTags.entries())
-                .filter(kv => kv[0].match(regex))
+                .filter(kv => match(transform(kv[0]), text))
                 .sort((kv1, kv2) => {
                     return kv2[1].usages - kv1[1].usages;
                 })
diff --git a/client/js/util/views.js b/client/js/util/views.js
index d432ee1f..2248b48b 100644
--- a/client/js/util/views.js
+++ b/client/js/util/views.js
@@ -243,7 +243,7 @@ function getTemplate(templatePath) {
         if (!ctx) {
             ctx = {};
         }
-        lodash.extend(ctx, {
+        Object.assign(ctx, {
             makeRelativeTime: makeRelativeTime,
             makeThumbnail: makeThumbnail,
             makeRadio: makeRadio,