Browse Source

Fix quote encoding in dropdown

pull/4074/head
Jack Lukic 9 years ago
parent
commit
f38237d6f8
2 changed files with 46 additions and 19 deletions
  1. 1
      RELEASE-NOTES.md
  2. 64
      src/definitions/modules/dropdown.js

1
RELEASE-NOTES.md

@ -36,6 +36,7 @@
- **Checkbox** - Radio buttons received `indeterminate` styles when user has not yet interacted with the page in Chrome - **Checkbox** - Radio buttons received `indeterminate` styles when user has not yet interacted with the page in Chrome
- **Dropdown** - Fixed bug where using `action: 'hide'` could cause `text` value not to be passed to `onChange` callback - **Dropdown** - Fixed bug where using `action: 'hide'` could cause `text` value not to be passed to `onChange` callback
- **Dropdown** - `apiSettings` was not defaulting to use `cache: 'local'` as specified in the docs - **Dropdown** - `apiSettings` was not defaulting to use `cache: 'local'` as specified in the docs
- **Dropdown** - Fixed issue where values with `"` (double quotes) would not work with a dropdown using a select, because value would not be encoded as html entities
- **Dropdown** - `get value` would not return correct value when value was blank #3766 - **Dropdown** - `get value` would not return correct value when value was blank #3766
- **Dropdown** - Dropdown would open when an label delete x was clicked when not using `search selection` #3789 - **Dropdown** - Dropdown would open when an label delete x was clicked when not using `search selection` #3789
- **Dropdown** - Dropdowns with sub-menus would not properly activate on mobile #3183 - **Dropdown** - Dropdowns with sub-menus would not properly activate on mobile #3183

64
src/definitions/modules/dropdown.js

@ -1228,7 +1228,7 @@ $.fn.dropdown = function(parameters) {
newIndex newIndex
; ;
// visible menu keyboard shortcuts // visible menu keyboard shortcuts
if( module.is.visible() ) {
if( module.is.visible() || settings.allowAdditions ) {
// enter (select or open sub-menu) // enter (select or open sub-menu)
if(pressedKey == keys.enter || delimiterPressed) { if(pressedKey == keys.enter || delimiterPressed) {
@ -2234,6 +2234,7 @@ $.fn.dropdown = function(parameters) {
}, },
value: function(value, text, $selected) { value: function(value, text, $selected) {
var var
escapedValue = module.escape.value(value),
hasInput = ($input.length > 0), hasInput = ($input.length > 0),
isAddition = !module.has.value(value), isAddition = !module.has.value(value),
currentValue = module.get.values(), currentValue = module.get.values(),
@ -2254,10 +2255,10 @@ $.fn.dropdown = function(parameters) {
module.debug('Adding user option', value); module.debug('Adding user option', value);
module.add.optionValue(value); module.add.optionValue(value);
} }
module.debug('Updating input value', value, currentValue);
module.debug('Updating input value', escapedValue, currentValue);
internalChange = true; internalChange = true;
$input $input
.val(value)
.val(escapedValue)
; ;
if(settings.fireOnInit === false && module.is.initialLoad()) { if(settings.fireOnInit === false && module.is.initialLoad()) {
module.debug('Input native change event ignored on initial load'); module.debug('Input native change event ignored on initial load');
@ -2268,8 +2269,8 @@ $.fn.dropdown = function(parameters) {
internalChange = false; internalChange = false;
} }
else { else {
module.verbose('Storing value in metadata', value, $input);
if(value !== currentValue) {
module.verbose('Storing value in metadata', escapedValue, $input);
if(escapedValue !== currentValue) {
$module.data(metadata.value, stringValue); $module.data(metadata.value, stringValue);
} }
} }
@ -2377,17 +2378,18 @@ $.fn.dropdown = function(parameters) {
$next = module.is.searchSelection() $next = module.is.searchSelection()
? $search ? $search
: $text, : $text,
escapedValue = module.escape.value(value),
$label $label
; ;
$label = $('<a />') $label = $('<a />')
.addClass(className.label) .addClass(className.label)
.attr('data-value', value)
.html(templates.label(value, text))
.attr('data-value', escapedValue)
.html(templates.label(escapedValue, text))
; ;
$label = settings.onLabelCreate.call($label, value, text);
$label = settings.onLabelCreate.call($label, escapedValue, text);
if(module.has.label(value)) { if(module.has.label(value)) {
module.debug('Label already exists, skipping', value);
module.debug('Label already exists, skipping', escapedValue);
return; return;
} }
if(settings.label.variation) { if(settings.label.variation) {
@ -2428,8 +2430,9 @@ $.fn.dropdown = function(parameters) {
}, },
optionValue: function(value) { optionValue: function(value) {
var var
$option = $input.find('option[value="' + value + '"]'),
hasOption = ($option.length > 0)
escapedValue = module.escape.value(value),
$option = $input.find('option[value="' + escapedValue + '"]'),
hasOption = ($option.length > 0)
; ;
if(hasOption) { if(hasOption) {
return; return;
@ -2437,14 +2440,14 @@ $.fn.dropdown = function(parameters) {
// temporarily disconnect observer // temporarily disconnect observer
if(selectObserver) { if(selectObserver) {
selectObserver.disconnect(); selectObserver.disconnect();
module.verbose('Temporarily disconnecting mutation observer', value);
module.verbose('Temporarily disconnecting mutation observer', escapedValue);
} }
if( module.is.single() ) { if( module.is.single() ) {
module.verbose('Removing previous user addition'); module.verbose('Removing previous user addition');
$input.find('option.' + className.addition).remove(); $input.find('option.' + className.addition).remove();
} }
$('<option/>') $('<option/>')
.prop('value', value)
.prop('value', escapedValue)
.addClass(className.addition) .addClass(className.addition)
.html(value) .html(value)
.appendTo($input) .appendTo($input)
@ -2601,8 +2604,9 @@ $.fn.dropdown = function(parameters) {
}, },
optionValue: function(value) { optionValue: function(value) {
var var
$option = $input.find('option[value="' + value + '"]'),
hasOption = ($option.length > 0)
escapedValue = module.escape.value(value),
$option = $input.find('option[value="' + escapedValue + '"]'),
hasOption = ($option.length > 0)
; ;
if(!hasOption || !$option.hasClass(className.addition)) { if(!hasOption || !$option.hasClass(className.addition)) {
return; return;
@ -2610,10 +2614,10 @@ $.fn.dropdown = function(parameters) {
// temporarily disconnect observer // temporarily disconnect observer
if(selectObserver) { if(selectObserver) {
selectObserver.disconnect(); selectObserver.disconnect();
module.verbose('Temporarily disconnecting mutation observer', value);
module.verbose('Temporarily disconnecting mutation observer');
} }
$option.remove(); $option.remove();
module.verbose('Removing user addition as an <option>', value);
module.verbose('Removing user addition as an <option>', escapedValue);
if(selectObserver) { if(selectObserver) {
selectObserver.observe($input[0], { selectObserver.observe($input[0], {
childList : true, childList : true,
@ -2814,9 +2818,10 @@ $.fn.dropdown = function(parameters) {
}, },
label: function(value) { label: function(value) {
var var
$labels = $module.find(selector.label)
escapedValue = module.escape.value(value),
$labels = $module.find(selector.label)
; ;
return ($labels.filter('[data-value="' + value +'"]').length > 0);
return ($labels.filter('[data-value="' + escapedValue +'"]').length > 0);
}, },
maxSelections: function() { maxSelections: function() {
return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections); return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections);
@ -3124,6 +3129,26 @@ $.fn.dropdown = function(parameters) {
}, },
escape: { escape: {
value: function(value) {
let
multipleValues = $.isArray(value),
stringValue = (typeof value === 'string'),
isUnparsable = (!stringValue && !multipleValues),
hasQuotes = (stringValue && value.search(regExp.quote) !== -1),
values = []
;
if(!module.has.selectInput() || isUnparsable || !hasQuotes) {
return value;
}
module.debug('Encoding quote values for use in select', value);
if(multipleValues) {
$.each(value, function(index, value){
values.push(value.replace(regExp.quote, '&quot;'));
});
return values;
}
return value.replace(regExp.quote, '&quot;');
},
regExp: function(text) { regExp: function(text) {
text = String(text); text = String(text);
return text.replace(regExp.escape, '\\$&'); return text.replace(regExp.escape, '\\$&');
@ -3411,6 +3436,7 @@ $.fn.dropdown.settings = {
regExp : { regExp : {
escape : /[-[\]{}()*+?.,\\^$|#\s]/g, escape : /[-[\]{}()*+?.,\\^$|#\s]/g,
quote : /"/g
}, },
metadata : { metadata : {

Loading…
Cancel
Save