FIX: allows forcing unsafe string in select-kit (#6386)

forceEscape will be defaulted to true before next release.
This commit is contained in:
Joffrey JAFFEUX 2018-09-12 12:19:04 +02:00 committed by GitHub
parent 2cc48cfd06
commit 38668818a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 192 additions and 21 deletions

View File

@ -40,6 +40,7 @@
<p>{{i18n "admin.customize.theme.color_scheme_select"}}</p>
<p>{{combo-box content=colorSchemes
filterable=true
forceEscape=true
value=colorSchemeId
icon="paint-brush"}}
{{#if colorSchemeChanged}}
@ -142,7 +143,7 @@
{{/unless}}
{{#if selectableChildThemes}}
<p>
{{combo-box filterable=true content=selectableChildThemes value=selectedChildThemeId}}
{{combo-box forceEscape=true filterable=true content=selectableChildThemes value=selectedChildThemeId}}
{{#d-button action="addChildTheme" icon="plus"}}{{i18n "admin.customize.theme.add"}}{{/d-button}}
</p>
{{/if}}

View File

@ -17,12 +17,9 @@ export default MultiSelectComponent.extend({
}
if (this.get("nameProperty").indexOf("color") > -1) {
this.set(
"headerComponentOptions",
Ember.Object.create({
selectedNameComponent: "multi-select/selected-color"
})
);
this.get("headerComponentOptions").setProperties({
selectedNameComponent: "multi-select/selected-color"
});
}
},

View File

@ -31,12 +31,9 @@ export default SelectKitComponent.extend({
this.set("values", []);
}
this.set(
"headerComponentOptions",
Ember.Object.create({
selectedNameComponent: this.get("selectedNameComponent")
})
);
this.get("headerComponentOptions").setProperties({
selectedNameComponent: this.get("selectedNameComponent")
});
},
@on("didRender")

View File

@ -14,6 +14,8 @@ export default SelectKitHeaderComponent.extend({
"select-kit/templates/components/multi-select/multi-select-header",
selectedNameComponent: Ember.computed.alias("options.selectedNameComponent"),
forceEscape: Ember.computed.alias("options.forceEscape"),
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title", "names"),
title: Ember.computed.or("computedContent.title", "names"),

View File

@ -81,13 +81,22 @@ export default Ember.Component.extend(
minimum: null,
minimumLabel: null,
maximumLabel: null,
forceEscape: false,
init() {
this._super();
this.noneValue = "__none__";
this.set("headerComponentOptions", Ember.Object.create());
this.set("rowComponentOptions", Ember.Object.create());
this.set(
"headerComponentOptions",
Ember.Object.create({ forceEscape: this.get("forceEscape") })
);
this.set(
"rowComponentOptions",
Ember.Object.create({
forceEscape: this.get("forceEscape")
})
);
this.set("computedContent", []);
this.set("highlightedSelection", []);

View File

@ -14,6 +14,8 @@ export default Ember.Component.extend({
"name:data-name"
],
forceEscape: Ember.computed.alias("options.forceEscape"),
isNone: Ember.computed.none("computedContent.value"),
ariaHasPopup: true,

View File

@ -18,6 +18,8 @@ export default Ember.Component.extend(UtilsMixin, {
],
classNameBindings: ["isHighlighted", "isSelected"],
forceEscape: Ember.computed.alias("options.forceEscape"),
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title"),
@computed("computedContent.title", "name")

View File

@ -1,7 +1,11 @@
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
<span class="selected-name">
{{{label}}}
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>
{{#if shouldDisplayClearableButton}}

View File

@ -5,7 +5,11 @@
{{/if}}
<span class="selected-name" title={{title}}>
{{{label}}}
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>
{{#if computedContent.datetime}}

View File

@ -3,6 +3,7 @@
{{component selectedNameComponent
onClickSelectionItem=onClickSelectionItem
highlightedSelection=highlightedSelection
forceEscape=forceEscape
computedContent=selection}}
{{/each}}
<span class="filter choice" tabindex="-1">

View File

@ -2,7 +2,11 @@
<div class="body">
<span class="name">
{{{label}}}
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>
</div>

View File

@ -1,5 +1,9 @@
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
<span class="selected-name">
{{{label}}}
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>

View File

@ -2,5 +2,11 @@
{{{template}}}
{{else}}
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
<span class="name">{{{label}}}</span>
<span class="name">
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>
{{/if}}

View File

@ -1,5 +1,9 @@
<span class="selected-name">
{{{label}}}
{{#if forceEscape}}
{{label}}
{{else}}
{{{label}}}
{{/if}}
</span>
{{d-icon caretIcon class="caret-icon fa-fw"}}

View File

@ -247,3 +247,73 @@ componentTest("with minimumLabel", {
);
}
});
componentTest("with forceEscape", {
template: "{{multi-select content=content forceEscape=true}}",
beforeEach() {
this.set("content", ["<div>sam</div>"]);
},
async test(assert) {
await this.get("subject").expand();
const row = this.get("subject").rowByIndex(0);
assert.equal(
row
.el()
.find(".name")
.html()
.trim(),
"&lt;div&gt;sam&lt;/div&gt;"
);
await this.get("subject").fillInFilter("<div>jeff</div>");
await this.get("subject").keyboard("enter");
assert.equal(
this.get("subject")
.header()
.el()
.find(".name")
.html()
.trim(),
"&lt;div&gt;jeff&lt;/div&gt;"
);
}
});
componentTest("with forceEscape", {
template: "{{multi-select content=content forceEscape=false}}",
beforeEach() {
this.set("content", ["<div>sam</div>"]);
},
async test(assert) {
await this.get("subject").expand();
const row = this.get("subject").rowByIndex(0);
assert.equal(
row
.el()
.find(".name")
.html()
.trim(),
"<div>sam</div>"
);
await this.get("subject").fillInFilter("<div>jeff</div>");
await this.get("subject").keyboard("enter");
assert.equal(
this.get("subject")
.header()
.el()
.find(".name")
.html()
.trim(),
"<div>jeff</div>"
);
}
});

View File

@ -771,3 +771,67 @@ componentTest("with no content and allowAny", {
assert.ok(!$filter.hasClass("is-hidden"));
}
});
componentTest("with forceEscape", {
template: "{{single-select content=content forceEscape=true}}",
beforeEach() {
this.set("content", ["<div>sam</div>"]);
},
async test(assert) {
await this.get("subject").expand();
const row = this.get("subject").rowByIndex(0);
assert.equal(
row
.el()
.find(".name")
.html()
.trim(),
"&lt;div&gt;sam&lt;/div&gt;"
);
assert.equal(
this.get("subject")
.header()
.el()
.find(".selected-name")
.html()
.trim(),
"&lt;div&gt;sam&lt;/div&gt;"
);
}
});
componentTest("without forceEscape", {
template: "{{single-select content=content forceEscape=false}}",
beforeEach() {
this.set("content", ["<div>sam</div>"]);
},
async test(assert) {
await this.get("subject").expand();
const row = this.get("subject").rowByIndex(0);
assert.equal(
row
.el()
.find(".name")
.html()
.trim(),
"<div>sam</div>"
);
assert.equal(
this.get("subject")
.header()
.el()
.find(".selected-name")
.html()
.trim(),
"<div>sam</div>"
);
}
});