diff options
| author | Misko Hevery | 2011-02-03 12:25:51 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2011-02-03 13:25:01 -0800 | 
| commit | b6a01bd27dbcd2f9c9df917ecc96b8a2bd88413d (patch) | |
| tree | 9ae08321a3741520014eac4d751a23ac39ab5f7e | |
| parent | aaaad298ac6447497b1b86edac5b0d9b092625a2 (diff) | |
| download | angular.js-b6a01bd27dbcd2f9c9df917ecc96b8a2bd88413d.tar.bz2 | |
fixed population of value attribute on option
The value attribute must be populated manually, since different
browsers default to different value of option when not explicitly
defined.
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | src/markups.js | 17 | ||||
| -rw-r--r-- | src/sanitizer.js | 6 | ||||
| -rw-r--r-- | test/markupSpec.js | 36 | ||||
| -rw-r--r-- | test/sanitizerSpec.js | 46 | 
5 files changed, 96 insertions, 11 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6ca359..5a4b4e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@  # <angular/> 0.9.11 snow-maker  (in-progress) # +### Bug Fixes +- <option> value attribute gets clobbered when the element contains new line character(s).  # <angular/> 0.9.10 flea-whisperer  (2011-01-26) # diff --git a/src/markups.js b/src/markups.js index 21dab128..0aa7170e 100644 --- a/src/markups.js +++ b/src/markups.js @@ -60,11 +60,18 @@ angularTextMarkup('{{}}', function(text, textNode, parentElement) {  // TODO: this should be widget not a markup  angularTextMarkup('OPTION', function(text, textNode, parentElement){    if (nodeName_(parentElement) == "OPTION") { -    var select = document.createElement('select'); -    select.insertBefore(parentElement[0].cloneNode(true), _null); -    if (!select.innerHTML.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) { -      parentElement.attr('value', text); -    } +    var select = jqLite('<select>'); +    select.append(parentElement.clone()); +    htmlParser(select.html(), { +      start: function(tag, attrs) { +        if (isUndefined(attrs.value)) { +          parentElement.attr('value', text); +        } +      }, +      chars: noop, +      end: noop, +      comment: noop +    });    }  }); diff --git a/src/sanitizer.js b/src/sanitizer.js index c8a7b9f1..8f4b87a6 100644 --- a/src/sanitizer.js +++ b/src/sanitizer.js @@ -15,9 +15,9 @@   */  // Regular Expressions for parsing tags and attributes -var START_TAG_REGEXP = /^<\s*([\w:]+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, -  END_TAG_REGEXP = /^<\s*\/\s*([\w:]+)[^>]*>/, -  ATTR_REGEXP = /(\w+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, +var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, +  END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/, +  ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,    BEGIN_TAG_REGEXP = /^</,    BEGING_END_TAGE_REGEXP = /^<\s*\//,    COMMENT_REGEXP = /<!--(.*?)-->/g, diff --git a/test/markupSpec.js b/test/markupSpec.js index f78112d7..f629378d 100644 --- a/test/markupSpec.js +++ b/test/markupSpec.js @@ -41,9 +41,39 @@ describe("markups", function(){      expect(element.attr('src')).toEqual("http://server/a/b.png");    }); -  it('should populate value attribute on OPTION', function(){ -    compile('<select name="x"><option>a</option></select>'); -    expect(sortedHtml(element).replace(' selected="true"', '')).toEqual('<select name="x"><option value="a">a</option></select>'); +  describe('OPTION value', function(){ +    beforeEach(function(){ +      this.addMatchers({ +        toHaveValue: function(expected){ +          this.message = function(){ +            return 'Expected "' + sortedHtml(this.actual) + '" to have value="' + expected + '".'; +          }; + +          return this.actual.html().indexOf('value="' + expected + '"') != -1; +        } +      }); +    }); + +    it('should populate value attribute on OPTION', function(){ +      compile('<select name="x"><option>abc</option></select>'); +      expect(element).toHaveValue('abc'); +    }); + +    it('should ignore value if already exists', function(){ +      compile('<select name="x"><option value="abc">xyz</option></select>'); +      expect(element).toHaveValue('abc'); +    }); + +    it('should set value even if newlines present', function(){ +      compile('<select name="x"><option attr="\ntext\n" \n>\nabc\n</option></select>'); +      expect(element).toHaveValue('\nabc\n'); +    }); + +    it('should set value even if self closing HTML', function(){ +      compile('<select name="x"><option>\n</option></select>'); +      expect(element).toHaveValue('\n'); +    }); +    });    it('should bind href', function() { diff --git a/test/sanitizerSpec.js b/test/sanitizerSpec.js index 57eedec9..7158fbee 100644 --- a/test/sanitizerSpec.js +++ b/test/sanitizerSpec.js @@ -4,6 +4,52 @@ describe('HTML', function(){      return expect(new HTML(html).get());    } +  describe('htmlParser', function(){ +    var handler, start, text; +    beforeEach(function(){ +      handler = { +          start: function(tag, attrs, unary){ +            start = { +                tag: tag, +                attrs: attrs, +                unary: unary +            }; +          }, +          chars: function(text_){ +            text = text_; +          }, +          end:function(tag) { +            expect(tag).toEqual(start.tag); +          } +      }; +    }); + +    it('should parse basic format', function(){ +      htmlParser('<tag attr="value">text</tag>', handler); +      expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false}); +      expect(text).toEqual('text'); +    }); + +    it('should parse newlines in tags', function(){ +      htmlParser('<\ntag\n attr="value"\n>text<\n/\ntag\n>', handler); +      expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false}); +      expect(text).toEqual('text'); +    }); + +    it('should parse newlines in attributes', function(){ +      htmlParser('<tag attr="\nvalue\n">text</tag>', handler); +      expect(start).toEqual({tag:'tag', attrs:{attr:'\nvalue\n'}, unary:false}); +      expect(text).toEqual('text'); +    }); + +    it('should parse namespace', function(){ +      htmlParser('<ns:t-a-g ns:a-t-t-r="\nvalue\n">text</ns:t-a-g>', handler); +      expect(start).toEqual({tag:'ns:t-a-g', attrs:{'ns:a-t-t-r':'\nvalue\n'}, unary:false}); +      expect(text).toEqual('text'); +    }); + +  }); +    it('should echo html', function(){      expectHTML('hello<b class="1\'23" align=\'""\'>world</b>.').         toEqual('hello<b class="1\'23" align="""">world</b>.'); | 
