"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchPanelPlugin = void 0;
const search_1 = require("@codemirror/search");
const view_1 = require("@codemirror/view");
const search_2 = require("../../../modules/search/index.js");
const react_facet_1 = require("../react-facet.js");
const theme_1 = require("./theme.js");
const SearchPanelPlugin = (params) => view_1.ViewPlugin.fromClass(class {
    view;
    params;
    renderer;
    receiver;
    panelOpened;
    searchState;
    constructor(view) {
        this.view = view;
        this.params = params;
        this.receiver = params.receiver;
        this.panelOpened = (0, search_1.searchPanelOpen)(view.state);
        this.searchState = (0, search_1.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 = (0, search_1.searchPanelOpen)(update.state);
        const searchQuery = (0, search_1.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(react_facet_1.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 (0, search_2.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') {
            (0, search_1.closeSearchPanel)(this.view);
        }
    }
    handleChange(config) {
        this.view.dispatch({
            effects: search_1.setSearchQuery.of(new search_1.SearchQuery({
                search: config.search,
                replace: config.replace,
                caseSensitive: config.caseSensitive,
                wholeWord: config.wholeWord,
            })),
        });
    }
    handleClose() {
        this.handleChange({ search: '' });
        (0, search_1.closeSearchPanel)(this.view);
        this.view.focus();
    }
    handleSearchNext() {
        (0, search_1.findNext)(this.view);
    }
    handleSearchPrev() {
        (0, search_1.findPrevious)(this.view);
    }
    handleReplaceNext() {
        (0, search_1.replaceNext)(this.view);
    }
    handleReplaceAll() {
        (0, search_1.replaceAll)(this.view);
    }
}, {
    provide: () => [
        view_1.keymap.of(search_1.searchKeymap),
        theme_1.searchTheme,
        (0, search_1.search)({
            createPanel: () => ({
                // Create an empty search panel
                dom: document.createElement('div'),
            }),
        }),
    ],
});
exports.SearchPanelPlugin = SearchPanelPlugin;
//# sourceMappingURL=plugin.js.map
