From 3680d959ddd64da3b39ed291812c2c339097871b Mon Sep 17 00:00:00 2001
From: epriestley <git@epriestley.com>
Date: Thu, 10 Dec 2015 17:36:07 -0800
Subject: [PATCH] Disable tokenizer "Browse" button once tokenizer is full

Summary: Ref T7858. Don't let users add multiple values to single-value tokenizers by using the "Browse" button.

Test Plan:
  - Added a token, browse button was disabled.
  - Removed the token, browse button was enabled again.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7858

Differential Revision: https://secure.phabricator.com/D14738
---
 resources/celerity/map.php                    | 18 +++++------
 .../lib/control/tokenizer/Tokenizer.js        | 30 ++++++++++++++++++-
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
index 199baa82e6..799cd3d0a5 100644
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -8,7 +8,7 @@
 return array(
   'names' => array(
     'core.pkg.css' => '6d8c526d',
-    'core.pkg.js' => '3c0f7f9b',
+    'core.pkg.js' => '46bc8dbd',
     'darkconsole.pkg.js' => 'e7393ebb',
     'differential.pkg.css' => '2de124c9',
     'differential.pkg.js' => '6223dd9d',
@@ -244,7 +244,7 @@ return array(
     'rsrc/externals/javelin/lib/__tests__/URI.js' => '1e45fda9',
     'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
     'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
-    'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'ab5f468d',
+    'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '9fef18a5',
     'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '70baed2f',
     'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'e6e25838',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
@@ -704,7 +704,7 @@ return array(
     'javelin-scrollbar' => '087e919c',
     'javelin-sound' => '949c0fe5',
     'javelin-stratcom' => '6c53634d',
-    'javelin-tokenizer' => 'ab5f468d',
+    'javelin-tokenizer' => '9fef18a5',
     'javelin-typeahead' => '70baed2f',
     'javelin-typeahead-composite-source' => '503e17fd',
     'javelin-typeahead-normalizer' => 'e6e25838',
@@ -1581,6 +1581,12 @@ return array(
       'javelin-dom',
       'javelin-vector',
     ),
+    '9fef18a5' => array(
+      'javelin-dom',
+      'javelin-util',
+      'javelin-stratcom',
+      'javelin-install',
+    ),
     'a0b57eb8' => array(
       'javelin-behavior',
       'javelin-dom',
@@ -1658,12 +1664,6 @@ return array(
       'javelin-util',
       'phabricator-prefab',
     ),
-    'ab5f468d' => array(
-      'javelin-dom',
-      'javelin-util',
-      'javelin-stratcom',
-      'javelin-install',
-    ),
     'ad10aeac' => array(
       'javelin-install',
       'javelin-util',
diff --git a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
index b626f9fc73..d0ba773790 100644
--- a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
+++ b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
@@ -313,7 +313,7 @@ JX.install('Tokenizer', {
 
       root.insertBefore(token, focus);
 
-      this.invoke('change', this);
+      this._didChangeValue();
 
       return true;
     },
@@ -419,7 +419,31 @@ JX.install('Tokenizer', {
       this._redraw(true);
       focus && this.focus();
 
+      this._didChangeValue();
+
+      return true;
+    },
+
+    _didChangeValue: function() {
+
+      if (this.getBrowseURI()) {
+        var button = JX.DOM.find(this._frame, 'a', 'tokenizer-browse');
+        JX.DOM.alterClass(button, 'disabled', !!this._isAtTokenLimit());
+      }
+
       this.invoke('change', this);
+    },
+
+    _isAtTokenLimit: function() {
+      var limit = this.getLimit();
+
+      if (!limit) {
+        return false;
+      }
+
+      if (limit > JX.keys(this.getTokens()).length) {
+        return false;
+      }
 
       return true;
     },
@@ -462,6 +486,10 @@ JX.install('Tokenizer', {
         return;
       }
 
+      if (this._isAtTokenLimit()) {
+        return;
+      }
+
       new JX.Workflow(uri, {exclude: JX.keys(this.getTokens()).join(',')})
         .setHandler(
           JX.bind(this, function(r) {