Skip to content

Commit

Permalink
Merge pull request #2723 from koenpunt/csp-fixes
Browse files Browse the repository at this point in the history
Content-Security-Policy fixes
  • Loading branch information
koenpunt authored Nov 27, 2016
2 parents 60cdbb7 + e7b68c3 commit 56ec9dd
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 111 deletions.
47 changes: 25 additions & 22 deletions coffee/chosen.jquery.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,19 @@ class Chosen extends AbstractChosen

container_props =
'class': container_classes.join ' '
'style': "width: #{this.container_width()};"
'title': @form_field.title

container_props.id = @form_field.id.replace(/[^\w]/g, '_') + "_chosen" if @form_field.id.length

@container = ($ "<div />", container_props)

# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
@container.width this.container_width()

if @is_multiple
@container.html '<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + @default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'
@container.html this.get_multi_html()
else
@container.html '<a class="chosen-single chosen-default"><span>' + @default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'
@container.html this.get_single_html()

@form_field_jq.hide().after @container
@dropdown = @container.find('div.chosen-drop').first()
Expand Down Expand Up @@ -430,9 +432,7 @@ class Chosen extends AbstractChosen
this.result_do_highlight do_high if do_high?

no_results: (terms) ->
no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
no_results_html.find("span").first().html(terms)

no_results_html = this.get_no_results_html(terms)
@search_results.append no_results_html
@form_field_jq.trigger("chosen:no_results", {chosen:this})

Expand Down Expand Up @@ -476,29 +476,32 @@ class Chosen extends AbstractChosen
@pending_backstroke = null

search_field_scale: ->
if @is_multiple
h = 0
w = 0
return unless @is_multiple

style_block =
position: 'absolute'
left: '-1000px'
top: '-1000px'
display: 'none'
whiteSpace: 'pre'

style_block = "position:absolute; left: -1000px; top: -1000px; display: none; white-space: pre;"
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']
styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing']

for style in styles
style_block += style + ":" + @search_field.css(style) + ";"
for style in styles
style_block[style] = @search_field.css(style)

div = $('<div />', { 'style' : style_block })
div.text this.get_search_field_value()
$('body').append div
div = $('<div />').css(style_block)
div.text this.get_search_field_value()
$('body').append div

w = div.width() + 25
div.remove()
width = div.width() + 25
div.remove()

f_width = @container.outerWidth()
container_width = @container.outerWidth()

if( w > f_width - 10 )
w = f_width - 10
width = Math.min(container_width - 10, width)

@search_field.css({'width': w + 'px'})
@search_field.width(width)

trigger_form_field_change: (extra) ->
@form_field_jq.trigger "input", extra
Expand Down
50 changes: 30 additions & 20 deletions coffee/chosen.proto.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ class @Chosen extends AbstractChosen
super()

# HTML Templates
@single_temp = new Template('<a class="chosen-single chosen-default"><span>#{default}</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>')
@multi_temp = new Template('<ul class="chosen-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>')
@no_results_temp = new Template('<li class="no-results">' + @results_none_found + ' "<span>#{terms}</span>"</li>')
@no_results_temp = new Template(this.get_no_results_html('#{terms}'))

set_up_html: ->
container_classes = ["chosen-container"]
Expand All @@ -19,12 +17,19 @@ class @Chosen extends AbstractChosen

container_props =
'class': container_classes.join ' '
'style': "width: #{this.container_width()};"
'title': @form_field.title

container_props.id = @form_field.id.replace(/[^\w]/g, '_') + "_chosen" if @form_field.id.length

@container = if @is_multiple then new Element('div', container_props).update( @multi_temp.evaluate({ "default": @default_text}) ) else new Element('div', container_props).update( @single_temp.evaluate({ "default":@default_text }) )
@container = new Element('div', container_props)

# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
@container.setStyle(width: this.container_width())

if @is_multiple
@container.update this.get_multi_html()
else
@container.update this.get_single_html()

@form_field.hide().insert({ after: @container })
@dropdown = @container.down('div.chosen-drop')
Expand Down Expand Up @@ -475,28 +480,33 @@ class @Chosen extends AbstractChosen
@pending_backstroke = null

search_field_scale: ->
if @is_multiple
h = 0
w = 0
return unless @is_multiple

style_block =
position: 'absolute'
left: '-1000px'
top: '-1000px'
display: 'none'
whiteSpace: 'pre'

style_block = "position:absolute; left: -1000px; top: -1000px; display: none; white-space: pre;"
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']
styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing']

for style in styles
style_block += style + ":" + @search_field.getStyle(style) + ";"
for style in styles
style_block[style] = @search_field.getStyle(style)

div = new Element('div', { 'style' : style_block }).update(this.get_search_field_value().escapeHTML())
document.body.appendChild(div)
div = new Element('div').update(this.escape_html(this.get_search_field_value()))
# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
div.setStyle(style_block)
document.body.appendChild(div)

w = Element.measure(div, 'width') + 25
div.remove()
width = div.measure('width') + 25
div.remove()

f_width = @container.getWidth()
container_width = @container.getWidth()

if( w > f_width-10 )
w = f_width - 10
width = Math.min(container_width - 10, width)

@search_field.setStyle({'width': w + 'px'})
@search_field.setStyle(width: width + 'px')

trigger_form_field_change: ->
triggerHtmlEvent @form_field, 'input'
Expand Down
33 changes: 33 additions & 0 deletions coffee/lib/abstract-chosen.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,39 @@ class AbstractChosen
tmp.appendChild(element)
tmp.innerHTML

get_single_html: ->
"""
<a class="chosen-single chosen-default">
<span>#{@default_text}</span>
<div><b></b></div>
</a>
<div class="chosen-drop">
<div class="chosen-search">
<input class="chosen-search-input" type="text" autocomplete="off" />
</div>
<ul class="chosen-results"></ul>
</div>
"""

get_multi_html: ->
"""
<ul class="chosen-choices">
<li class="search-field">
<input class="chosen-search-input" type="text" autocomplete="off" value="#{@default_text}" />
</li>
</ul>
<div class="chosen-drop">
<ul class="chosen-results"></ul>
</div>
"""

get_no_results_html: (terms) ->
"""
<li class="no-results">
#{@results_none_found} <span>#{terms}</span>
</li>
"""

# class methods and variables ============================================================

@browser_is_supported: ->
Expand Down
11 changes: 11 additions & 0 deletions public/docsupport/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : { allow_single_deselect: true },
'.chosen-select-no-single' : { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-rtl' : { rtl: true },
'.chosen-select-width' : { width: '95%' }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
16 changes: 16 additions & 0 deletions public/docsupport/init.proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
document.observe('dom:loaded', function(evt) {
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : { allow_single_deselect: true },
'.chosen-select-no-single' : { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-rtl' : { rtl: true },
'.chosen-select-width' : { width: '95%' }
}

for (var selector in config) {
$$(selector).each(function(element) {
new Chosen(element, config[selector]);
});
}
});
15 changes: 15 additions & 0 deletions public/docsupport/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,18 @@ i { font-style: italic; }
padding-left: 27px;
text-decoration: none;
}

.select,
.chosen-select,
.chosen-select-no-single,
.chosen-select-no-results,
.chosen-select-deselect,
.chosen-select-rtl,
.chosen-select-width {
width: 350px;
}

.jquery-version-refer {
margin-top: 40px;
font-style: italic;
}
Loading

0 comments on commit 56ec9dd

Please sign in to comment.