Merge pull request #89 from harvesthq/use_innerhtml_for_proper_escaping

Use innerhtml instead of text for definitive text
abstract-chosen
Patrick Filler 2011-07-28 08:44:34 -07:00
commit cbd29bf0d8
6 changed files with 58 additions and 50 deletions

View File

@ -256,7 +256,7 @@
if (option.group_array_index != null) { if (option.group_array_index != null) {
classes.push("group-option"); classes.push("group-option");
} }
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + $("<div />").text(option.text).html() + '</li>'; return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>';
} else { } else {
return ""; return "";
} }
@ -377,7 +377,7 @@
var choice_id, link; var choice_id, link;
choice_id = this.container_id + "_c_" + item.array_index; choice_id = this.container_id + "_c_" + item.array_index;
this.choices += 1; this.choices += 1;
this.search_container.before('<li class="search-choice" id="' + choice_id + '"><span>' + item.text + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>'); this.search_container.before('<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>');
link = $('#' + choice_id).find("a").first(); link = $('#' + choice_id).find("a").first();
return link.click(__bind(function(evt) { return link.click(__bind(function(evt) {
return this.choice_destroy_link_click(evt); return this.choice_destroy_link_click(evt);
@ -454,7 +454,7 @@
startTime = new Date(); startTime = new Date();
this.no_results_clear(); this.no_results_clear();
results = 0; results = 0;
searchText = this.search_field.val() === this.default_text ? "" : $.trim(this.search_field.val()); searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
_ref = this.results_data; _ref = this.results_data;
@ -466,11 +466,11 @@
} else if (!(this.is_multiple && option.selected)) { } else if (!(this.is_multiple && option.selected)) {
found = false; found = false;
result_id = option.dom_id; result_id = option.dom_id;
if (regex.test(option.text)) { if (regex.test(option.html)) {
found = true; found = true;
results += 1; results += 1;
} else if (option.text.indexOf(" ") >= 0 || option.text.indexOf("[") === 0) { } else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) {
parts = option.text.replace(/\[|\]/g, "").split(" "); parts = option.html.replace(/\[|\]/g, "").split(" ");
if (parts.length) { if (parts.length) {
for (_j = 0, _len2 = parts.length; _j < _len2; _j++) { for (_j = 0, _len2 = parts.length; _j < _len2; _j++) {
part = parts[_j]; part = parts[_j];
@ -483,11 +483,11 @@
} }
if (found) { if (found) {
if (searchText.length) { if (searchText.length) {
startpos = option.text.search(zregex); startpos = option.html.search(zregex);
text = option.text.substr(0, startpos + searchText.length) + '</em>' + option.text.substr(startpos + searchText.length); text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length);
text = text.substr(0, startpos) + '<em>' + text.substr(startpos); text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
} else { } else {
text = option.text; text = option.html;
} }
if ($("#" + result_id).html !== text) { if ($("#" + result_id).html !== text) {
$("#" + result_id).html(text); $("#" + result_id).html(text);
@ -535,7 +535,7 @@
Chosen.prototype.no_results = function(terms) { Chosen.prototype.no_results = function(terms) {
var no_results_html; var no_results_html;
no_results_html = $('<li class="no-results">No results match "<span></span>"</li>'); no_results_html = $('<li class="no-results">No results match "<span></span>"</li>');
no_results_html.find("span").first().text(terms); no_results_html.find("span").first().html(terms);
return this.search_results.append(no_results_html); return this.search_results.append(no_results_html);
}; };
Chosen.prototype.no_results_clear = function() { Chosen.prototype.no_results_clear = function() {
@ -746,6 +746,7 @@
options_index: this.options_index, options_index: this.options_index,
value: option.value, value: option.value,
text: option.text, text: option.text,
html: option.innerHTML,
selected: option.selected, selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled, disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position group_array_index: group_position

File diff suppressed because one or more lines are too long

View File

@ -216,7 +216,7 @@
if (data.selected && this.is_multiple) { if (data.selected && this.is_multiple) {
this.choice_build(data); this.choice_build(data);
} else if (data.selected && !this.is_multiple) { } else if (data.selected && !this.is_multiple) {
this.selected_item.down("span").update(data.text); this.selected_item.down("span").update(data.html);
} }
} }
} }
@ -244,7 +244,7 @@
if (option.group_array_index != null) { if (option.group_array_index != null) {
classes.push("group-option"); classes.push("group-option");
} }
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.text.escapeHTML() + '</li>'; return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>';
} else { } else {
return ""; return "";
} }
@ -365,9 +365,9 @@
this.choices += 1; this.choices += 1;
this.search_container.insert({ this.search_container.insert({
before: this.choice_temp.evaluate({ before: this.choice_temp.evaluate({
"id": choice_id, id: choice_id,
"choice": item.text, choice: item.html,
"position": item.array_index position: item.array_index
}) })
}); });
link = $(choice_id).down('a'); link = $(choice_id).down('a');
@ -407,7 +407,7 @@
if (this.is_multiple) { if (this.is_multiple) {
this.choice_build(item); this.choice_build(item);
} else { } else {
this.selected_item.down("span").update(item.text); this.selected_item.down("span").update(item.html);
} }
this.results_hide(); this.results_hide();
this.search_field.value = ""; this.search_field.value = "";
@ -449,7 +449,7 @@
startTime = new Date(); startTime = new Date();
this.no_results_clear(); this.no_results_clear();
results = 0; results = 0;
searchText = this.search_field.value === this.default_text ? "" : this.search_field.value.strip(); searchText = this.search_field.value === this.default_text ? "" : this.search_field.value.strip().escapeHTML();
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
_ref = this.results_data; _ref = this.results_data;
@ -461,11 +461,11 @@
} else if (!(this.is_multiple && option.selected)) { } else if (!(this.is_multiple && option.selected)) {
found = false; found = false;
result_id = option.dom_id; result_id = option.dom_id;
if (regex.test(option.text)) { if (regex.test(option.html)) {
found = true; found = true;
results += 1; results += 1;
} else if (option.text.indexOf(" ") >= 0 || option.text.indexOf("[") === 0) { } else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) {
parts = option.text.replace(/\[|\]/g, "").split(" "); parts = option.html.replace(/\[|\]/g, "").split(" ");
if (parts.length) { if (parts.length) {
for (_j = 0, _len2 = parts.length; _j < _len2; _j++) { for (_j = 0, _len2 = parts.length; _j < _len2; _j++) {
part = parts[_j]; part = parts[_j];
@ -478,11 +478,11 @@
} }
if (found) { if (found) {
if (searchText.length) { if (searchText.length) {
startpos = option.text.search(zregex); startpos = option.html.search(zregex);
text = option.text.substr(0, startpos + searchText.length) + '</em>' + option.text.substr(startpos + searchText.length); text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length);
text = text.substr(0, startpos) + '<em>' + text.substr(startpos); text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
} else { } else {
text = option.text; text = option.html;
} }
if ($(result_id).innerHTML !== text) { if ($(result_id).innerHTML !== text) {
$(result_id).update(text); $(result_id).update(text);
@ -528,7 +528,7 @@
}; };
Chosen.prototype.no_results = function(terms) { Chosen.prototype.no_results = function(terms) {
return this.search_results.insert(this.no_results_temp.evaluate({ return this.search_results.insert(this.no_results_temp.evaluate({
"terms": terms.escapeHTML() terms: terms
})); }));
}; };
Chosen.prototype.no_results_clear = function() { Chosen.prototype.no_results_clear = function() {
@ -658,7 +658,7 @@
} }
div = new Element('div', { div = new Element('div', {
'style': style_block 'style': style_block
}).update(this.search_field.value); }).update(this.search_field.value.escapeHTML());
document.body.appendChild(div); document.body.appendChild(div);
w = Element.measure(div, 'width') + 25; w = Element.measure(div, 'width') + 25;
div.remove(); div.remove();
@ -735,6 +735,7 @@
options_index: this.options_index, options_index: this.options_index,
value: option.value, value: option.value,
text: option.text, text: option.text,
html: option.innerHTML,
selected: option.selected, selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled, disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position group_array_index: group_position

File diff suppressed because one or more lines are too long

View File

@ -220,7 +220,7 @@ class Chosen
classes.push "result-selected" if option.selected classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index? classes.push "group-option" if option.group_array_index?
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + $("<div />").text(option.text).html() + '</li>' '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'
else else
"" ""
@ -321,7 +321,7 @@ class Chosen
choice_build: (item) -> choice_build: (item) ->
choice_id = @container_id + "_c_" + item.array_index choice_id = @container_id + "_c_" + item.array_index
@choices += 1 @choices += 1
@search_container.before '<li class="search-choice" id="' + choice_id + '"><span>' + item.text + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>' @search_container.before '<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>'
link = $('#' + choice_id).find("a").first() link = $('#' + choice_id).find("a").first()
link.click (evt) => this.choice_destroy_link_click(evt) link.click (evt) => this.choice_destroy_link_click(evt)
@ -402,7 +402,7 @@ class Chosen
results = 0 results = 0
searchText = if @search_field.val() is @default_text then "" else $.trim @search_field.val() searchText = if @search_field.val() is @default_text then "" else $('<div/>').text($.trim(@search_field.val())).html()
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
@ -414,12 +414,12 @@ class Chosen
found = false found = false
result_id = option.dom_id result_id = option.dom_id
if regex.test option.text if regex.test option.html
found = true found = true
results += 1 results += 1
else if option.text.indexOf(" ") >= 0 or option.text.indexOf("[") == 0 else if option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0
#TODO: replace this substitution of /\[\]/ with a list of characters to skip. #TODO: replace this substitution of /\[\]/ with a list of characters to skip.
parts = option.text.replace(/\[|\]/g, "").split(" ") parts = option.html.replace(/\[|\]/g, "").split(" ")
if parts.length if parts.length
for part in parts for part in parts
if regex.test part if regex.test part
@ -428,11 +428,11 @@ class Chosen
if found if found
if searchText.length if searchText.length
startpos = option.text.search zregex startpos = option.html.search zregex
text = option.text.substr(0, startpos + searchText.length) + '</em>' + option.text.substr(startpos + searchText.length) text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
text = text.substr(0, startpos) + '<em>' + text.substr(startpos) text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
else else
text = option.text text = option.html
$("#" + result_id).html text if $("#" + result_id).html != text $("#" + result_id).html text if $("#" + result_id).html != text
@ -467,7 +467,7 @@ class Chosen
no_results: (terms) -> no_results: (terms) ->
no_results_html = $('<li class="no-results">No results match "<span></span>"</li>') no_results_html = $('<li class="no-results">No results match "<span></span>"</li>')
no_results_html.find("span").first().text(terms) no_results_html.find("span").first().html(terms)
@search_results.append no_results_html @search_results.append no_results_html
@ -632,6 +632,7 @@ class SelectParser
options_index: @options_index options_index: @options_index
value: option.value value: option.value
text: option.text text: option.text
html: option.innerHTML
selected: option.selected selected: option.selected
disabled: if group_disabled is true then group_disabled else option.disabled disabled: if group_disabled is true then group_disabled else option.disabled
group_array_index: group_position group_array_index: group_position

View File

@ -189,7 +189,7 @@ class Chosen
if data.selected and @is_multiple if data.selected and @is_multiple
this.choice_build data this.choice_build data
else if data.selected and not @is_multiple else if data.selected and not @is_multiple
@selected_item.down("span").update( data.text ) @selected_item.down("span").update( data.html )
this.show_search_field_default() this.show_search_field_default()
this.search_field_scale() this.search_field_scale()
@ -213,7 +213,7 @@ class Chosen
classes.push "result-selected" if option.selected classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index? classes.push "group-option" if option.group_array_index?
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.text.escapeHTML() + '</li>' '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'
else else
"" ""
@ -313,7 +313,11 @@ class Chosen
choice_build: (item) -> choice_build: (item) ->
choice_id = @container_id + "_c_" + item.array_index choice_id = @container_id + "_c_" + item.array_index
@choices += 1 @choices += 1
@search_container.insert { before: @choice_temp.evaluate({"id":choice_id, "choice":item.text, "position":item.array_index}) } @search_container.insert
before: @choice_temp.evaluate
id: choice_id
choice: item.html
position: item.array_index
link = $(choice_id).down('a') link = $(choice_id).down('a')
link.observe "click", (evt) => this.choice_destroy_link_click(evt) link.observe "click", (evt) => this.choice_destroy_link_click(evt)
@ -352,7 +356,7 @@ class Chosen
if @is_multiple if @is_multiple
this.choice_build item this.choice_build item
else else
@selected_item.down("span").update(item.text) @selected_item.down("span").update(item.html)
this.results_hide() this.results_hide()
@search_field.value = "" @search_field.value = ""
@ -392,7 +396,7 @@ class Chosen
results = 0 results = 0
searchText = if @search_field.value is @default_text then "" else @search_field.value.strip() searchText = if @search_field.value is @default_text then "" else @search_field.value.strip().escapeHTML()
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
@ -404,12 +408,12 @@ class Chosen
found = false found = false
result_id = option.dom_id result_id = option.dom_id
if regex.test option.text if regex.test option.html
found = true found = true
results += 1 results += 1
else if option.text.indexOf(" ") >= 0 or option.text.indexOf("[") == 0 else if option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0
#TODO: replace this substitution of /\[\]/ with a list of characters to skip. #TODO: replace this substitution of /\[\]/ with a list of characters to skip.
parts = option.text.replace(/\[|\]/g, "").split(" ") parts = option.html.replace(/\[|\]/g, "").split(" ")
if parts.length if parts.length
for part in parts for part in parts
if regex.test part if regex.test part
@ -418,11 +422,11 @@ class Chosen
if found if found
if searchText.length if searchText.length
startpos = option.text.search zregex startpos = option.html.search zregex
text = option.text.substr(0, startpos + searchText.length) + '</em>' + option.text.substr(startpos + searchText.length) text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
text = text.substr(0, startpos) + '<em>' + text.substr(startpos) text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
else else
text = option.text text = option.html
$(result_id).update text if $(result_id).innerHTML != text $(result_id).update text if $(result_id).innerHTML != text
@ -455,7 +459,7 @@ class Chosen
this.result_do_highlight do_high this.result_do_highlight do_high
no_results: (terms) -> no_results: (terms) ->
@search_results.insert @no_results_temp.evaluate({"terms":terms.escapeHTML()}) @search_results.insert @no_results_temp.evaluate( terms: terms )
no_results_clear: -> no_results_clear: ->
nr = null nr = null
@ -551,7 +555,7 @@ class Chosen
for style in styles for style in styles
style_block += style + ":" + @search_field.getStyle(style) + ";" style_block += style + ":" + @search_field.getStyle(style) + ";"
div = new Element('div', { 'style' : style_block }).update(@search_field.value) div = new Element('div', { 'style' : style_block }).update(@search_field.value.escapeHTML())
document.body.appendChild(div) document.body.appendChild(div)
w = Element.measure(div, 'width') + 25 w = Element.measure(div, 'width') + 25
@ -611,6 +615,7 @@ class SelectParser
options_index: @options_index options_index: @options_index
value: option.value value: option.value
text: option.text text: option.text
html: option.innerHTML
selected: option.selected selected: option.selected
disabled: if group_disabled is true then group_disabled else option.disabled disabled: if group_disabled is true then group_disabled else option.disabled
group_array_index: group_position group_array_index: group_position