Commit | Line | Data |
---|---|---|
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 | ||
90cd1ece TO |
68 | // FIXME: This makes vertical scrolling much better, but horizontal is still weird. |
69 | var origOverflow; | |
70 | function bodyScrollSuspend() { | |
71 | if (origOverflow !== undefined) return; | |
72 | origOverflow = $('body').css('overflow'); | |
73 | $('body').css('overflow', 'hidden'); | |
74 | } | |
75 | function bodyScrollRestore() { | |
76 | if (origOverflow === undefined) return; | |
77 | $('body').css('overflow', origOverflow); | |
78 | origOverflow = undefined; | |
79 | } | |
80 | editorEl.on('mouseenter', bodyScrollSuspend); | |
81 | editorEl.on('mouseleave', bodyScrollRestore); | |
82 | editor.onDidFocusEditorWidget(bodyScrollSuspend); | |
83 | editor.onDidBlurEditorWidget(bodyScrollRestore); | |
84 | ||
687bc834 TO |
85 | crmMonaco.editor = editor; |
86 | ||
1aac4625 | 87 | $scope.$on('$destroy', function () { |
90cd1ece | 88 | bodyScrollRestore(); |
1aac4625 | 89 | if (editor) editor.dispose(); |
687bc834 | 90 | delete crmMonaco.editor; |
1aac4625 TO |
91 | }); |
92 | }); | |
93 | } | |
94 | }; | |
95 | }); | |
96 | ||
341a2441 TO |
97 | angular.module('crmMonaco').directive('crmMonacoInsertRx', function() { |
98 | return { | |
99 | require: 'crmMonaco', | |
100 | link: function(scope, element, attrs, crmMonaco) { | |
101 | scope.$on(attrs.crmMonacoInsertRx, function(e, tokenName) { | |
102 | var editor = crmMonaco.editor; | |
103 | var id = { major: 1, minor: 1 }; | |
104 | var op = {identifier: id, range: editor.getSelection(), text: tokenName, forceMoveMarkers: true}; | |
105 | editor.executeEdits("tokens", [op]); | |
106 | editor.focus(); | |
107 | }); | |
108 | } | |
109 | }; | |
110 | }); | |
111 | ||
1aac4625 | 112 | })(angular, CRM.$, CRM._); |