| 
									
										
										
										
											2011-07-15 22:30:55 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @provides phabricator-prefab | 
					
						
							|  |  |  |  * @requires javelin-install | 
					
						
							|  |  |  |  *           javelin-util | 
					
						
							|  |  |  |  *           javelin-dom | 
					
						
							| 
									
										
										
											
												Use Javelin placeholders and new sorting rules broadly; consolidate tokenizer construction code
Summary:
  - We have three nearly-identical blocks of Tokenizer construction code; consolidate them into Prefab.
  - Add placeholder support.
  - Augment server-side stuff to specify placeholder text.
Test Plan: Verified behavior of Differential edit tokenizers, Differential comment tokenizers, Maniphest edit tokenizers, Maniphest comment tokenizers, Maniphest filter tokenizers, Differential filter tokenizers, Owners filter tokenizers, Owners edit tokenizers, Herald edit tokenizers, Audit filter tokenizers.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, epriestley
Maniphest Tasks: T772, T946
Differential Revision: https://secure.phabricator.com/D1844
											
										 
											2012-03-09 15:46:39 -08:00
										 |  |  |  *           javelin-typeahead | 
					
						
							|  |  |  |  *           javelin-tokenizer | 
					
						
							|  |  |  |  *           javelin-typeahead-preloaded-source | 
					
						
							|  |  |  |  *           javelin-typeahead-ondemand-source | 
					
						
							|  |  |  |  *           javelin-dom | 
					
						
							|  |  |  |  *           javelin-stratcom | 
					
						
							|  |  |  |  *           javelin-util | 
					
						
							| 
									
										
										
										
											2011-07-15 22:30:55 -07:00
										 |  |  |  * @javelin | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Utilities for client-side rendering (the greatest thing in the world). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | JX.install('Prefab', { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   statics : { | 
					
						
							|  |  |  |     renderSelect : function(map, selected, attrs) { | 
					
						
							|  |  |  |       var select = JX.$N('select', attrs || {}); | 
					
						
							|  |  |  |       for (var k in map) { | 
					
						
							|  |  |  |         select.options[select.options.length] = new Option(map[k], k); | 
					
						
							|  |  |  |         if (k == selected) { | 
					
						
							|  |  |  |           select.value = k; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       select.value = select.value || JX.keys(map)[0]; | 
					
						
							|  |  |  |       return select; | 
					
						
							| 
									
										
										
											
												Use Javelin placeholders and new sorting rules broadly; consolidate tokenizer construction code
Summary:
  - We have three nearly-identical blocks of Tokenizer construction code; consolidate them into Prefab.
  - Add placeholder support.
  - Augment server-side stuff to specify placeholder text.
Test Plan: Verified behavior of Differential edit tokenizers, Differential comment tokenizers, Maniphest edit tokenizers, Maniphest comment tokenizers, Maniphest filter tokenizers, Differential filter tokenizers, Owners filter tokenizers, Owners edit tokenizers, Herald edit tokenizers, Audit filter tokenizers.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, epriestley
Maniphest Tasks: T772, T946
Differential Revision: https://secure.phabricator.com/D1844
											
										 
											2012-03-09 15:46:39 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Build a Phabricator tokenizer out of a configuration with application | 
					
						
							|  |  |  |      * sorting, datasource and placeholder rules. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2012-03-21 14:01:04 -07:00
										 |  |  |      *   - `id` Root tokenizer ID (alternatively, pass `root`). | 
					
						
							|  |  |  |      *   - `root` Root tokenizer node (replaces `id`). | 
					
						
							| 
									
										
										
											
												Use Javelin placeholders and new sorting rules broadly; consolidate tokenizer construction code
Summary:
  - We have three nearly-identical blocks of Tokenizer construction code; consolidate them into Prefab.
  - Add placeholder support.
  - Augment server-side stuff to specify placeholder text.
Test Plan: Verified behavior of Differential edit tokenizers, Differential comment tokenizers, Maniphest edit tokenizers, Maniphest comment tokenizers, Maniphest filter tokenizers, Differential filter tokenizers, Owners filter tokenizers, Owners edit tokenizers, Herald edit tokenizers, Audit filter tokenizers.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, epriestley
Maniphest Tasks: T772, T946
Differential Revision: https://secure.phabricator.com/D1844
											
										 
											2012-03-09 15:46:39 -08:00
										 |  |  |      *   - `src` Datasource URI. | 
					
						
							|  |  |  |      *   - `ondemand` Optional, use an ondemand source. | 
					
						
							|  |  |  |      *   - `value` Optional, initial value. | 
					
						
							|  |  |  |      *   - `limit` Optional, token limit. | 
					
						
							|  |  |  |      *   - `placeholder` Optional, placeholder text. | 
					
						
							|  |  |  |      *   - `username` Optional, username to sort first (i.e., viewer). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     buildTokenizer : function(config) { | 
					
						
							| 
									
										
										
										
											2013-04-08 13:42:45 -07:00
										 |  |  |       try { | 
					
						
							|  |  |  |         var root = config.root || JX.$(config.id); | 
					
						
							|  |  |  |       } catch (ex) { | 
					
						
							|  |  |  |         // If the root element does not exist, just return without building
 | 
					
						
							|  |  |  |         // anything. This happens in some cases -- like Conpherence -- where we
 | 
					
						
							|  |  |  |         // may load a tokenizer but not put it in the document.
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
											
												Use Javelin placeholders and new sorting rules broadly; consolidate tokenizer construction code
Summary:
  - We have three nearly-identical blocks of Tokenizer construction code; consolidate them into Prefab.
  - Add placeholder support.
  - Augment server-side stuff to specify placeholder text.
Test Plan: Verified behavior of Differential edit tokenizers, Differential comment tokenizers, Maniphest edit tokenizers, Maniphest comment tokenizers, Maniphest filter tokenizers, Differential filter tokenizers, Owners filter tokenizers, Owners edit tokenizers, Herald edit tokenizers, Audit filter tokenizers.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, epriestley
Maniphest Tasks: T772, T946
Differential Revision: https://secure.phabricator.com/D1844
											
										 
											2012-03-09 15:46:39 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var datasource; | 
					
						
							|  |  |  |       if (config.ondemand) { | 
					
						
							|  |  |  |         datasource = new JX.TypeaheadOnDemandSource(config.src); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         datasource = new JX.TypeaheadPreloadedSource(config.src); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Sort results so that the viewing user always comes up first; after
 | 
					
						
							|  |  |  |       // that, prefer unixname matches to realname matches.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var sort_handler = function(value, list, cmp) { | 
					
						
							|  |  |  |         var priority_hits = {}; | 
					
						
							|  |  |  |         var self_hits     = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var tokens = this.tokenize(value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (var ii = 0; ii < list.length; ii++) { | 
					
						
							|  |  |  |           var item = list[ii]; | 
					
						
							|  |  |  |           if (!item.priority) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (config.username && item.priority == config.username) { | 
					
						
							|  |  |  |             self_hits[item.id] = true; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           for (var jj = 0; jj < tokens.length; jj++) { | 
					
						
							|  |  |  |             if (item.priority.substr(0, tokens[jj].length) == tokens[jj]) { | 
					
						
							|  |  |  |               priority_hits[item.id] = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         list.sort(function(u, v) { | 
					
						
							|  |  |  |           if (self_hits[u.id] != self_hits[v.id]) { | 
					
						
							|  |  |  |             return self_hits[v.id] ? 1 : -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (priority_hits[u.id] != priority_hits[v.id]) { | 
					
						
							|  |  |  |             return priority_hits[v.id] ? 1 : -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return cmp(u, v); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       datasource.setSortHandler(JX.bind(datasource, sort_handler)); | 
					
						
							|  |  |  |       datasource.setTransformer( | 
					
						
							|  |  |  |         function(object) { | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             name: object[0], | 
					
						
							|  |  |  |             display: object[0], | 
					
						
							|  |  |  |             uri: object[1], | 
					
						
							|  |  |  |             id: object[2], | 
					
						
							|  |  |  |             priority: object[3] | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var typeahead = new JX.Typeahead( | 
					
						
							|  |  |  |         root, | 
					
						
							|  |  |  |         JX.DOM.find(root, 'input', 'tokenizer-input')); | 
					
						
							|  |  |  |       typeahead.setDatasource(datasource); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var tokenizer = new JX.Tokenizer(root); | 
					
						
							|  |  |  |       tokenizer.setTypeahead(typeahead); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (config.placeholder) { | 
					
						
							|  |  |  |         tokenizer.setPlaceholder(config.placeholder); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (config.limit) { | 
					
						
							|  |  |  |         tokenizer.setLimit(config.limit); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (config.value) { | 
					
						
							|  |  |  |         tokenizer.setInitialValue(config.value); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       JX.Stratcom.addData(root, {'tokenizer' : tokenizer}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         tokenizer: tokenizer | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2011-07-15 22:30:55 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); |