import { SearchQuery, closeSearchPanel, findNext, findPrevious, getSearchQuery, replaceAll, replaceNext, search, searchKeymap, searchPanelOpen, setSearchQuery, } from '@codemirror/search';
import { ViewPlugin, keymap, } from '@codemirror/view';
import { renderSearchPopup } from "../../../modules/search/index.js";
import { ReactRendererFacet } from "../react-facet.js";
import { searchTheme } from "./theme.js";
export const SearchPanelPlugin = (params) => ViewPlugin.fromClass(class {
    view;
    params;
    renderer;
    receiver;
    panelOpened;
    searchState;
    constructor(view) {
        this.view = view;
        this.params = params;
        this.receiver = params.receiver;
        this.panelOpened = searchPanelOpen(view.state);
        this.searchState = getSearchQuery(view.state);
        this.renderer = this.createRenderer();
        this.handleClose = this.handleClose.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleSearchNext = this.handleSearchNext.bind(this);
        this.handleSearchPrev = this.handleSearchPrev.bind(this);
        this.handleReplaceNext = this.handleReplaceNext.bind(this);
        this.handleReplaceAll = this.handleReplaceAll.bind(this);
        this.handleEditorModeChange = this.handleEditorModeChange.bind(this);
        this.receiver?.on('change-editor-mode', this.handleEditorModeChange);
    }
    update(update) {
        const isPanelOpen = searchPanelOpen(update.state);
        const searchQuery = getSearchQuery(update.state);
        if (isPanelOpen !== this.panelOpened || searchQuery !== this.searchState) {
            this.panelOpened = isPanelOpen;
            this.searchState = searchQuery;
            this.renderer.rerender();
        }
    }
    destroy() {
        this.renderer.remove();
        this.receiver?.off('change-editor-mode', this.handleEditorModeChange);
    }
    createRenderer() {
        return this.view.state.facet(ReactRendererFacet).createItem('cm-search', () => {
            if (!this.panelOpened || !this.searchState)
                return null;
            const { dom: viewDom } = this.view;
            const container = (params.editorSelector && viewDom.closest(params.editorSelector)) ||
                viewDom.ownerDocument;
            const anchor = container.querySelector(params.anchorSelector);
            if (!anchor)
                return null;
            return renderSearchPopup({
                open: true,
                anchor: anchor,
                state: this.searchState,
                onClose: this.handleClose,
                onChange: this.handleChange,
                onSearchNext: this.handleSearchNext,
                onSearchPrev: this.handleSearchPrev,
                onReplaceNext: this.handleReplaceNext,
                onReplaceAll: this.handleReplaceAll,
                intersectionTracking: {
                    container: this.view.contentDOM,
                    selector: '.cm-searchMatch-selected',
                    observerOptions: {
                        childList: true,
                        subtree: true,
                        attributes: true,
                        attributeFilter: ['class'],
                    },
                },
            });
        });
    }
    handleEditorModeChange({ mode }) {
        if (mode === 'wysiwyg') {
            closeSearchPanel(this.view);
        }
    }
    handleChange(config) {
        this.view.dispatch({
            effects: setSearchQuery.of(new SearchQuery({
                search: config.search,
                replace: config.replace,
                caseSensitive: config.caseSensitive,
                wholeWord: config.wholeWord,
            })),
        });
    }
    handleClose() {
        this.handleChange({ search: '' });
        closeSearchPanel(this.view);
        this.view.focus();
    }
    handleSearchNext() {
        findNext(this.view);
    }
    handleSearchPrev() {
        findPrevious(this.view);
    }
    handleReplaceNext() {
        replaceNext(this.view);
    }
    handleReplaceAll() {
        replaceAll(this.view);
    }
}, {
    provide: () => [
        keymap.of(searchKeymap),
        searchTheme,
        search({
            createPanel: () => ({
                // Create an empty search panel
                dom: document.createElement('div'),
            }),
        }),
    ],
});
//# sourceMappingURL=plugin.js.map
