Skip to content

Commit b6a01bd

Browse files
committed
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.
1 parent aaaad29 commit b6a01bd

5 files changed

Lines changed: 96 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# <angular/> 0.9.11 snow-maker (in-progress) #
22

3+
### Bug Fixes
4+
- <option> value attribute gets clobbered when the element contains new line character(s).
35

46

57
# <angular/> 0.9.10 flea-whisperer (2011-01-26) #

src/markups.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,18 @@ angularTextMarkup('{{}}', function(text, textNode, parentElement) {
6060
// TODO: this should be widget not a markup
6161
angularTextMarkup('OPTION', function(text, textNode, parentElement){
6262
if (nodeName_(parentElement) == "OPTION") {
63-
var select = document.createElement('select');
64-
select.insertBefore(parentElement[0].cloneNode(true), _null);
65-
if (!select.innerHTML.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) {
66-
parentElement.attr('value', text);
67-
}
63+
var select = jqLite('<select>');
64+
select.append(parentElement.clone());
65+
htmlParser(select.html(), {
66+
start: function(tag, attrs) {
67+
if (isUndefined(attrs.value)) {
68+
parentElement.attr('value', text);
69+
}
70+
},
71+
chars: noop,
72+
end: noop,
73+
comment: noop
74+
});
6875
}
6976
});
7077

src/sanitizer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616

1717
// Regular Expressions for parsing tags and attributes
18-
var START_TAG_REGEXP = /^<\s*([\w:]+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
19-
END_TAG_REGEXP = /^<\s*\/\s*([\w:]+)[^>]*>/,
20-
ATTR_REGEXP = /(\w+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
18+
var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
19+
END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
20+
ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
2121
BEGIN_TAG_REGEXP = /^</,
2222
BEGING_END_TAGE_REGEXP = /^<\s*\//,
2323
COMMENT_REGEXP = /<!--(.*?)-->/g,

test/markupSpec.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,39 @@ describe("markups", function(){
4141
expect(element.attr('src')).toEqual("http://server/a/b.png");
4242
});
4343

44-
it('should populate value attribute on OPTION', function(){
45-
compile('<select name="x"><option>a</option></select>');
46-
expect(sortedHtml(element).replace(' selected="true"', '')).toEqual('<select name="x"><option value="a">a</option></select>');
44+
describe('OPTION value', function(){
45+
beforeEach(function(){
46+
this.addMatchers({
47+
toHaveValue: function(expected){
48+
this.message = function(){
49+
return 'Expected "' + sortedHtml(this.actual) + '" to have value="' + expected + '".';
50+
};
51+
52+
return this.actual.html().indexOf('value="' + expected + '"') != -1;
53+
}
54+
});
55+
});
56+
57+
it('should populate value attribute on OPTION', function(){
58+
compile('<select name="x"><option>abc</option></select>');
59+
expect(element).toHaveValue('abc');
60+
});
61+
62+
it('should ignore value if already exists', function(){
63+
compile('<select name="x"><option value="abc">xyz</option></select>');
64+
expect(element).toHaveValue('abc');
65+
});
66+
67+
it('should set value even if newlines present', function(){
68+
compile('<select name="x"><option attr="\ntext\n" \n>\nabc\n</option></select>');
69+
expect(element).toHaveValue('\nabc\n');
70+
});
71+
72+
it('should set value even if self closing HTML', function(){
73+
compile('<select name="x"><option>\n</option></select>');
74+
expect(element).toHaveValue('\n');
75+
});
76+
4777
});
4878

4979
it('should bind href', function() {

test/sanitizerSpec.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,52 @@ describe('HTML', function(){
44
return expect(new HTML(html).get());
55
}
66

7+
describe('htmlParser', function(){
8+
var handler, start, text;
9+
beforeEach(function(){
10+
handler = {
11+
start: function(tag, attrs, unary){
12+
start = {
13+
tag: tag,
14+
attrs: attrs,
15+
unary: unary
16+
};
17+
},
18+
chars: function(text_){
19+
text = text_;
20+
},
21+
end:function(tag) {
22+
expect(tag).toEqual(start.tag);
23+
}
24+
};
25+
});
26+
27+
it('should parse basic format', function(){
28+
htmlParser('<tag attr="value">text</tag>', handler);
29+
expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false});
30+
expect(text).toEqual('text');
31+
});
32+
33+
it('should parse newlines in tags', function(){
34+
htmlParser('<\ntag\n attr="value"\n>text<\n/\ntag\n>', handler);
35+
expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false});
36+
expect(text).toEqual('text');
37+
});
38+
39+
it('should parse newlines in attributes', function(){
40+
htmlParser('<tag attr="\nvalue\n">text</tag>', handler);
41+
expect(start).toEqual({tag:'tag', attrs:{attr:'\nvalue\n'}, unary:false});
42+
expect(text).toEqual('text');
43+
});
44+
45+
it('should parse namespace', function(){
46+
htmlParser('<ns:t-a-g ns:a-t-t-r="\nvalue\n">text</ns:t-a-g>', handler);
47+
expect(start).toEqual({tag:'ns:t-a-g', attrs:{'ns:a-t-t-r':'\nvalue\n'}, unary:false});
48+
expect(text).toEqual('text');
49+
});
50+
51+
});
52+
753
it('should echo html', function(){
854
expectHTML('hello<b class="1\'23" align=\'""\'>world</b>.').
955
toEqual('hello<b class="1\'23" align="&#34;&#34;">world</b>.');

0 commit comments

Comments
 (0)