canjs / can-stache

Live binding handlebars templates
https://canjs.com/doc/can-stache.html
MIT License
10 stars 13 forks source link

Top-level non-sectioning not converter is interpreted as empty sectioning helper #731

Open rjgotten opened 2 years ago

rjgotten commented 2 years ago

How often can you reproduce it?

Description:

When using an expression in stache that is supposed to render the result of a top-level not() call as a true or false string, e.g. a basic aria-hidden="{{ not( this.expanded ) }}" as part of a disclosure widget, then the not converter will always render an empty string as a result.

The root cause is in broken logic in the not converter's getter: https://github.com/canjs/can-stache/blob/17b727a5423abdfefa054462c7289da32c64ca88/helpers/core.js#L496-L507

It uses looksLikeOptions and then falsely (!!) assumes whenever an options argument is present, that the not converter is being used as a {{#not}} sectioning helper. This leads to cases such as the above example to effectively be interpreted as:

aria-hidden="{{#not ( this.expanded ) }}{{/not}}"

- i.e. to be interpreted as never rendering any actual content, because the sectioning templates are empty.

Here's also a screenshot of the above problem in action, with the debugger halted on the problematic conditional branch: image

What the converter should be doing is strengthening that check with an additional check of the options.isSection property. E.g.

var notConverter = {
    get: function(obs, options){
        if(helpersCore.looksLikeOptions(options) && (options.isSection !== false)) {
            return canReflect.getValue(obs) ? options.inverse() : options.fn();
        } else {
            return !canReflect.getValue(obs);
        }
    },
    set: function(newVal, obs){
        canReflect.setValue(obs, !newVal);
    }
};

Steps to reproduce:

See the description.

Expected results: The not converter handles the described case correctly and does not hit the sectioning helper logic branch.

Actual results: The not converter handles the described case incorrectly and hits the sectioning helper logic branch.

Environment:

Software Version
can-stache version all current affected
Browser any
Operating system any