Handsontable within the Salesforce Locker service

Tags: #<Tag:0x00007f8b25734058>

Building a Salesforce lightning component using handsontable and i am running into issues with the Salesforce locker service. Among other things, the locker service prevents components from traversing the DOM outside of their component. Because of this, i am running into an error when trying to click outside of handsontable due to the mousedown event trying to grab a parentNode which it is not allowed to access.

This is the unmodified listener:

this.eventManager.addEventListener(document.documentElement, 'mousedown', function(event)
{
    var originalTarget = event.target;
    var next = event.target;
    var eventX = event.x || event.clientX;
    var eventY = event.y || event.clientY;
    
    if (isMouseDown || !instance.rootElement)
    {
        return;
    }
    
    if (next === instance.view.wt.wtTable.holder)
    {
        var scrollbarWidth = getScrollbarWidth();
        if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder || document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) 
        {
            return;
        }
    }
    else
    {
        while (next !== document.documentElement)
        {
            if (next === null)
            {
                if (event.isTargetWebComponent)
                {
                    break;
                }
                return;
            }
            if (next === instance.rootElement)
            {
                return;
            }

	    next = next.parentNode;
        }
    }
    
    var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ? that.settings.outsideClickDeselects(originalTarget) : that.settings.outsideClickDeselects;
    if (outsideClickDeselects)
    {
        instance.deselectCell();
    } else {
        instance.destroyEditor();
    }
});

To address this issue, i modified the following line:

next = next.parentNode;

to

	if(next.parentNode != null)
	next = next.parentNode;
else
	next = null;

Essentially, i check to see if the next node in the chain is defined, and if so use it. If it is not, i.e. the component doesnt have permission to access it, i set next to null.

Based on this seemingly simple change which i have tested and seems to work, any thoughts on unintended consequences that i should be aware of?

Details on locker incase anyone is interested or needs more details:

Salesforce Locker Service

Thank you for mentioning this subject @wkuehler I have to say that I do not have any knowledge about LocerService. I’ll ask our developers and be back with any news as soon as possible.