diff options
| author | Igor Minar | 2010-11-17 22:32:35 -0800 | 
|---|---|---|
| committer | Igor Minar | 2010-11-18 02:35:29 -0800 | 
| commit | 522ec1a9ec10e1fece3e5e855c1d7ef9770a8efc (patch) | |
| tree | c4ae99f716539745d45b55e09e1aa6537db372e1 /src | |
| parent | 9cb57772a4030925318475fe93bc19e2916b37bf (diff) | |
| download | angular.js-522ec1a9ec10e1fece3e5e855c1d7ef9770a8efc.tar.bz2 | |
move attribute widgets to widgets.js file
- move @ng:repeat to widgets.js and its specs to widgetsSpecs.js
- move @ng:non-bindable to widgets.js and its specs to widgetsSpecs.js
- make widget.template suitable for attribute widgets
- fix up the js docs for attribute widgets
Diffstat (limited to 'src')
| -rw-r--r-- | src/directives.js | 154 | ||||
| -rw-r--r-- | src/widgets.js | 160 | 
2 files changed, 158 insertions, 156 deletions
diff --git a/src/directives.js b/src/directives.js index 2958773d..d47d993d 100644 --- a/src/directives.js +++ b/src/directives.js @@ -378,160 +378,6 @@ angularDirective("ng:bind-attr", function(expression){    };  }); -/** - * @ngdoc directive - * @name angular.directive.ng:non-bindable - * - * @description - * Sometimes it is necessary to write code which looks like  - * bindings but which should be left alone by <angular/>.  - * Use `ng:non-bindable` to ignore a chunk of HTML. - *  - * @element ANY - * @param {string} ignore  - * - * @exampleDescription - * In this example there are two location where  - * <tt ng:non-bindable>{{1 + 2}}</tt> is present, but the one  - * wrapped in `ng:non-bindable` is left alone - * @example -    <div>Normal: {{1 + 2}}</div> -    <div ng:non-bindable>Ignored: {{1 + 2}}</div> - *  - * @scenario -   it('should check ng:non-bindable', function(){ -     expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); -     expect(using('.doc-example-live').element('div:last').text()). -       toMatch(/1 \+ 2/); -   }); - */ -angularWidget("@ng:non-bindable", noop); - -/** - * @ngdoc directive - * @name angular.directive.ng:repeat - * - * @description - * `ng:repeat` instantiates a template once per item from a  - * collection. The collection is enumerated with  - * `ng:repeat-index` attribute starting from 0. Each template  - * instance gets its own scope where the given loop variable  - * is set to the current collection item and `$index` is set  - * to the item index or key. - *  - * NOTE: `ng:repeat` looks like a directive, but is actually a  - * attribute widget. - *  - * @element ANY - * @param {repeat} repeat_expression to itterate over. - *  - *   * `variable in expression`, where variable is the user  - *     defined loop variable and expression is a scope expression  - *     giving the collection to enumerate. For example:  - *     `track in cd.tracks`. - *   * `(key, value) in expression`, where key and value can  - *     be any user defined identifiers, and expression is the  - *     scope expression giving the collection to enumerate.  - *     For example: `(name, age) in {'adam':10, 'amalie':12}`. - * - * Special properties set on the local scope: - *   * {number} $index - iterator offset of the repeated element (0..length-1) - *   * {string} $position - position of the repeated element in the iterator ('first', 'middle', 'last') - * - * @exampleDescription - * This example initializes the scope to a list of names and  - * than uses `ng:repeat` to display every person. - * @example -    <div ng:init="friends = [{name:'John', age:25}, {name:'Mary', age:28}]"> -      I have {{friends.length}} friends. They are: -      <ul> -        <li ng:repeat="friend in friends">  -          [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. -        </li> -      </ul> -    </div> - * @scenario -   it('should check ng:repeat', function(){ -     var r = using('.doc-example-live').repeater('ul li');  -     expect(r.count()).toBe(2); -     expect(r.row(0)).toEqual(["1","John","25"]); -     expect(r.row(1)).toEqual(["2","Mary","28"]); -   }); - */ -angularWidget("@ng:repeat", function(expression, element){ -  element.removeAttr('ng:repeat'); -  element.replaceWith(this.comment("ng:repeat: " + expression)); -  var template = this.compile(element); -  return function(reference){ -    var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/), -        lhs, rhs, valueIdent, keyIdent; -    if (! match) { -      throw Error("Expected ng:repeat in form of 'item in collection' but got '" + -      expression + "'."); -    } -    lhs = match[1]; -    rhs = match[2]; -    match = lhs.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/); -    if (!match) { -      throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '" + -      keyValue + "'."); -    } -    valueIdent = match[3] || match[1]; -    keyIdent = match[2]; - -    var children = [], currentScope = this; -    this.$onEval(function(){ -      var index = 0, -          childCount = children.length, -          lastElement = reference, -          collection = this.$tryEval(rhs, reference),  -          is_array = isArray(collection), -          collectionLength = 0, -          childScope, -          key; - -      if (is_array) { -        collectionLength = collection.length; -      } else { -        for (key in collection) -          if (collection.hasOwnProperty(key)) -            collectionLength++; -      } - -      for (key in collection) { -        if (!is_array || collection.hasOwnProperty(key)) { -          if (index < childCount) { -            // reuse existing child -            childScope = children[index]; -            childScope[valueIdent] = collection[key]; -            if (keyIdent) childScope[keyIdent] = key; -          } else { -            // grow children -            childScope = template(quickClone(element), createScope(currentScope)); -            childScope[valueIdent] = collection[key]; -            if (keyIdent) childScope[keyIdent] = key; -            lastElement.after(childScope.$element); -            childScope.$index = index; -            childScope.$position = index == 0 ? -                                      'first' : -                                      (index == collectionLength - 1 ? 'last' : 'middle'); -            childScope.$element.attr('ng:repeat-index', index); -            childScope.$init(); -            children.push(childScope); -          } -          childScope.$eval(); -          lastElement = childScope.$element; -          index ++; -        } -      } -      // shrink children -      while(children.length > index) { -        children.pop().$element.remove(); -      } -    }, reference); -  }; -}); -  /**   * @ngdoc directive diff --git a/src/widgets.js b/src/widgets.js index 887b31ac..930a6788 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -691,7 +691,7 @@ var ngSwitch = angularWidget('ng:switch', function (element){   * changing the location or causing page reloads, e.g.:   * <a href="" ng:click="model.$save()">Save</a>   */ -angular.widget('a', function() { +angularWidget('a', function() {    this.descend(true);    this.directives(true); @@ -702,4 +702,160 @@ angular.widget('a', function() {        });      }    }; -});
\ No newline at end of file +}); + + +/** + * @ngdoc widget + * @name angular.widget.@ng:repeat + * + * @description + * `ng:repeat` instantiates a template once per item from a collection. The collection is enumerated + * with `ng:repeat-index` attribute starting from 0. Each template instance gets its own scope where + * the given loop variable is set to the current collection item and `$index` is set to the item + * index or key. + * + * There are special properties exposed on the local scope of each template instance: + * + *   * `$index` – `{number}` – iterator offset of the repeated element (0..length-1) + *   * `$position` – {string} – position of the repeated element in the iterator. One of: `'first'`, + *     `'middle'` or `'last'`. + * + * NOTE: `ng:repeat` looks like a directive, but is actually an attribute widget. + * + * @element ANY + * @param {string} repeat_expression The expression indicating how to enumerate a collection. Two + *   formats are currently supported: + * + *   * `variable in expression` – where variable is the user defined loop variable and `expression` + *     is a scope expression giving the collection to enumerate. + * + *     For example: `track in cd.tracks`. + *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers, + *     and `expression` is the scope expression giving the collection to enumerate. + * + *     For example: `(name, age) in {'adam':10, 'amalie':12}`. + * + * @exampleDescription + * This example initializes the scope to a list of names and + * than uses `ng:repeat` to display every person. + * @example +    <div ng:init="friends = [{name:'John', age:25}, {name:'Mary', age:28}]"> +      I have {{friends.length}} friends. They are: +      <ul> +        <li ng:repeat="friend in friends"> +          [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. +        </li> +      </ul> +    </div> + * @scenario +   it('should check ng:repeat', function(){ +     var r = using('.doc-example-live').repeater('ul li'); +     expect(r.count()).toBe(2); +     expect(r.row(0)).toEqual(["1","John","25"]); +     expect(r.row(1)).toEqual(["2","Mary","28"]); +   }); + */ +angularWidget("@ng:repeat", function(expression, element){ +  element.removeAttr('ng:repeat'); +  element.replaceWith(this.comment("ng:repeat: " + expression)); +  var template = this.compile(element); +  return function(reference){ +    var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/), +        lhs, rhs, valueIdent, keyIdent; +    if (! match) { +      throw Error("Expected ng:repeat in form of 'item in collection' but got '" + +      expression + "'."); +    } +    lhs = match[1]; +    rhs = match[2]; +    match = lhs.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/); +    if (!match) { +      throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '" + +      keyValue + "'."); +    } +    valueIdent = match[3] || match[1]; +    keyIdent = match[2]; + +    var children = [], currentScope = this; +    this.$onEval(function(){ +      var index = 0, +          childCount = children.length, +          lastElement = reference, +          collection = this.$tryEval(rhs, reference), +          is_array = isArray(collection), +          collectionLength = 0, +          childScope, +          key; + +      if (is_array) { +        collectionLength = collection.length; +      } else { +        for (key in collection) +          if (collection.hasOwnProperty(key)) +            collectionLength++; +      } + +      for (key in collection) { +        if (!is_array || collection.hasOwnProperty(key)) { +          if (index < childCount) { +            // reuse existing child +            childScope = children[index]; +            childScope[valueIdent] = collection[key]; +            if (keyIdent) childScope[keyIdent] = key; +          } else { +            // grow children +            childScope = template(quickClone(element), createScope(currentScope)); +            childScope[valueIdent] = collection[key]; +            if (keyIdent) childScope[keyIdent] = key; +            lastElement.after(childScope.$element); +            childScope.$index = index; +            childScope.$position = index == 0 ? +                                      'first' : +                                      (index == collectionLength - 1 ? 'last' : 'middle'); +            childScope.$element.attr('ng:repeat-index', index); +            childScope.$init(); +            children.push(childScope); +          } +          childScope.$eval(); +          lastElement = childScope.$element; +          index ++; +        } +      } +      // shrink children +      while(children.length > index) { +        children.pop().$element.remove(); +      } +    }, reference); +  }; +}); + + +/** + * @ngdoc widget + * @name angular.widget.@ng:non-bindable + * + * @description + * Sometimes it is necessary to write code which looks like bindings but which should be left alone + * by angular. Use `ng:non-bindable` to make angular ignore a chunk of HTML. + * + * NOTE: `ng:non-bindable` looks like a directive, but is actually an attribute widget. + * + * @element ANY + * + * @exampleDescription + * In this example there are two location where a siple binding (`{{}}`) is present, but the one + * wrapped in `ng:non-bindable` is left alone. + * + * @example +    <div>Normal: {{1 + 2}}</div> +    <div ng:non-bindable>Ignored: {{1 + 2}}</div> + * + * @scenario +   it('should check ng:non-bindable', function(){ +     expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); +     expect(using('.doc-example-live').element('div:last').text()). +       toMatch(/1 \+ 2/); +   }); + */ +angularWidget("@ng:non-bindable", noop);  | 
