From 9ee2cdff44e7d496774b340de816344126c457b3 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 22 Nov 2011 21:28:39 -0800
Subject: refactor(directives): connect new compiler
- turn everything into a directive
---
 src/widget/select.js | 554 ++++++++++++++++++++++++++-------------------------
 1 file changed, 284 insertions(+), 270 deletions(-)
(limited to 'src/widget/select.js')
diff --git a/src/widget/select.js b/src/widget/select.js
index a3633ddd..ae9e1b7c 100644
--- a/src/widget/select.js
+++ b/src/widget/select.js
@@ -112,321 +112,335 @@
       
       
          it('should check ng:options', function() {
-           expect(binding('color')).toMatch('red');
+           expect(binding('{selected_color:color}')).toMatch('red');
            select('color').option('0');
-           expect(binding('color')).toMatch('black');
+           expect(binding('{selected_color:color}')).toMatch('black');
            using('.nullable').select('color').option('');
-           expect(binding('color')).toMatch('null');
+           expect(binding('{selected_color:color}')).toMatch('null');
          });
       
     
  */
 
-
-                       //00001111100000000000222200000000000000000000003333000000000000044444444444444444000000000555555555555555550000000666666666666666660000000000000007777
-var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/;
-
-
-angularWidget('select', function(element){
-  this.directives(true);
-  this.descend(true);
-  return element.attr('ng:model') &&
-               ['$formFactory', '$compile', '$parse', '$element',
-        function($formFactory,   $compile,   $parse,   selectElement){
-    var modelScope = this,
-        match,
-        form = $formFactory.forElement(selectElement),
-        multiple = selectElement.attr('multiple'),
-        optionsExp = selectElement.attr('ng:options'),
-        modelExp = selectElement.attr('ng:model'),
-        widget = form.$createWidget({
-          scope: modelScope,
-          model: modelExp,
-          onChange: selectElement.attr('ng:change'),
-          alias: selectElement.attr('name'),
-          controller: ['$scope', optionsExp ? Options : (multiple ? Multiple : Single)]});
-
-    selectElement.bind('$destroy', function() { widget.$destroy(); });
-
-    widget.$pristine = !(widget.$dirty = false);
-
-    watchElementProperty(modelScope, widget, 'required', selectElement);
-    watchElementProperty(modelScope, widget, 'readonly', selectElement);
-    watchElementProperty(modelScope, widget, 'disabled', selectElement);
-
-    widget.$on('$validate', function() {
-      var valid = !widget.$required || !!widget.$modelValue;
-      if (valid && multiple && widget.$required) valid = !!widget.$modelValue.length;
-      if (valid !== !widget.$error.REQUIRED) {
-        widget.$emit(valid ? '$valid' : '$invalid', 'REQUIRED');
-      }
-    });
-
-    widget.$on('$viewChange', function() {
-      widget.$pristine = !(widget.$dirty = true);
-    });
-
-    forEach(['valid', 'invalid', 'pristine', 'dirty'], function(name) {
-      widget.$watch('$' + name, function(value) {
-        selectElement[value ? 'addClass' : 'removeClass']('ng-' + name);
+var ngOptionsDirective = valueFn({ terminal: true });
+var selectDirective = ['$formFactory', '$compile', '$parse',
+               function($formFactory,   $compile,   $parse){
+                         //00001111100000000000222200000000000000000000003333000000000000044444444444444444000000000555555555555555550000000666666666666666660000000000000007777
+  var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/;
+
+  return {
+    restrict: 'E',
+    link: function(modelScope, selectElement, attr) {
+      if (!attr.ngModel) return;
+      var form = $formFactory.forElement(selectElement),
+          multiple = attr.multiple,
+          optionsExp = attr.ngOptions,
+          modelExp = attr.ngModel,
+          widget = form.$createWidget({
+            scope: modelScope,
+            model: modelExp,
+            onChange: attr.ngChange,
+            alias: attr.name,
+            controller: ['$scope', optionsExp ? Options : (multiple ? Multiple : Single)]});
+
+      selectElement.bind('$destroy', function() { widget.$destroy(); });
+
+      widget.$pristine = !(widget.$dirty = false);
+
+      widget.$on('$validate', function() {
+        var valid = !attr.required || !!widget.$modelValue;
+        if (valid && multiple && attr.required) valid = !!widget.$modelValue.length;
+        if (valid !== !widget.$error.REQUIRED) {
+          widget.$emit(valid ? '$valid' : '$invalid', 'REQUIRED');
+        }
       });
-    });
 
-    ////////////////////////////
+      widget.$on('$viewChange', function() {
+        widget.$pristine = !(widget.$dirty = true);
+      });
 
-    function Multiple(widget) {
-      widget.$render = function() {
-        var items = new HashMap(widget.$viewValue);
-        forEach(selectElement.children(), function(option){
-          option.selected = isDefined(items.get(option.value));
+      forEach(['valid', 'invalid', 'pristine', 'dirty'], function(name) {
+        widget.$watch('$' + name, function(value) {
+          selectElement[value ? 'addClass' : 'removeClass']('ng-' + name);
         });
-      };
+      });
+
+      ////////////////////////////
 
-      selectElement.bind('change', function() {
-        widget.$apply(function() {
-          var array = [];
+      function Multiple(widget) {
+        widget.$render = function() {
+          var items = new HashMap(this.$viewValue);
           forEach(selectElement.children(), function(option){
-            if (option.selected) {
-              array.push(option.value);
-            }
+            option.selected = isDefined(items.get(option.value));
+          });
+        };
+
+        selectElement.bind('change', function() {
+          widget.$apply(function() {
+            var array = [];
+            forEach(selectElement.children(), function(option){
+              if (option.selected) {
+                array.push(option.value);
+              }
+            });
+            widget.$emit('$viewChange', array);
           });
-          widget.$emit('$viewChange', array);
         });
-      });
 
-    }
+      }
 
-    function Single(widget) {
-      widget.$render = function() {
-        selectElement.val(widget.$viewValue);
-      };
+      function Single(widget) {
+        widget.$render = function() {
+          selectElement.val(widget.$viewValue);
+        };
 
-      selectElement.bind('change', function() {
-        widget.$apply(function() {
-          widget.$emit('$viewChange', selectElement.val());
+        selectElement.bind('change', function() {
+          widget.$apply(function() {
+            widget.$emit('$viewChange', selectElement.val());
+          });
         });
-      });
-
-      widget.$viewValue = selectElement.val();
-    }
-
-    function Options(widget) {
-      var match;
 
-      if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
-        throw Error(
-          "Expected ng:options in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" +
-          " but got '" + optionsExp + "'.");
+        widget.$viewValue = selectElement.val();
       }
 
-      var displayFn = $parse(match[2] || match[1]),
-          valueName = match[4] || match[6],
-          keyName = match[5],
-          groupByFn = $parse(match[3] || ''),
-          valueFn = $parse(match[2] ? match[1] : valueName),
-          valuesFn = $parse(match[7]),
-          // we can't just jqLite('