function link()

in ui-modules/utils/yaml-editor/yaml-editor.js [54:199]


    function link($scope, $element) {
        $scope.type = $scope.type || 'brooklyn';

        // Init CodeMirror
        CodeMirror.extendMode('yaml', {
            fold: 'indent',
            type: $scope.type
        });

        let lint = (text, cb, options, cm) => {
            let promises = cm.getHelpers(CodeMirror.Pos(0, 0), 'lint').reduce((issues, helper) => issues.concat(helper(text, options, cm)), []);

            Promise.all(promises).then(issues => {
                let issuesReduced = issues.reduce((acc, arr) => {
                    acc.push(...arr);
                    return acc;
                }, []);
                $rootScope.$broadcast('yaml.lint', issuesReduced.some(issue => !issue.severity || issue.severity === 'error'), cm.getValue());
                cb(cm, issuesReduced);
            });
        }
        let hint = (cm, callback, options) => {
            let loadingState = createLoadingState();
            let removeLoadingState = () => {
                if (loadingState) {
                    loadingState.remove();
                }
                cm.off('cursorActivity', removeLoadingState);
            };

            cm.on('cursorActivity', removeLoadingState);
            cm.addWidget(cm.getCursor(), loadingState);

            let promises = cm.getHelpers(CodeMirror.Pos(0, 0), 'hint').reduce((promises, helper) => promises.concat(helper(cm, options)), []);

            Promise.all(promises).then(results => {
                removeLoadingState();

                callback(results.reduce((hints, result) => {
                    let list = hints.list.concat(result.list);
                    list.sort();
                    return Object.assign(hints, result, {list: list});
                }, {list: []}));
            }).catch(error => {
                removeLoadingState();

                $scope.$apply(() => {
                    brSnackbar.create(error.message);
                });

                callback({
                    list: [],
                    from: cm.getCursor(),
                    to: cm.getCursor()
                });
            });
        };
        hint.async = true;

        let createLoadingState = () => {
            let loadingState = document.createElement('ul');
            loadingState.className = 'CodeMirror-hints';
            let loading = loadingState.appendChild(document.createElement('li'));
            loading.className = 'CodeMirror-hint CodeMirror-hint-loading';
            loading.appendChild(document.createTextNode('Loading'));

            return loadingState;
        };

        $scope.cm = new CodeMirror($element[0], {
            value: $scope.value || '',
            styleActiveLine: true,
            matchBrackets: true,
            theme: 'eclipse',
            lineNumbers: true,
            lineWrapping: true,
            foldGutter: true,
            gutters: ['CodeMirror-linenumbers', 'CodeMirror-lint-markers', 'CodeMirror-foldgutter'],
            mode: {
                name: 'yaml',
                globalVars: true
            },
            lint: {
                getAnnotations: lint,
                async: true,
                timeout: 1000
            },
            extraKeys: {
                'Ctrl-Space': 'autocomplete',
                'Tab': cm => {
                    let wideSelection = cm.listSelections().reduce((acc, range) => {
                        if ((range.anchor.line !== range.head.line) || (range.anchor.ch !== range.head.ch)) {
                            return acc || true;
                        }
                        return acc;
                    }, false);

                    if (wideSelection) {
                        CodeMirror.commands.indentMore(cm);
                    } else {
                        cm.replaceSelection('  ', 'end');
                    }
                }
            },
            foldOptions: {
                widget: '{ ... }'
            }
        });
        $scope.cm.on('changes', (cm, change)=> {
            if ($scope.value !== cm.getValue()) {
                $scope.$apply(()=> {
                    $scope.value = cm.getValue();
                    let fn = $scope.onChange();
                    if (angular.isFunction(fn)) {
                        fn(cm);
                    }
                });
            }
        });
        $scope.cm.on('superhint-error', (error) => {
            $scope.$apply(()=> {
                brSnackbar.create(error.message);
            });
        });

        $scope.$watch('value', (newVal, oldVal)=> {
            $scope.cm.getDoc();
            $scope.cm.focus();
            if ($scope.cm.getValue() !== newVal && angular.isDefined(newVal)) {
                $scope.cm.setValue(newVal);
                if ($scope.resetToEndOnExternalValueSet) {
                    $scope.cm.setCursor($scope.cm.lineCount(), 0);
                }
            }
            setTimeout(()=> {
                $scope.cm.focus();
                $scope.cm.refresh();
            });
        });

        $scope.$on(`${MODULE_NAME}.cm`, (event, callback) => {
            if (angular.isFunction(callback)) {
                callback.apply(null, [CodeMirror, $scope.cm]);
            }
        });
    }