aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2011-02-03 12:25:51 -0800
committerMisko Hevery2011-02-03 13:25:01 -0800
commitb6a01bd27dbcd2f9c9df917ecc96b8a2bd88413d (patch)
tree9ae08321a3741520014eac4d751a23ac39ab5f7e
parentaaaad298ac6447497b1b86edac5b0d9b092625a2 (diff)
downloadangular.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.md2
-rw-r--r--src/markups.js17
-rw-r--r--src/sanitizer.js6
-rw-r--r--test/markupSpec.js36
-rw-r--r--test/sanitizerSpec.js46
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="&#34;&#34;">world</b>.');