export function formatLogElements()

in tools/chrome-debug-extension/src/helpers.ts [262:472]


export function formatLogElements(target: Object, tmLabel: string, key: string, level: number, textFilter: string, excludeKeys: string[], thingsReferenced?: any[], includeFunctions?:boolean): any {
    let openState = false;
    if (!level) {
        level = 0;
    }

    if (!thingsReferenced) {
        thingsReferenced = [];
    }

    let isObj = isObject(target) || Util.isError(target);
    let isErr = target && target["baseType"] && target["baseType"] === "ExceptionData" || Util.isError(target);

    const children: HTMLElement[] = [];

    function _openNode(currentLine: HTMLElement) {
        openState = true;
        arrForEach(children, (child) => {
            rootDiv.appendChild(child);
        });

        currentLine.className = "obj-key expandable open"
    }

    function _collapseNode(currentLine: HTMLElement) {
        // rootDiv.innerHTML = '';
        arrForEach(children, (child) => {
            rootDiv.removeChild(child);
        });
        // rootDiv.appendChild(currentLine);
        openState = false;
        currentLine.className = "obj-key expandable closed"
    }

    let matched: boolean;
    // Always displayed opened if there is no filter
    let childOpened = textFilter ? false : true;
    const keys = getTargetKeys(target, excludeKeys, includeFunctions as boolean);
    if (keys.length === 0) { keys.push("<empty>"); }
    if (level >= MAX_DEPTH) { keys.unshift("<maxdepth>"); }
    for (const key of keys) {
        if (excludeKeys.indexOf(key) !== -1) {
            continue;
        }

        let targetValue = target[key];
        if (isSymbol(targetValue)) {
            targetValue = targetValue.toString();
        }

        if (key === "<maxdepth>") {
            const builder = document.createElement("div");
            builder.className = "empty";
            builder.innerText = "<max allowed depth reached>";
            children.push(builder);
            break;
        }
        else if (key === "<empty>") {
            const builder = document.createElement("div");
            builder.className = "empty";
            builder.innerText = "<empty>";
            children.push(builder);
        }
        else if (targetValue !== null && arrIndexOf(thingsReferenced, targetValue) !== -1) {
            const builder = document.createElement("div");
            builder.className = "empty";
            builder.innerText = `<circular (${key}) - "${getTargetName(targetValue)}">`;
            children.push(builder);
        }
        else if (targetValue !== null && (isObject(targetValue) || Util.isError(targetValue))) {
            thingsReferenced.push(target);
            let formatted = formatLogElements(targetValue, "", key, level + 1, textFilter, excludeKeys, thingsReferenced, includeFunctions);
            thingsReferenced.pop();

            // Always displayed opened if there is no filter
            if (!textFilter || formatted.matched) {
                childOpened = true;
            }

            if (formatted.isErr) {
                isErr = true;
            }

            children.push(formatted.root);
        } else {
            const builder = document.createElement("div");
            builder.setAttribute("tabindex", "0");
            builder.onclick = (evt: MouseEvent) => {
                evt.stopPropagation();
            }
            builder.ontouchend = (evt: TouchEvent) => {
                evt.stopPropagation();
            }
            builder.onkeydown = (evt: KeyboardEvent) => {
                evt.stopPropagation();
                _navHandler(evt);
            }
            builder.onfocus = (evt: Event) => {
                focusHandler(evt, target, level, excludeKeys, includeFunctions as boolean);
            }

            const outerSpan = document.createElement("span");
            const keySpan = document.createElement("span");
            keySpan.className = "key";
            if (_setInnerText(keySpan, `${key}: `, textFilter)) {
                childOpened = true;
            }

            outerSpan.appendChild(keySpan);

            const valueSpan = document.createElement("span");
            if (isFunction(targetValue)) {
                const fnStr = targetValue.toString();
                const fnHead = fnStr.match(/^([^{]+)/)[1];
                valueSpan.textContent = `${fnHead}{...}`;
            } else {
                if (_setInnerText(valueSpan, `${targetValue}`, textFilter)) {
                    childOpened = true;
                }
            }
            valueSpan.className = `${typeof targetValue}`;
            outerSpan.appendChild(valueSpan);
            builder.appendChild(outerSpan);
            children.push(builder);
        }
    }

    const rootDiv = document.createElement("div");

    let innerText = "";
    let currentLine = document.createElement("span");
    if (isObj || children.length) {
        innerText = `${key ? key : "obj"}: `;
        if (Util.isArray(target)) {
            innerText += `[${getTargetKeys(target, excludeKeys, includeFunctions as boolean).length}]`;
        } else {
            let targetName = getTargetName(target);
            if (targetName) {
                innerText += ` <"${targetName}"> `
            }
            innerText += `{${getTargetKeys(target, excludeKeys, includeFunctions as boolean).length}}`;
        }

        matched = _setInnerText(currentLine, innerText, textFilter);

        if (tmLabel) {
            const tmWrapper = document.createElement("span");
            const tmDetails = document.createElement("span");
            tmDetails.className = "obj-time";
            tmDetails.innerText = tmLabel;
            tmWrapper.appendChild(tmDetails);
            tmWrapper.appendChild(currentLine);

            currentLine = tmWrapper;
        }

        currentLine.className = "obj-key expandable closed"
    } else {
        innerText = `${key ? key : "obj"}: ${target.toString()}`;
        matched = _setInnerText(currentLine, innerText, textFilter);

        currentLine.className = "obj-key";
    }

    rootDiv.appendChild(currentLine);
    rootDiv.setAttribute("tabindex", "0");

    if (childOpened) {
        // A child node matched so auto-expand
        _openNode(currentLine);
    }
    if (isObj) {
        if (isErr) { rootDiv.className = "exception" }
        const openHandler = (evt: Event, forceState?: boolean) => {
            evt.stopPropagation();
            if (Util.getIEVersion()) {
                focusHandler(evt, target, level, excludeKeys, includeFunctions as boolean);
            }
            if (forceState !== undefined && openState === forceState) {
                return;
            }
            if (lastSelectedElement === rootDiv) {
                if (openState) {
                    _collapseNode(currentLine);
                }
                else {
                    _openNode(currentLine);
                }
            }
        }

        rootDiv.onkeydown = (evt: KeyboardEvent) => {
            _navHandler(evt, openHandler, openState);
        }
        rootDiv.onclick = (evt: MouseEvent) => {
            openHandler(evt);
        }
        rootDiv.ontouchend = (evt: TouchEvent) => {
            openHandler(evt);
        }
        rootDiv.onfocus = (evt: Event) => {
            focusHandler(evt, target, level, excludeKeys, includeFunctions as boolean);
        }
    }

    return {
        root: rootDiv,
        isErr: isErr,
        matched: matched || childOpened
    };
}