Example #1
0
  function setLangMode(lang: string) {
    ace.acequire('ace/ext/language_tools');
    codeEditor.setOptions({
      enableBasicAutocompletion: true,
      enableLiveAutocompletion: true,
      enableSnippets: snippetsEnabled,
    });

    if (scope.getCompleter()) {
      // make copy of array as ace seems to share completers array between instances
      const anyEditor = codeEditor as any;
      anyEditor.completers = anyEditor.completers.slice();
      anyEditor.completers.push(scope.getCompleter());
    }

    const aceModeName = `ace/mode/${lang}`;
    editorSession.setMode(aceModeName);
  }
Example #2
0
export default function previewPanelDirective($interval: ng.IIntervalService, $timeout: ng.ITimeoutService) {
    let animation = {editor: null, stage: 0, start: 0, stop: 0};
    let prevContent = [];

    const Range = ace.acequire('ace/range').Range;

    const _clearSelection = (editor) => {
        _.forEach(editor.session.getMarkers(false), (marker) => {
            editor.session.removeMarker(marker.id);
        });
    };

    /**
     * Switch to next stage of animation.
     */
    const _animate = () => {
        animation.stage += animation.step;

        const stage = animation.stage;
        const editor = animation.editor;

        _clearSelection(editor);

        animation.selections.forEach((selection) => {
            editor.session.addMarker(new Range(selection.start, 0, selection.stop, 0),
                'preview-highlight-' + stage, 'line', false);
        });

        if (stage === animation.finalStage) {
            editor.animatePromise = null;

            if (animation.clearOnFinal)
                _clearSelection(editor);
        }
    };

    /**
     * Selection with animation.
     *
     * @param editor Editor to show selection animation.
     * @param selections Array of selection intervals.
     * @param step Step of animation (1 or -1).
     * @param stage Start stage of animation.
     * @param finalStage Final stage of animation.
     * @param clearOnFinal Boolean flat to clear selection on animation finish.
     */
    const _fade = (editor, selections, step, stage, finalStage, clearOnFinal) => {
        const promise = editor.animatePromise;

        if (promise) {
            $interval.cancel(promise);

            _clearSelection(editor);
        }

        animation = {editor, selections, step, stage, finalStage, clearOnFinal};

        editor.animatePromise = $interval(_animate, 100, 10, false);
    };

    /**
     * Show selections with animation.
     *
     * @param editor Editor to show selection.
     * @param selections Array of selection intervals.
     */
    const _fadeIn = (editor, selections) => {
        _fade(editor, selections, 1, 0, 10, false);
    };

    /**
     * Hide selections with animation.
     *
     * @param editor Editor to show selection.
     * @param selections Array of selection intervals.
     */
    const _fadeOut = (editor, selections) => {
        _fade(editor, selections, -1, 10, 0, true);
    };

    const onChange = ([content, editor]) => {
        const {clearPromise} = editor;
        const {lines} = content;

        if (content.action === 'remove')
            prevContent = lines;
        else if (prevContent.length > 0 && lines.length > 0 && editor.attractAttention) {
            if (clearPromise) {
                $timeout.cancel(clearPromise);

                _clearSelection(editor);
            }

            const selections = [];

            let newIx = 0;
            let prevIx = 0;

            let prevLen = prevContent.length - (prevContent[prevContent.length - 1] === '' ? 1 : 0);
            let newLen = lines.length - (lines[lines.length - 1] === '' ? 1 : 0);

            const removed = newLen < prevLen;

            let skipEnd = 0;

            let selected = false;
            let scrollTo = -1;

            while (lines[newLen - 1] === prevContent[prevLen - 1] && newLen > 0 && prevLen > 0) {
                prevLen -= 1;
                newLen -= 1;

                skipEnd += 1;
            }

            while (newIx < newLen || prevIx < prevLen) {
                let start = -1;
                let stop = -1;

                // Find an index of a first line with different text.
                for (; (newIx < newLen || prevIx < prevLen) && start < 0; newIx++, prevIx++) {
                    if (newIx >= newLen || prevIx >= prevLen || lines[newIx] !== prevContent[prevIx]) {
                        start = newIx;

                        break;
                    }
                }

                if (start >= 0) {
                    // Find an index of a last line with different text by checking last string of old and new content in reverse order.
                    for (let i = start; i < newLen && stop < 0; i++) {
                        for (let j = prevIx; j < prevLen && stop < 0; j++) {
                            if (lines[i] === prevContent[j] && lines[i] !== '') {
                                stop = i;

                                newIx = i;
                                prevIx = j;

                                break;
                            }
                        }
                    }

                    if (stop < 0) {
                        stop = newLen;

                        newIx = newLen;
                        prevIx = prevLen;
                    }

                    if (start === stop) {
                        if (removed)
                            start = Math.max(0, start - 1);

                        stop = Math.min(newLen + skipEnd, stop + 1);
                    }

                    if (start <= stop) {
                        selections.push({start, stop});

                        if (!selected)
                            scrollTo = start;

                        selected = true;
                    }
                }
            }

            // Run clear selection one time.
            if (selected) {
                _fadeIn(editor, selections);

                editor.clearPromise = $timeout(() => {
                    _fadeOut(editor, selections);

                    editor.clearPromise = null;
                }, 2000);

                editor.scrollToRow(scrollTo);
            }

            prevContent = [];
        }
        else
            editor.attractAttention = true;
    };


    const link = (scope, $element, $attrs, [igniteUiAceTabs1, igniteUiAceTabs2]) => {
        const igniteUiAceTabs = igniteUiAceTabs1 || igniteUiAceTabs2;

        if (!igniteUiAceTabs)
            return;

        igniteUiAceTabs.onLoad = (editor) => {
            editor.setReadOnly(true);
            editor.setOption('highlightActiveLine', false);
            editor.setAutoScrollEditorIntoView(true);
            editor.$blockScrolling = Infinity;
            editor.attractAttention = false;

            const renderer = editor.renderer;

            renderer.setHighlightGutterLine(false);
            renderer.setShowPrintMargin(false);
            renderer.setOption('fontSize', '10px');
            renderer.setOption('maxLines', '50');

            editor.setTheme('ace/theme/chrome');
        };

        igniteUiAceTabs.onChange = onChange;
    };

    return {
        restrict: 'C',
        link,
        require: ['?igniteUiAceTabs', '?^igniteUiAceTabs']
    };
}