Showing
5 changed files
with
65 additions
and
1 deletions
ui/src/app/components/ace-editor-fix.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +export default function fixAceEditor(aceEditor) { | ||
18 | + aceEditor.$blockScrolling = Infinity; | ||
19 | + aceEditor.on("showGutterTooltip", function (tooltip) { | ||
20 | + if (!tooltip.isAttachedToBody) { | ||
21 | + document.body.appendChild(tooltip.$element); //eslint-disable-line | ||
22 | + tooltip.isAttachedToBody = true; | ||
23 | + onElementRemoved(tooltip.$parentNode, () => { | ||
24 | + if (tooltip.$element.parentNode != null) { | ||
25 | + tooltip.$element.parentNode.removeChild(tooltip.$element); | ||
26 | + } | ||
27 | + }); | ||
28 | + } | ||
29 | + }); | ||
30 | +} | ||
31 | + | ||
32 | +function onElementRemoved(element, callback) { | ||
33 | + if (!document.body.contains(element)) { //eslint-disable-line | ||
34 | + callback(); | ||
35 | + } else { | ||
36 | + var observer; | ||
37 | + observer = new MutationObserver(function(mutations) { //eslint-disable-line | ||
38 | + if (!document.body.contains(element)) { //eslint-disable-line | ||
39 | + callback(); | ||
40 | + observer.disconnect(); | ||
41 | + } | ||
42 | + }); | ||
43 | + observer.observe(document.body, {childList: true}); //eslint-disable-line | ||
44 | + } | ||
45 | +} |
@@ -22,6 +22,8 @@ import thingsboardToast from '../services/toast'; | @@ -22,6 +22,8 @@ import thingsboardToast from '../services/toast'; | ||
22 | import thingsboardUtils from '../common/utils.service'; | 22 | import thingsboardUtils from '../common/utils.service'; |
23 | import thingsboardExpandFullscreen from './expand-fullscreen.directive'; | 23 | import thingsboardExpandFullscreen from './expand-fullscreen.directive'; |
24 | 24 | ||
25 | +import fixAceEditor from './ace-editor-fix'; | ||
26 | + | ||
25 | /* eslint-disable import/no-unresolved, import/default */ | 27 | /* eslint-disable import/no-unresolved, import/default */ |
26 | 28 | ||
27 | import jsFuncTemplate from './js-func.tpl.html'; | 29 | import jsFuncTemplate from './js-func.tpl.html'; |
@@ -83,6 +85,7 @@ function JsFunc($compile, $templateCache, toast, utils, $translate) { | @@ -83,6 +85,7 @@ function JsFunc($compile, $templateCache, toast, utils, $translate) { | ||
83 | scope.js_editor.session.on("change", function () { | 85 | scope.js_editor.session.on("change", function () { |
84 | scope.cleanupJsErrors(); | 86 | scope.cleanupJsErrors(); |
85 | }); | 87 | }); |
88 | + fixAceEditor(_ace); | ||
86 | } | 89 | } |
87 | }; | 90 | }; |
88 | 91 |
@@ -19,6 +19,8 @@ import 'brace/ext/language_tools'; | @@ -19,6 +19,8 @@ import 'brace/ext/language_tools'; | ||
19 | import 'brace/mode/json'; | 19 | import 'brace/mode/json'; |
20 | import 'ace-builds/src-min-noconflict/snippets/json'; | 20 | import 'ace-builds/src-min-noconflict/snippets/json'; |
21 | 21 | ||
22 | +import fixAceEditor from './ace-editor-fix'; | ||
23 | + | ||
22 | /* eslint-disable import/no-unresolved, import/default */ | 24 | /* eslint-disable import/no-unresolved, import/default */ |
23 | 25 | ||
24 | import jsonObjectEditTemplate from './json-object-edit.tpl.html'; | 26 | import jsonObjectEditTemplate from './json-object-edit.tpl.html'; |
@@ -30,7 +32,7 @@ export default angular.module('thingsboard.directives.jsonObjectEdit', []) | @@ -30,7 +32,7 @@ export default angular.module('thingsboard.directives.jsonObjectEdit', []) | ||
30 | .name; | 32 | .name; |
31 | 33 | ||
32 | /*@ngInject*/ | 34 | /*@ngInject*/ |
33 | -function JsonObjectEdit($compile, $templateCache, toast, utils) { | 35 | +function JsonObjectEdit($compile, $templateCache, $document, toast, utils) { |
34 | 36 | ||
35 | var linker = function (scope, element, attrs, ngModelCtrl) { | 37 | var linker = function (scope, element, attrs, ngModelCtrl) { |
36 | var template = $templateCache.get(jsonObjectEditTemplate); | 38 | var template = $templateCache.get(jsonObjectEditTemplate); |
@@ -67,6 +69,7 @@ function JsonObjectEdit($compile, $templateCache, toast, utils) { | @@ -67,6 +69,7 @@ function JsonObjectEdit($compile, $templateCache, toast, utils) { | ||
67 | scope.json_editor.session.on("change", function () { | 69 | scope.json_editor.session.on("change", function () { |
68 | scope.cleanupJsonErrors(); | 70 | scope.cleanupJsonErrors(); |
69 | }); | 71 | }); |
72 | + fixAceEditor(_ace); | ||
70 | } | 73 | } |
71 | }; | 74 | }; |
72 | 75 |
@@ -23,6 +23,8 @@ import FlatButton from 'material-ui/FlatButton'; | @@ -23,6 +23,8 @@ import FlatButton from 'material-ui/FlatButton'; | ||
23 | import 'brace/ext/language_tools'; | 23 | import 'brace/ext/language_tools'; |
24 | import 'brace/theme/github'; | 24 | import 'brace/theme/github'; |
25 | 25 | ||
26 | +import fixAceEditor from './../ace-editor-fix'; | ||
27 | + | ||
26 | class ThingsboardAceEditor extends React.Component { | 28 | class ThingsboardAceEditor extends React.Component { |
27 | 29 | ||
28 | constructor(props) { | 30 | constructor(props) { |
@@ -31,6 +33,7 @@ class ThingsboardAceEditor extends React.Component { | @@ -31,6 +33,7 @@ class ThingsboardAceEditor extends React.Component { | ||
31 | this.onBlur = this.onBlur.bind(this); | 33 | this.onBlur = this.onBlur.bind(this); |
32 | this.onFocus = this.onFocus.bind(this); | 34 | this.onFocus = this.onFocus.bind(this); |
33 | this.onTidy = this.onTidy.bind(this); | 35 | this.onTidy = this.onTidy.bind(this); |
36 | + this.onLoad = this.onLoad.bind(this); | ||
34 | var value = props.value ? props.value + '' : ''; | 37 | var value = props.value ? props.value + '' : ''; |
35 | this.state = { | 38 | this.state = { |
36 | value: value, | 39 | value: value, |
@@ -72,6 +75,10 @@ class ThingsboardAceEditor extends React.Component { | @@ -72,6 +75,10 @@ class ThingsboardAceEditor extends React.Component { | ||
72 | } | 75 | } |
73 | } | 76 | } |
74 | 77 | ||
78 | + onLoad(editor) { | ||
79 | + fixAceEditor(editor); | ||
80 | + } | ||
81 | + | ||
75 | render() { | 82 | render() { |
76 | 83 | ||
77 | const styles = reactCSS({ | 84 | const styles = reactCSS({ |
@@ -117,6 +124,7 @@ class ThingsboardAceEditor extends React.Component { | @@ -117,6 +124,7 @@ class ThingsboardAceEditor extends React.Component { | ||
117 | onChange={this.onValueChanged} | 124 | onChange={this.onValueChanged} |
118 | onFocus={this.onFocus} | 125 | onFocus={this.onFocus} |
119 | onBlur={this.onBlur} | 126 | onBlur={this.onBlur} |
127 | + onLoad={this.onLoad} | ||
120 | name={this.props.form.title} | 128 | name={this.props.form.title} |
121 | value={this.state.value} | 129 | value={this.state.value} |
122 | readOnly={this.props.form.readonly} | 130 | readOnly={this.props.form.readonly} |
@@ -23,6 +23,8 @@ import thingsboardJsonForm from '../json-form.directive'; | @@ -23,6 +23,8 @@ import thingsboardJsonForm from '../json-form.directive'; | ||
23 | import thingsboardManageWidgetActions from './action/manage-widget-actions.directive'; | 23 | import thingsboardManageWidgetActions from './action/manage-widget-actions.directive'; |
24 | import 'angular-ui-ace'; | 24 | import 'angular-ui-ace'; |
25 | 25 | ||
26 | +import fixAceEditor from './../ace-editor-fix'; | ||
27 | + | ||
26 | import './widget-config.scss'; | 28 | import './widget-config.scss'; |
27 | 29 | ||
28 | /* eslint-disable import/no-unresolved, import/default */ | 30 | /* eslint-disable import/no-unresolved, import/default */ |
@@ -72,6 +74,9 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout | @@ -72,6 +74,9 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout | ||
72 | enableSnippets: true, | 74 | enableSnippets: true, |
73 | enableBasicAutocompletion: true, | 75 | enableBasicAutocompletion: true, |
74 | enableLiveAutocompletion: true | 76 | enableLiveAutocompletion: true |
77 | + }, | ||
78 | + onLoad: function (_ace) { | ||
79 | + fixAceEditor(_ace); | ||
75 | } | 80 | } |
76 | }; | 81 | }; |
77 | 82 |