Why does DOMPurify with SAFE_FOR_TEMPLATES removes data attributes? - javascript

I stumbled across a weird behavior of DOMPurify where data-* attributes get left when sanitizing with the default options, but get stripped out when using the SAFE_FOR_TEMPLATES option. Also, the whole text that contains a template gets stripped out instead of just the template part.
Are these bugs or features? What is the rationale for these?
const dirty = '<span data-foo="bar"> Hello {{ World }} </span>';
console.log(
DOMPurify.sanitize(dirty)
// expected <span data-foo="bar"> Hello {{ World }} </span>
// actual <span data-foo="bar"> Hello {{ World }} </span>
);
console.log(
DOMPurify.sanitize(dirty, { SAFE_FOR_TEMPLATES: true })
// expected <span data-foo="bar"> Hello </span>
// actual <span> </span>
);
<script src="https://unpkg.com/dompurify#2.0.0/dist/purify.min.js"></script>

Related

HighlightJS not highlighting certain code fragments

I'm using HighlightJS to format code that's being stored in a model's TextField of my Django application.
Here is the template HTML:
<pre>
<code class="{{ compiler.highlight_js_alias }}">{{ compiler.unit_test_boilerplate_code }}</code>
</pre>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/default.min.css"
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
Example output:
<pre>
<code class="ruby hljs language-ruby">
<span class="hljs-keyword">class</span>
<span class="hljs-title class_">Person</span>
:
<span class="hljs-keyword">def</span>
<span class="hljs-title function_">__init__</span>
(
<span class="hljs-params">
<span class="hljs-variable language_">self</span>, name, age</span>
):
<span class="hljs-variable language_">self</span>
.name = name
<span class="hljs-variable language_">self</span>
.age = age
me = Person(
<span class="hljs-string">"Nathan"</span>
<span class="hljs-number">32</span>
)
print(me.name)
</code>
</pre>
Why are certain fragments not highlighted? Thank you for any advice.
After inspecting the outputted HTML of HighlightJS' own demos, it seems this is expected behavior.

parse array in html with javascript and render a different span each time

How can I make this code more general:
<div class="xx" *ngIf="this.message.address">
<span class="helper" *ngIf="this.message.address">
{{ this.errorMessage.address[0] }}
</span>
<span class="helper" *ngIf="this.message.address[1]">
{{ this.errorMessage.address[1] }}
</span>
</div>
so that this span is rendered multiple times for each array element:
<span class="xx" *ngIf="this.message.address.forEach(x=> x">
{{ this.errorMessage.address[x] }}
</span>
(my attempt above doesn't work by the way)
I could only make it work in the angular component, sth like:
this.message.address.forEach(x=> console.log(x))
but I'm not sure how to parse an array in html and render a different span in each case, which is what I really need
What you are looking for is *ngFor, which can be used in your HTML to iterate over an array of elements.
<div class="xx" *ngFor="let ad of this.message.address">
<span class="helper" *ngIf="ad">
{{ ad }}
</span>
</div>

Sending HTML tags in props - react

I need something function or trick to allow using HTML tags in react's props, because i'm using ckeditor for form.
my code:
render(){
let name = this.props.name;
let text = this.props.description;
console.log(text);
return (
<li class="collection-item avatar">
<span class="title"> <strong> {name} </strong> </span>
<p > {text} </p>
<i class="material-icons">grade</i>
</li>
)
}
}
dangerouslySetInnerHTML might help you.
Example from doc:
function createMarkup() { return {__html: 'First ยท Second'}; };
<div dangerouslySetInnerHTML={createMarkup()} />
Always keep in mind that setting html directly can lead to XSS, so you should avoid the stuff as long as possible.

Style one word from a sentence

Hello I have This sentence:
"Starbucks open-hours are from 7-17. Please choose another time!"
I want to make the numbers "7-17" bold and red so that users can see it easier.
This whole sentence is stored in a #Umbraco.GetDictionaryValue:
#Umbraco.GetDictionaryValue("BookingStep1_ClosedPickup") which then in view shows the sentence above.
How can I target the numbers only?
<div class="coffees">
<div class="message">
{{if (!data.location.matchHoursPickup) { }}
{{if (data.location.closedPickup) { }}
#Umbraco.GetDictionaryValue("BookingStep1_ClosedPickup")
{{ }else{ }}
{{= data.closedPickupMsg }}
{{ } }}
{{ }else{ }}
{{ if (data.location.closedDelivery){ }}
#Umbraco.GetDictionaryValue("BookingStep1_ClosedDelivery")
{{ }else{ }}
{{= data.closedDeliveryMsg }}
{{ } }}
{{ } }}
</div>
</div>
You can do it using a span tag.
For ex:
<p>Starbucks open-hours are from <span id="hey">7-17</span>. Please choose another time!</p>
CSS:
#hey {
font-weight:bold;
color:red;
}
You can add the span-tag in the Dictionary value and then use
#Html.Raw(Umbraco.GetDictionaryValue("BookingStep1_ClosedPickup"))
/F
The span tag is the correct way to do this.
The span element is a generic wrapper for phrasing content that by itself does not represent anything.
HebleV's example works.

wrapping div around string using jquery

How do i wrap a div class div class="includingVAT"></div> around the string text :incl. MwSt
<span id="VariantPrice_3181">
<span class="variantprice">
<span class="pricelabel">Preis </span>
240,00 (CHF)
</span>
incl. MwSt
<span id="plus-shipping">plus-shipping</span>
</span>
using jquery?
it needs to look like this:
<span id="VariantPrice_3181">
<span class="variantprice">
<span class="pricelabel">Preis </span>
240,00 (CHF)
</span>
<div class="includingVAT"> incl. MwSt</div>
<span id="plus-shipping">plus-shipping</span>
</span>
the string without span or div needs the div class includingVAT as there could be different language translations.
You can try this example here: DEMO
var text = $('#plus-shipping').map(function(){
return this.previousSibling.nodeValue
});
$('#plus-shipping').prepend('<div class="includingVAT">' + text[0] + '</div>');
$(".pricelabel").after('<div class="includingVAT">');
$(".plus-shipping").before('</div>');
This is awkward and error-prone. Is there any-way you can insert the whole div? Why does incl. MwSt exist only in the HTML?

Categories