function attachResizeEvent(element, resizeListener) {
    if (!element) {
        return;
    }
    if (element.resizedAttached) {
        element.resizedAttached.add(() => resizeListener());
        return;
    }

    element.resizedAttached = new EventQueue();
    element.resizedAttached.add(() => resizeListener());

    const resizeSensor = createResizeSensor();
    element.resizeSensor = resizeSensor;
    element.appendChild(resizeSensor);

    const position = (window.getComputedStyle(element) || element.style).getPropertyValue(
        'position',
    );

    if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
        element.style.position = 'relative';
    }

    const expand = resizeSensor.childNodes[0];
    const expandChild = expand.childNodes[0];
    const shrink = resizeSensor.childNodes[1];

    let dirty;
    let rafId;
    let size = getElementSize(element);
    let lastWidth = size.width;
    let lastHeight = size.height;
    let initialHiddenCheck = true;
    let resetRafId;

    const resetExpandShrink = () => {
        expandChild.style.width = '100000px';
        expandChild.style.height = '100000px';

        expand.scrollLeft = 100000;
        expand.scrollTop = 100000;

        shrink.scrollLeft = 100000;
        shrink.scrollTop = 100000;
    };

    const reset = () => {
        // Check if element is hidden
        if (initialHiddenCheck) {
            if (!expand.scrollTop && !expand.scrollLeft) {
                // reset
                resetExpandShrink();

                // Check in next frame
                if (!resetRafId) {
                    resetRafId = requestAnimationFrame(() => {
                        resetRafId = 0;
                        reset();
                    });
                }

                return;
            }

            initialHiddenCheck = false;
        }

        resetExpandShrink();
    };
    resizeSensor.resetSensor = reset;

    const onResized = () => {
        rafId = 0;

        if (!dirty) {
            return;
        }

        lastWidth = size.width;
        lastHeight = size.height;

        if (element.resizedAttached) {
            element.resizedAttached.call(size);
        }
    };

    const onScroll = () => {
        size = getElementSize(element);
        dirty = size.width !== lastWidth || size.height !== lastHeight;

        if (dirty && !rafId) {
            rafId = requestAnimationFrame(onResized);
        }

        reset();
    };

    const addEvent = (elem, name, callback) => {
        elem.addEventListener(name, callback);
    };

    addEvent(expand, 'scroll', onScroll);
    addEvent(shrink, 'scroll', onScroll);

    // Fix for custom Elements
    requestAnimationFrame(reset);
}
@param {HTMLElement} element - element to listen resize.
@param {Function}    resizeListener - resize event listener.