All files / services/editor-factory editor-factory.service.ts

80.76% Statements 21/26
0% Branches 0/3
37.5% Functions 3/8
79.16% Lines 19/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 3x       3x 3x     3x                                                                                             3x     3x        
import { russianPhrases } from '../../constants/editor-phrases';
import { continueLists, decreaseListIndent, increaseListIndent } from '../../helpers/list-commands';
import { quoteKeymap } from '../../helpers/quote-commands';
import { WikiHighlighterService } from '../wiki-highlighter/wiki-highlighter.service';
import { isPlatformServer } from '@angular/common';
import { inject, Injectable, PLATFORM_ID } from '@angular/core';
import { closeBrackets } from '@codemirror/autocomplete';
import { history, defaultKeymap, historyKeymap } from '@codemirror/commands';
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from '@codemirror/language';
import { openSearchPanel, search, searchKeymap } from '@codemirror/search';
import { EditorState, Extension } from '@codemirror/state';
import { drawSelection, dropCursor, EditorView, highlightSpecialChars, keymap, ViewUpdate } from '@codemirror/view';
 
@Injectable()
export class EditorFactoryService {
    private changeHandler: (text: string) => void = () => {
        // Should be changed by setChangeHandler
    };
 
    private readonly wikiHighlighter = inject(WikiHighlighterService);
    private readonly platformId = inject<object>(PLATFORM_ID);
 
    public isServer(): boolean {
        return isPlatformServer(this.platformId);
    }
 
    public createState(doc: string, customExtensions: Extension[] = []): EditorState {
        return EditorState.create({
            doc,
            extensions: [
                EditorState.phrases.of(russianPhrases),
                highlightSpecialChars(),
                drawSelection(),
                dropCursor(),
                syntaxHighlighting(defaultHighlightStyle),
                indentOnInput(),
                EditorView.lineWrapping,
                history(),
                closeBrackets(),
                bracketMatching(),
                this.wikiHighlighter.wikiHighlighter,
                // listener
                EditorView.updateListener.of((v: ViewUpdate) => {
                    if (v.docChanged) {
                        this.onContentChanged(v.state.doc.toString());
                    }
                }),
                keymap.of([
                    { key: 'Enter', run: continueLists },
                    { key: 'Tab', run: increaseListIndent },
                    { key: 'Shift-Tab', run: decreaseListIndent },
                    ...defaultKeymap,
                    ...historyKeymap,
                    ...searchKeymap,
                    ...quoteKeymap,
                    { key: 'Mod-f', run: openSearchPanel },
                ]),
                search({
                    scrollToMatch: ({ from }) =>
                        EditorView.scrollIntoView(from, {
                            y: 'start',
                            x: 'nearest',
                        }),
                }),
                ...customExtensions,
            ],
        });
    }
 
    public setChangeHandler(handler: (text: string) => void): void {
        this.changeHandler = handler;
    }
 
    private onContentChanged = (text: string) => {
        this.changeHandler(text);
    };
}