mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 23:07:28 +08:00
FIX: allows forcing unsafe string in select-kit (#6386)
forceEscape will be defaulted to true before next release.
This commit is contained in:
@ -40,6 +40,7 @@
|
|||||||
<p>{{i18n "admin.customize.theme.color_scheme_select"}}</p>
|
<p>{{i18n "admin.customize.theme.color_scheme_select"}}</p>
|
||||||
<p>{{combo-box content=colorSchemes
|
<p>{{combo-box content=colorSchemes
|
||||||
filterable=true
|
filterable=true
|
||||||
|
forceEscape=true
|
||||||
value=colorSchemeId
|
value=colorSchemeId
|
||||||
icon="paint-brush"}}
|
icon="paint-brush"}}
|
||||||
{{#if colorSchemeChanged}}
|
{{#if colorSchemeChanged}}
|
||||||
@ -142,7 +143,7 @@
|
|||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{#if selectableChildThemes}}
|
{{#if selectableChildThemes}}
|
||||||
<p>
|
<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}}
|
{{#d-button action="addChildTheme" icon="plus"}}{{i18n "admin.customize.theme.add"}}{{/d-button}}
|
||||||
</p>
|
</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -17,12 +17,9 @@ export default MultiSelectComponent.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.get("nameProperty").indexOf("color") > -1) {
|
if (this.get("nameProperty").indexOf("color") > -1) {
|
||||||
this.set(
|
this.get("headerComponentOptions").setProperties({
|
||||||
"headerComponentOptions",
|
|
||||||
Ember.Object.create({
|
|
||||||
selectedNameComponent: "multi-select/selected-color"
|
selectedNameComponent: "multi-select/selected-color"
|
||||||
})
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -31,12 +31,9 @@ export default SelectKitComponent.extend({
|
|||||||
this.set("values", []);
|
this.set("values", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set(
|
this.get("headerComponentOptions").setProperties({
|
||||||
"headerComponentOptions",
|
|
||||||
Ember.Object.create({
|
|
||||||
selectedNameComponent: this.get("selectedNameComponent")
|
selectedNameComponent: this.get("selectedNameComponent")
|
||||||
})
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@on("didRender")
|
@on("didRender")
|
||||||
|
@ -14,6 +14,8 @@ export default SelectKitHeaderComponent.extend({
|
|||||||
"select-kit/templates/components/multi-select/multi-select-header",
|
"select-kit/templates/components/multi-select/multi-select-header",
|
||||||
selectedNameComponent: Ember.computed.alias("options.selectedNameComponent"),
|
selectedNameComponent: Ember.computed.alias("options.selectedNameComponent"),
|
||||||
|
|
||||||
|
forceEscape: Ember.computed.alias("options.forceEscape"),
|
||||||
|
|
||||||
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title", "names"),
|
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title", "names"),
|
||||||
|
|
||||||
title: Ember.computed.or("computedContent.title", "names"),
|
title: Ember.computed.or("computedContent.title", "names"),
|
||||||
|
@ -81,13 +81,22 @@ export default Ember.Component.extend(
|
|||||||
minimum: null,
|
minimum: null,
|
||||||
minimumLabel: null,
|
minimumLabel: null,
|
||||||
maximumLabel: null,
|
maximumLabel: null,
|
||||||
|
forceEscape: false,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
this.noneValue = "__none__";
|
this.noneValue = "__none__";
|
||||||
this.set("headerComponentOptions", Ember.Object.create());
|
this.set(
|
||||||
this.set("rowComponentOptions", Ember.Object.create());
|
"headerComponentOptions",
|
||||||
|
Ember.Object.create({ forceEscape: this.get("forceEscape") })
|
||||||
|
);
|
||||||
|
this.set(
|
||||||
|
"rowComponentOptions",
|
||||||
|
Ember.Object.create({
|
||||||
|
forceEscape: this.get("forceEscape")
|
||||||
|
})
|
||||||
|
);
|
||||||
this.set("computedContent", []);
|
this.set("computedContent", []);
|
||||||
this.set("highlightedSelection", []);
|
this.set("highlightedSelection", []);
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ export default Ember.Component.extend({
|
|||||||
"name:data-name"
|
"name:data-name"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
forceEscape: Ember.computed.alias("options.forceEscape"),
|
||||||
|
|
||||||
isNone: Ember.computed.none("computedContent.value"),
|
isNone: Ember.computed.none("computedContent.value"),
|
||||||
|
|
||||||
ariaHasPopup: true,
|
ariaHasPopup: true,
|
||||||
|
@ -18,6 +18,8 @@ export default Ember.Component.extend(UtilsMixin, {
|
|||||||
],
|
],
|
||||||
classNameBindings: ["isHighlighted", "isSelected"],
|
classNameBindings: ["isHighlighted", "isSelected"],
|
||||||
|
|
||||||
|
forceEscape: Ember.computed.alias("options.forceEscape"),
|
||||||
|
|
||||||
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title"),
|
ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title"),
|
||||||
|
|
||||||
@computed("computedContent.title", "name")
|
@computed("computedContent.title", "name")
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
||||||
|
|
||||||
<span class="selected-name">
|
<span class="selected-name">
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
{{{label}}}
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{#if shouldDisplayClearableButton}}
|
{{#if shouldDisplayClearableButton}}
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<span class="selected-name" title={{title}}>
|
<span class="selected-name" title={{title}}>
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
{{{label}}}
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{#if computedContent.datetime}}
|
{{#if computedContent.datetime}}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
{{component selectedNameComponent
|
{{component selectedNameComponent
|
||||||
onClickSelectionItem=onClickSelectionItem
|
onClickSelectionItem=onClickSelectionItem
|
||||||
highlightedSelection=highlightedSelection
|
highlightedSelection=highlightedSelection
|
||||||
|
forceEscape=forceEscape
|
||||||
computedContent=selection}}
|
computedContent=selection}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
<span class="filter choice" tabindex="-1">
|
<span class="filter choice" tabindex="-1">
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
{{{label}}}
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
||||||
|
|
||||||
<span class="selected-name">
|
<span class="selected-name">
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
{{{label}}}
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
@ -2,5 +2,11 @@
|
|||||||
{{{template}}}
|
{{{template}}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
|
||||||
<span class="name">{{{label}}}</span>
|
<span class="name">
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<span class="selected-name">
|
<span class="selected-name">
|
||||||
|
{{#if forceEscape}}
|
||||||
|
{{label}}
|
||||||
|
{{else}}
|
||||||
{{{label}}}
|
{{{label}}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{d-icon caretIcon class="caret-icon fa-fw"}}
|
{{d-icon caretIcon class="caret-icon fa-fw"}}
|
||||||
|
@ -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(),
|
||||||
|
"<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>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@ -771,3 +771,67 @@ componentTest("with no content and allowAny", {
|
|||||||
assert.ok(!$filter.hasClass("is-hidden"));
|
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(),
|
||||||
|
"<div>sam</div>"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
this.get("subject")
|
||||||
|
.header()
|
||||||
|
.el()
|
||||||
|
.find(".selected-name")
|
||||||
|
.html()
|
||||||
|
.trim(),
|
||||||
|
"<div>sam</div>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user