Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

value binding should no longer escape values of select controls by de…

…fault
  • Loading branch information...
commit 53ce1eed5b7dac964475aa119ed801d49470b5f0 1 parent 2d8d636
politician authored

Showing 2 changed files with 75 additions and 4 deletions. Show diff stats Hide diff stats

  1. +8 4 outback.js
  2. +67 0 spec/bindings/value.spec.js
12 outback.js
@@ -751,7 +751,7 @@
751 751 form elements such as <input>, <select> and <textarea>.
752 752 */
753 753 Backbone.outback.bindingHandlers['value'] = (function() {
754   - function optionsFor(valueAccessor, allBindingsAccessor) {
  754 + function optionsFor(element, valueAccessor, allBindingsAccessor) {
755 755 var config, options;
756 756
757 757 config = {
@@ -761,6 +761,10 @@
761 761 previewError: true
762 762 };
763 763
  764 + if ($(element).filter('select').size() > 0) {
  765 + config.escape = false;
  766 + }
  767 +
764 768 options = allBindingsAccessor('valueOptions');
765 769 if(options && hop(options, 'escape')) {
766 770 config.escape = !!options.escape;
@@ -780,7 +784,7 @@
780 784 return {
781 785 init: function (element, valueAccessor, allBindingsAccessor, view) {
782 786 var config, writeOptions;
783   - config = optionsFor(valueAccessor, allBindingsAccessor);
  787 + config = optionsFor(element, valueAccessor, allBindingsAccessor);
784 788
785 789 writeOptions = {
786 790 silent: config.silent,
@@ -795,7 +799,7 @@
795 799 },
796 800 update: function (element, valueAccessor, allBindingsAccessor, view) {
797 801 var config, value, readOptions;
798   - config = optionsFor(valueAccessor, allBindingsAccessor);
  802 + config = optionsFor(element, valueAccessor, allBindingsAccessor);
799 803
800 804 readOptions = {escape: config.escape};
801 805
@@ -804,7 +808,7 @@
804 808 },
805 809 remove: function (element, valueAccessor, allBindingsAccessor, view) {
806 810 var config;
807   - config = optionsFor(valueAccessor, allBindingsAccessor);
  811 + config = optionsFor(element, valueAccessor, allBindingsAccessor);
808 812
809 813 $(element).off(config.eventName);
810 814 },
67 spec/bindings/value.spec.js
@@ -80,6 +80,73 @@ describe('the value binding', function() {
80 80
81 81 });
82 82
  83 + describe('should work with select controls with multiple="multiple"', function() {
  84 +
  85 + beforeEach(function() {
  86 + this.model = new AModel({car: 'volvo'});
  87 + this.view = new FixtureView({model: this.model});
  88 + _.extend(this.view, {
  89 + innerHtml:
  90 + "<select type='text' multiple='multiple' data-bind='value: @car'> \
  91 + <option value='volvo'>Volvo</option>\
  92 + <option value='saab'>Saab</option>\
  93 + <option value='mercedes'>Mercedes</option>\
  94 + <option value='audi'>Audi</option>\
  95 + </select>"
  96 + })
  97 +
  98 + this.view.render();
  99 + this.el = this.view.$('#anchor select');
  100 + });
  101 +
  102 + afterEach(function() {
  103 + this.view.remove();
  104 + })
  105 +
  106 + it('should update the value of the DOM element when the model changes', function() {
  107 + expect(this.el.size() > 0).toBeTruthy();
  108 + expect(this.el.val()).toContain('volvo');
  109 +
  110 + this.model.set({car: 'saab'});
  111 +
  112 + expect(this.el.val()).toContain('saab');
  113 + });
  114 +
  115 + it('should update the model when the value of the DOM element changes', function() {
  116 + expect(this.el.size() > 0).toBeTruthy();
  117 + expect(this.el.val()).toContain('volvo');
  118 +
  119 + this.el.val('saab');
  120 + this.el.trigger('change');
  121 +
  122 + expect(this.model.get('car')).toContain('saab');
  123 + });
  124 +
  125 + it('should select multiple DOM elements when the model is set to an array', function() {
  126 + expect(this.el.size() > 0).toBeTruthy();
  127 + expect(this.el.val()).toContain('volvo');
  128 +
  129 + this.model.set({car: ['saab','audi']});
  130 +
  131 + var val = this.el.val();
  132 + expect(val).not.toBeNull();
  133 + expect(val).toContain('saab');
  134 + expect(val).toContain('audi');
  135 + });
  136 +
  137 + it('should set the model to an array when multiple options in the DOM are selected', function() {
  138 + expect(this.el.size() > 0).toBeTruthy();
  139 + expect(this.el.val()).toContain('volvo');
  140 +
  141 + this.el.val(['saab','audi']);
  142 + this.el.trigger('change');
  143 +
  144 + var val = this.model.get('car');
  145 + expect(val).toContain('saab');
  146 + expect(val).toContain('audi');
  147 + });
  148 + });
  149 +
83 150 describe('helps prevent XSS attacks', function() {
84 151 var xssPayload = "<script>(function() { var xss = 'in ur page, hackin ur users'; })();</script>";
85 152 var xssPayloadEscaped = '&lt;script&gt;(function() { var xss = &#x27;in ur page, hackin ur users&#x27;; })();&lt;&#x2F;script&gt;'

0 comments on commit 53ce1ee

Please sign in to comment.
Something went wrong with that request. Please try again.