import { emptyElement, isDefined } from '@slickgrid-universal/utils';
/**
 * Apply HTML code by 3 different ways depending on what is provided as input and what options are enabled.
 * 1. value is an HTMLElement or DocumentFragment, then first empty the target and simply append the HTML to the target element.
 * 2. value is string and `enableHtmlRendering` is enabled, then use `target.innerHTML = value;`
 * 3. value is string and `enableHtmlRendering` is disabled, then use `target.textContent = value;`
 * @param target - target element to apply to
 * @param val - input value can be either a string or an HTMLElement
 * @param options -
 *  - `emptyTarget`, defaults to true, will empty the target.
 *  - `enableHtmlRendering` do we want to render using `innerHTML` (ideally sanitize the data prior to assignment).
 *  - `skipEmptyReassignment`, defaults to true, when enabled it will not try to reapply an empty value when the target is already empty
 *  - `sanitizer` when using `innerHTML` what sanitizer should we use?
 */
export function applyHtmlToElement(target, val = '', options) {
    if (target) {
        if (val instanceof HTMLElement || val instanceof DocumentFragment) {
            // first empty target and then append new HTML element
            const emptyTarget = options?.emptyTarget !== false;
            if (emptyTarget) {
                emptyElement(target);
            }
            target.appendChild(val);
        }
        else {
            // when it's already empty and we try to reassign empty, it's probably ok to skip the assignment
            const skipEmptyReassignment = options?.skipEmptyReassignment !== false;
            if (skipEmptyReassignment && !isDefined(val) && !target.innerHTML) {
                return; // same result, just skip it
            }
            if (typeof val === 'number' || typeof val === 'boolean') {
                target.textContent = String(val);
            }
            else {
                const sanitizeHtmlString = (dirtyHtml) => {
                    if (typeof options?.sanitizer !== 'function' || !dirtyHtml || typeof dirtyHtml !== 'string') {
                        return dirtyHtml;
                    }
                    return options.sanitizer(dirtyHtml);
                };
                const sanitizedText = sanitizeHtmlString(val);
                // apply HTML when enableHtmlRendering is enabled
                // but make sure we do have a value (without a value, it will simply use `textContent` to clear text content)
                if (options?.enableHtmlRendering && sanitizedText) {
                    target.innerHTML = sanitizedText;
                }
                else {
                    target.textContent = sanitizedText;
                }
            }
        }
    }
}
/**
 * Sanitize possible dirty html string (remove any potential XSS code like scripts and others) when a `sanitizer` is provided via grid options.
 * The logic will only call the sanitizer if it exists and the value is a defined string, anything else will be skipped (number, boolean, TrustedHTML will all be skipped)
 * @param {*} dirtyHtml: dirty html string
 * @param {(dirtyHtml: String) => string | TrustedHTML} [sanitizer] - optional sanitizer function
 */
export function runOptionalHtmlSanitizer(dirtyHtml, sanitizer) {
    if (typeof sanitizer !== 'function' || !dirtyHtml || typeof dirtyHtml !== 'string') {
        return dirtyHtml;
    }
    return sanitizer(dirtyHtml);
}
//# sourceMappingURL=utils.js.map