Merge pull request #22490 from colemanw/refreshButton
[civicrm-core.git] / ang / crmMonaco.js
CommitLineData
1aac4625 1(function(angular, $, _) {
9a78af90 2 angular.module('crmMonaco', CRM.angRequires('crmMonaco'));
1aac4625 3
9a78af90
TO
4 // "crmMonaco" is a basic skeletal directive.
5 // Example usage: <div crm-monaco ng-model="my.content"></div>
f1291614
TO
6 // Example usage: <div crm-monaco="{readOnly: true}" ng-model="my.content"></div>
7 angular.module('crmMonaco').directive('crmMonaco', function($timeout, $parse) {
1aac4625
TO
8 return {
9 restrict: 'AE',
687bc834 10 require: ['ngModel', 'crmMonaco'],
9a78af90 11 template: '<div class="crm-monaco-container"></div>',
687bc834
TO
12 controller: function() {
13 this.editor = null; // Filled in by link().
14 },
15 link: function($scope, $el, $attr, controllers) {
16 var ngModel = controllers[0], crmMonaco = controllers[1];
6cb689b3 17 var heightPct = 0.70;
1aac4625 18 var editor;
9a78af90 19 require.config({paths: CRM.crmMonaco.paths});
1aac4625 20 require(['vs/editor/editor.main'], function() {
f1291614
TO
21 var options = {
22 readOnly: false,
1aac4625 23 language: 'html',
6cb689b3 24 // theme: 'vs-dark',
f1291614
TO
25 theme: 'vs'
26 };
27 if ($attr.crmMonaco) {
28 angular.extend(options, $parse($attr.crmMonaco)($scope));
29 }
30 angular.extend(options, {
31 value: ngModel.$modelValue,
1aac4625
TO
32 minimap: {
33 enabled: false
85933a02 34 },
6cb689b3 35 automaticLayout: true,
85933a02
TO
36 scrollbar: {
37 useShadows: false,
38 verticalHasArrows: true,
39 horizontalHasArrows: true,
40 vertical: 'visible',
41 horizontal: 'visible',
42 verticalScrollbarSize: 17,
43 horizontalScrollbarSize: 17,
44 arrowSize: 30
1aac4625
TO
45 }
46 });
47
64d0a548
TO
48 heightPct = options.crmHeightPct || heightPct;
49 delete options.crmHeightPct;
50
f1291614
TO
51 var editorEl = $el.find('.crm-monaco-container');
52 editorEl.css({height: Math.round(heightPct * $(window).height())});
53 editor = monaco.editor.create(editorEl[0], options);
54
1aac4625
TO
55 editor.onDidChangeModelContent(_.debounce(function () {
56 $scope.$apply(function () {
57 ngModel.$setViewValue(editor.getValue());
58 });
59 }, 150));
60
61 ngModel.$render = function() {
62 if (editor) {
63 editor.setValue(ngModel.$modelValue);
64 }
65 // FIXME: else: retry?
66 };
67
2a9c42ba
TO
68 if ($attr.ngDisabled) {
69 $scope.$watch($parse($attr.ngDisabled), function(disabled){
70 editor.updateOptions({readOnly: disabled});
71 });
72 }
73
90cd1ece
TO
74 // FIXME: This makes vertical scrolling much better, but horizontal is still weird.
75 var origOverflow;
76 function bodyScrollSuspend() {
77 if (origOverflow !== undefined) return;
78 origOverflow = $('body').css('overflow');
79 $('body').css('overflow', 'hidden');
80 }
81 function bodyScrollRestore() {
82 if (origOverflow === undefined) return;
83 $('body').css('overflow', origOverflow);
84 origOverflow = undefined;
85 }
86 editorEl.on('mouseenter', bodyScrollSuspend);
87 editorEl.on('mouseleave', bodyScrollRestore);
88 editor.onDidFocusEditorWidget(bodyScrollSuspend);
89 editor.onDidBlurEditorWidget(bodyScrollRestore);
90
687bc834
TO
91 crmMonaco.editor = editor;
92
1aac4625 93 $scope.$on('$destroy', function () {
90cd1ece 94 bodyScrollRestore();
1aac4625 95 if (editor) editor.dispose();
687bc834 96 delete crmMonaco.editor;
1aac4625
TO
97 });
98 });
99 }
100 };
101 });
102
341a2441
TO
103 angular.module('crmMonaco').directive('crmMonacoInsertRx', function() {
104 return {
105 require: 'crmMonaco',
106 link: function(scope, element, attrs, crmMonaco) {
107 scope.$on(attrs.crmMonacoInsertRx, function(e, tokenName) {
108 var editor = crmMonaco.editor;
109 var id = { major: 1, minor: 1 };
110 var op = {identifier: id, range: editor.getSelection(), text: tokenName, forceMoveMarkers: true};
111 editor.executeEdits("tokens", [op]);
112 editor.focus();
113 });
114 }
115 };
116 });
117
1aac4625 118})(angular, CRM.$, CRM._);