Don't decorate cooked items in composer view?

AI-generated summary

The discussion revolves around a theme component that blocks posts containing user-specified keywords. asc has the block functionality working but is seeking a way to prevent api.decorateCookedElement from firing on the composer preview pane. Don suggests adding the onlyStream option to the method, which will only fire the code when the post is rendered inside a topic, effectively preventing the decoration of the composer preview. asc finds the solution helpful.

I’m working on a theme component to block posts that contain keywords the user specifies in a custom user field.

I have the block/show functionality working, but it also decorates the preview pane of the composer view when typing. Is there a way to prevent api.decorateCookedElement from firing on the composer preview? Below is what I have working so far.

<script type="text/discourse-plugin" version="0.8">
let currentUser = api.getCurrentUser();

if (currentUser) {
    api.container.lookup('store:main').find('user', currentUser.username).then((user) => {
        let blocklist = user.user_fields[1];

        const blocked = blocklist.split(",").map(function(item) {
            return item.trim();
        });
        
        api.decorateCookedElement(
            elem => {
                let textContent = elem.textContent;
                let result = "";
                if (blocked.find(text => textContent.includes(text))) {
                    const found = blocked.filter(text => textContent.includes(text));
                    if (found.length >= 2) {
                        const last = found.pop();
                        result = found.join(', ') + ' and ' + last;
                    } else {
                        result = found.join(', ');
                    }
                    const children = elem.childNodes;
                    const newNode = document.createElement("a");
                    const textNode = document.createTextNode("Blocked for containing " + result + ".");
                    newNode.classList.add("block-notice")
                    newNode.appendChild(textNode);
                    newNode.onclick = function() { showComment(this); };
                    
                    elem.insertBefore(newNode, elem.children[0]);
                    for (let index = 0; index < children.length; ++index) {
                        children[index].classList.add("blocker-blocked")
                    }
                    newNode.classList.remove("blocker-blocked");
                }
            },
            {"id": "blocker-blocked"}
        );
        
    });
}

function showComment(elem) {
    const cooked = elem.parentNode;
    elem.remove();
    const children = cooked.childNodes;
    for (let index = 0; index < children.length; ++index) {
        children[index].classList.remove("blocker-blocked")
    }
}
</script>

Hello,

Adding onlyStream can do it. Here is an example from an other topic. :slightly_smiling_face:

Perfect, thanks for the link!