{"version":3,"sources":["../../../../src/visualBuilder/generators/generateToolbar.tsx"],"sourcesContent":["import React from \"preact/compat\";\nimport { VisualBuilderCslpEventDetails } from \"../types/visualBuilder.types\";\nimport {\n    DATA_CSLP_ATTR_SELECTOR,\n    LIVE_PREVIEW_OUTLINE_WIDTH_IN_PX,\n    RIGHT_EDGE_BUFFER,\n    TOOLBAR_EDGE_BUFFER,\n    TOP_EDGE_BUFFER,\n} from \"../utils/constants\";\nimport FieldToolbarComponent from \"../components/FieldToolbar\";\nimport { render } from \"preact\";\nimport FieldLabelWrapperComponent from \"../components/fieldLabelWrapper\";\nimport { VisualBuilderPostMessageEvents } from \"../utils/types/postMessage.types\";\nimport visualBuilderPostMessage from \"../utils/visualBuilderPostMessage\";\nimport { fetchEntryPermissionsAndStageDetails } from \"../utils/fetchEntryPermissionsAndStageDetails\";\n\nexport function appendFocusedToolbar(\n    eventDetails: VisualBuilderCslpEventDetails,\n    focusedToolbarElement: HTMLDivElement,\n    hideOverlay: () => void,\n    isVariant: boolean = false,\n    options?: {\n        isHover?: boolean;\n    }\n): void {\n    appendFieldPathDropdown(eventDetails, focusedToolbarElement, options);\n    if(options?.isHover) {\n        return;\n    }\n    appendFieldToolbar(\n        eventDetails,\n        focusedToolbarElement,\n        hideOverlay,\n        isVariant\n    );\n}\n\nexport async function appendFieldToolbar(\n    eventDetails: VisualBuilderCslpEventDetails,\n    focusedToolbarElement: HTMLDivElement,\n    hideOverlay: () => void,\n    isVariant: boolean = false,\n    options?: {\n        isHover?: boolean;\n    }\n): Promise<void> {\n    const { isHover } = options || {};\n    if (\n        focusedToolbarElement.querySelector(\n            \".visual-builder__focused-toolbar__multiple-field-toolbar\"\n        ) && !isHover\n    )\n        return;\n    const { acl: entryPermissions, workflowStage: entryWorkflowStageDetails, resolvedVariantPermissions } =\n        await fetchEntryPermissionsAndStageDetails({\n            entryUid: eventDetails.fieldMetadata.entry_uid,\n            contentTypeUid: eventDetails.fieldMetadata.content_type_uid,\n            locale: eventDetails.fieldMetadata.locale,\n            variantUid: eventDetails.fieldMetadata.variant,\n            fieldPathWithIndex: eventDetails.fieldMetadata.fieldPathWithIndex,\n        });\n    const wrapper = document.createDocumentFragment();\n    render(\n        <FieldToolbarComponent\n            eventDetails={eventDetails}\n            hideOverlay={hideOverlay}\n            isVariant={isVariant}\n            entryPermissions={entryPermissions}\n            entryWorkflowStageDetails={entryWorkflowStageDetails}\n            resolvedVariantPermissions={resolvedVariantPermissions}\n        />,\n        wrapper\n    );\n    focusedToolbarElement.append(wrapper);\n}\n\nexport function appendFieldPathDropdown(\n    eventDetails: VisualBuilderCslpEventDetails,\n    focusedToolbarElement: HTMLDivElement,\n    options?: {\n        isHover?: boolean;\n    }\n): void {\n    const { isHover } = options || {};\n    const fieldLabelWrapper = document.querySelector(\n        \".visual-builder__focused-toolbar__field-label-wrapper\"\n    ) as HTMLDivElement | null;\n    const { editableElement: targetElement, fieldMetadata } = eventDetails;\n\n    if (fieldLabelWrapper) {\n        if(isHover) {\n            const fieldCslp = fieldLabelWrapper.getAttribute(\"data-hovered-cslp\");\n            if(fieldCslp === fieldMetadata.cslpValue) {\n                return;\n            } else {\n                removeFieldToolbar(focusedToolbarElement);\n            }\n        } else {\n            return;\n        }\n    }\n    \n    const targetElementDimension = targetElement.getBoundingClientRect();\n\n    const distanceFromTop =\n        targetElementDimension.top + window.scrollY - TOOLBAR_EDGE_BUFFER;\n    // Position the toolbar at the top unless there's insufficient space or scrolling up is not possible (topmost element targetted).\n    const adjustedDistanceFromTop =\n        targetElementDimension.top + window.scrollY < TOP_EDGE_BUFFER\n            ? distanceFromTop + targetElementDimension.height + TOP_EDGE_BUFFER\n            : distanceFromTop;\n\n    const distanceFromLeft =\n        targetElementDimension.left - LIVE_PREVIEW_OUTLINE_WIDTH_IN_PX;\n    const adjustedDistanceFromLeft = Math.max(\n        distanceFromLeft,\n        TOOLBAR_EDGE_BUFFER\n    );\n\n    const targetElementRightEdgeOffset =\n        window.scrollX + window.innerWidth - targetElementDimension.left;\n\n    if (targetElementRightEdgeOffset < RIGHT_EDGE_BUFFER) {\n        // Overflow / Cutoff on right edge\n        focusedToolbarElement.style.justifyContent = \"flex-end\";\n        focusedToolbarElement.style.left = `${\n            targetElementDimension.right + LIVE_PREVIEW_OUTLINE_WIDTH_IN_PX\n        }px`;\n    } else {\n        focusedToolbarElement.style.justifyContent = \"flex-start\"; // default\n        focusedToolbarElement.style.left = `${adjustedDistanceFromLeft}px`;\n    }\n\n    focusedToolbarElement.style.top = `${adjustedDistanceFromTop}px`;\n\n    const parentPaths = collectParentCSLPPaths(targetElement, 2);\n\n    const wrapper = document.createDocumentFragment();\n    render(\n        <FieldLabelWrapperComponent\n            fieldMetadata={fieldMetadata}\n            eventDetails={eventDetails}\n            parentPaths={parentPaths}\n            getParentEditableElement={(cslp: string) => {\n                const parentElement = targetElement.closest(\n                    `[${DATA_CSLP_ATTR_SELECTOR}=\"${cslp}\"]`\n                ) as HTMLElement | null;\n                return parentElement;\n            }}\n        />,\n        wrapper\n    );\n\n    focusedToolbarElement.appendChild(wrapper);\n}\n\nfunction collectParentCSLPPaths(\n    targetElement: Element,\n    count: number\n): Array<string> {\n    const cslpPaths: Array<string> = [];\n    let currentElement = targetElement.parentElement;\n\n    while (count > 0 || currentElement === window.document.body) {\n        if (!currentElement) {\n            return cslpPaths;\n        }\n\n        if (currentElement.hasAttribute(DATA_CSLP_ATTR_SELECTOR)) {\n            cslpPaths.push(\n                currentElement.getAttribute(DATA_CSLP_ATTR_SELECTOR) as string\n            );\n            count--;\n        }\n        currentElement = currentElement.parentElement;\n    }\n\n    return cslpPaths;\n}\n\nexport function removeFieldToolbar(toolbar: Element) {\n    toolbar.innerHTML = \"\";\n    const toolbarEvents = [\n        VisualBuilderPostMessageEvents.DELETE_INSTANCE,\n        VisualBuilderPostMessageEvents.UPDATE_DISCUSSION_ID,\n        VisualBuilderPostMessageEvents.FIELD_LOCATION_DATA\n    ];\n    toolbarEvents.forEach((event) => {\n        //@ts-expect-error - We are accessing private method here, but it is necessary to clean up the event listeners.\n        if (visualBuilderPostMessage?.requestMessageHandlers?.has(event)) {\n            //@ts-expect-error - We are accessing private method here, but it is necessary to clean up the event listeners.\n            visualBuilderPostMessage?.unregisterEvent?.(event);\n        }\n    });\n}\n"],"mappings":"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","names":["FieldToolbarComponent","FieldLabelWrapperComponent","visualBuilderPostMessage"]}