#
### add single attribute
#
<div data-sly-attribute.data-values="${properties.myValues}"></div>
===
<div data-values="some data value"></div>
^^^
30:     if (!$.col.empty(var_attrValue_data_values0)) {
#
### don't double escape attributes
#
<time datetime="${date}">${date}</time>
<time data-sly-attribute.datetime="${date}">${date}</time>
===
<time datetime="2019-04-02T08&#x3a;44&#x3a;26.000Z">2019-04-02T08:44:26.000Z</time>
<time datetime="2019-04-02T08&#x3a;44&#x3a;26.000Z">2019-04-02T08:44:26.000Z</time>
^^^
35:     $.dom.append($n, var_1);
40:     if (!$.col.empty(var_attrValue_datetime2)) {
45:     $.dom.append($n, var_3);
#
### keep existing attribute
#
<div title="Hello &amp; world."></div>
===
<div title="Hello &amp; world."></div>
#
### replace single attribute
#
<div title="" class="className" data-sly-attribute.class="${properties.myClass}"/>
===
<div title="" class="super-green"/>
^^^
31:     if (!$.col.empty(var_attrValue_class0)) {
#
### replace single attribute after call works.
#
<div data-sly-attribute.class="${properties.myClass}" class="className"/>
===
<div class="super-green"/>
#
### remove single attribute
#
<div title="" class="className" data-sly-attribute.class="${false}"/>
===
<div title=""/>
^^^
31:     if (!$.col.empty(var_attrValue_class0)) {
#
### ignore dangerous attributes
#
<div title="" onMouseMove="javascript:alert()" data-sly-attribute.onMouseMove="${'system.exit()'}"/>
===
<div title="" onMouseMove="javascript&#x3a;alert&#x28;&#x29;"/>
#
### create / replace / delete multiple arguments
#
<input class="green" lang="en" data-sly-attribute="${foobar}" type="text" />
===
<input class="bar" type="text" id="foo"/>
^^^
32:     if (!$.col.empty(var_mapContains_class2)) {
#
### left to right
#
<div class="bar1" data-sly-attribute.class="bar2" data-sly-attribute="${foobar}"></div>
<div data-sly-attribute="${foobar}" data-sly-attribute.class="bar2" id="foo2"></div>
===
<div class="bar" id="foo"></div>
<div id="foo2" class="bar2"></div>
#
### Empty string values lead to the removal of the attribute:
#
<div lang="${''}"></div>
<div lang="en" data-sly-attribute.lang></div>
<div lang="en" data-sly-attribute.lang=""></div>
<div lang="en" data-sly-attribute.lang="${''}"></div>
<div lang="en" data-sly-attribute="${foobar}"></div>
===
<div></div>
<div></div>
<div></div>
<div></div>
<div id="foo" class="bar"></div>
^^^
38:     if (!$.col.empty(var_attrValue_lang1)) {
46:     if (!$.col.empty(var_attrValue_lang2)) {
54:     if (!$.col.empty(var_attrValue_lang3)) {
64:     if (!$.col.empty(var_mapContains_lang6)) {
#
### empty attributes are left as they are if no data-sly-attribute applies to them
#
<div title="" data-sly-attribute="${foobar}"></div>
===
<div title="" id="foo" class="bar"></div>
^^^
32:     if (!$.col.empty(var_mapContains_title2)) {
#
### Boolean values allow to control the display of boolean attributes:
#
<input checked="${true}"/>
<input data-sly-attribute.checked="${true}"/>
<input checked="${false}"/>
<input data-sly-attribute.checked="${false}"/>
<input checked="${'true'}"/>
<input checked="${'false'}"/>
<input data-sly-attribute="${attrs}"/>
===
<input checked/>
<input checked/>
<input/>
<input/>
<input checked="true"/>
<input checked="false"/>
<input checked/>
^^^
38:     if (!$.col.empty(var_attrValue_checked1)) {
54:     if (!$.col.empty(var_attrValue_checked3)) {
85:           if (!$.col.empty(var_attrContent11)) {
#
### Arrays are cast to strings:
#
<div title="${['one', 'two', 'three']}"></div>
<div title="${[]}"></div>
===
<div title="one,two,three"></div>
<div></div>
#
### Numbers are cast to strings (i.e. zero doesn't remove the attribute):
#
<div class="${0}"></div>
===
<div class="0"></div>
#
### Quotes are escaped
#
<div class='"foo" "bar"'></div>
===
<div class="&quot;foo&quot; &quot;bar&quot;"></div>
#
### Quotes are escaped in variables
#
<div class="${quotes}"></div>
===
<div class="Hello, &quot;World &amp; Mars&#x21;&quot;"></div>
#
### can output vars with colon
#
<div class="${jcr:content}"></div>
===
<div class="hello again"></div>
#
### can output vars with colon in property
#
<div class="${properties.jcr:content}"></div>
===
<div class="the content"></div>
#
### allow for attributes without value
#
<input type="checkbox" checked disabled>
===
<input type="checkbox" checked disabled>
#
### undefined link
#
<a href="${ foobar.link @ extension = 'html' }">test</a>
===
<a>test</a>
#
### add attribute with many dashes
#
<div data-sly-attribute.data-cmp-contentfragment-path="${properties.myValues}"></div>
===
<div data-cmp-contentfragment-path="some data value"></div>
#
###
