1 (function(angular
, $, _
) {
2 angular
.module('crmMonaco', CRM
.angRequires('crmMonaco'));
4 // "crmMonaco" is a basic skeletal directive.
5 // Example usage: <div crm-monaco ng-model="my.content"></div>
6 // Example usage: <div crm-monaco="{readOnly: true}" ng-model="my.content"></div>
7 angular
.module('crmMonaco').directive('crmMonaco', function($timeout
, $parse
) {
10 require
: ['ngModel', 'crmMonaco'],
11 template
: '<div class="crm-monaco-container"></div>',
12 controller: function() {
13 this.editor
= null; // Filled in by link().
15 link: function($scope
, $el
, $attr
, controllers
) {
16 var ngModel
= controllers
[0], crmMonaco
= controllers
[1];
19 require
.config({paths
: CRM
.crmMonaco
.paths
});
20 require(['vs/editor/editor.main'], function() {
27 if ($attr
.crmMonaco
) {
28 angular
.extend(options
, $parse($attr
.crmMonaco
)($scope
));
30 angular
.extend(options
, {
31 value
: ngModel
.$modelValue
,
35 automaticLayout
: true,
38 verticalHasArrows
: true,
39 horizontalHasArrows
: true,
41 horizontal
: 'visible',
42 verticalScrollbarSize
: 17,
43 horizontalScrollbarSize
: 17,
48 heightPct
= options
.crmHeightPct
|| heightPct
;
49 delete options
.crmHeightPct
;
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
);
55 editor
.onDidChangeModelContent(_
.debounce(function () {
56 $scope
.$apply(function () {
57 ngModel
.$setViewValue(editor
.getValue());
61 ngModel
.$render = function() {
63 editor
.setValue(ngModel
.$modelValue
);
65 // FIXME: else: retry?
68 if ($attr
.ngDisabled
) {
69 $scope
.$watch($parse($attr
.ngDisabled
), function(disabled
){
70 editor
.updateOptions({readOnly
: disabled
});
74 // FIXME: This makes vertical scrolling much better, but horizontal is still weird.
76 function bodyScrollSuspend() {
77 if (origOverflow
!== undefined) return;
78 origOverflow
= $('body').css('overflow');
79 $('body').css('overflow', 'hidden');
81 function bodyScrollRestore() {
82 if (origOverflow
=== undefined) return;
83 $('body').css('overflow', origOverflow
);
84 origOverflow
= undefined;
86 editorEl
.on('mouseenter', bodyScrollSuspend
);
87 editorEl
.on('mouseleave', bodyScrollRestore
);
88 editor
.onDidFocusEditorWidget(bodyScrollSuspend
);
89 editor
.onDidBlurEditorWidget(bodyScrollRestore
);
91 crmMonaco
.editor
= editor
;
93 $scope
.$on('$destroy', function () {
95 if (editor
) editor
.dispose();
96 delete crmMonaco
.editor
;
103 angular
.module('crmMonaco').directive('crmMonacoInsertRx', function() {
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
]);
118 })(angular
, CRM
.$, CRM
._
);