@inteli.city/node-red-contrib-exec-collection 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/template.njk.html DELETED
@@ -1,201 +0,0 @@
1
- <script type="text/javascript">
2
- function getNunjucksSnippets() {
3
- return [
4
- {
5
- label: "block",
6
- detail: "block defines a section on the template and identifies it with a name. This is used by template inheritance. Base templates can specify blocks and child templates can override them with new content.",
7
- insertText: "{% block ${1:name} %}\n\t$2\n{% endblock %}",
8
- },
9
- {
10
- label: "njk",
11
- detail: "A nunjucks template block.",
12
- insertText: "{% $1 %}",
13
- },
14
- {
15
- label: "v{}",
16
- detail: "A variable looks up a value from the template context.",
17
- insertText: "{{ ${1:variable} }}",
18
- },
19
- {
20
- label: "extends",
21
- detail: "extends is used to specify template inheritance. The specified template is used as a base template.",
22
- insertText: '{% extends "${1:template}" %}$2',
23
- },
24
- {
25
- label: "include",
26
- detail: 'Include pulls in other templates in place.It"s useful when you need to share smaller chunks across several templates that already inherit other templates.',
27
- insertText: '{% include "${1:template}" %}$2',
28
- },
29
- {
30
- label: "filter",
31
- detail: "A filter block allows you to call a filter with the contents of the block. Instead passing a value with the | syntax, the render contents from the block will be passed.",
32
- insertText: "{% filter ${1:filter} %}\n\t$2\n{% endfilter %}",
33
- },
34
- {
35
- label: "for",
36
- detail: "for iterates over arrays and dictionaries.",
37
- insertText:
38
- "{% for ${1:item} in ${2:sequence} %}\n\t$3\n{% endfor %}",
39
- },
40
- {
41
- label: "asyncEach",
42
- detail: "asyncEach is an asynchronous version of for. You only need this if you are using a custom template loader that is asynchronous; otherwise you will never need it. Async filters and extensions also need this, but internally loops are automatically converted into asyncEach if any async filters and extensions are used within the loop.",
43
- insertText:
44
- "{% asyncEach ${1:item} in ${2:sequence} %}\n\t$3\n{% endeach %}",
45
- },
46
- {
47
- label: "asyncAll",
48
- detail: "asyncAll is similar to asyncEach, except it renders all the items in parallel, preserving the order of the items. This is only helpful if you are using asynchronous filters, extensions, or loaders. Otherwise you should never use this.",
49
- insertText:
50
- "{% asyncAll ${1:item} in ${2:sequence} %}\n\t$3\n{% endeach %}",
51
- },
52
- {
53
- label: "if",
54
- detail: 'if tests a condition and lets you selectively display content. It behaves exactly as javascript"s if behaves.',
55
- insertText: "{% if ${1:condition} %}\n\t$2\n{% endif %}",
56
- },
57
- {
58
- label: "ife",
59
- detail: "It creates the if else block.",
60
- insertText:
61
- "{% if ${1:condition} %}\n\t$2\n{% else %}\n\t$3\n{% endif %}",
62
- },
63
- {
64
- label: "ifel",
65
- detail: "Alternate condition with the if block",
66
- insertText:
67
- "{% if ${1:condition} %}\n\t$2\n{% elif ${3:condition} %}\n\t$4\n{% else %}\n\t$5\n{% endif %}",
68
- },
69
- {
70
- label: "elif",
71
- detail: "Alternate condition in the if block",
72
- insertText: "{% elif ${1:condition} %}\n\t$2",
73
- },
74
- {
75
- label: "else",
76
- detail: "Alternate condition in the if block",
77
- insertText: "{% else ${1:condition} %}\n\t$2",
78
- },
79
- {
80
- label: "end",
81
- detail: "Alternate condition in the if block",
82
- insertText: "{% endif %}",
83
- },
84
- {
85
- label: "set",
86
- detail: "set lets you create/modify a variable.",
87
- insertText: "{% set ${1:var} = ${2:value} %}$3",
88
- },
89
- {
90
- label: "macro",
91
- detail: "macro allows you to define reusable chunks of content. It is similar to a function in a programming language. ",
92
- insertText:
93
- "{% macro ${1:name}(${2:args}) %}\n\t$3\n{% endmacro %}",
94
- },
95
- {
96
- label: "import",
97
- detail: "import loads a different template and allows you to access its exported values. Macros and top-level assignments (done with set) are exported from templates, allowing you to access them in a different template.",
98
- insertText: '{% import "${1:template}" as ${2:var} %}$3',
99
- },
100
- {
101
- label: "from",
102
- detail: "It imports specific values from a template into the current namespace.",
103
- insertText:
104
- '{% from "${1:template}" import ${2:macro} as ${3:var} %}$4',
105
- },
106
- {
107
- label: "raw",
108
- detail: "If you want to output any of the special nunjucks tags like {{, you can use raw and anything inside of it will be output as plain text.",
109
- insertText: "{% raw %}\n\t$1\n{% endraw %}",
110
- },
111
- {
112
- label: "call",
113
- detail: "A call block enables you to call a macro with all the text inside the tag. This is helpful if you want to pass a lot of content into a macro. The content is available inside the macro as caller().",
114
- insertText: "{% call ${1:macro} %}\n\t$2\n{% endcall %}",
115
- },
116
- {
117
- label: "var",
118
- detail: "A variable looks up a value from the template context. If you wanted to simply display a variable, you would do: {{ username }}",
119
- insertText: "{{ ${1:var} }}",
120
- },
121
- {
122
- label: "super",
123
- detail: "You can render the contents of the parent block inside a child block by calling super.",
124
- insertText: "{{ super() }}",
125
- },
126
- { label: "or", detail: "Logical or operator.", insertText: "or" },
127
- {
128
- label: "pipe",
129
- detail: "You can pass filters from the variable directly e.g. {{ foo | escape }}",
130
- insertText: "| ${1:filter}",
131
- },
132
- ].map((i) => {
133
- return {
134
- ...i,
135
- kind: monaco.languages.CompletionItemKind.Snippet,
136
- insertTextRules:
137
- monaco.languages.CompletionItemInsertTextRule
138
- .InsertAsSnippet,
139
- };
140
- });
141
- }
142
-
143
- if (
144
- RED.editor.codeEditor.settings &&
145
- RED.editor.codeEditor.settings.lib === "monaco"
146
- ) {
147
- monaco.languages.registerCompletionItemProvider("twig", {
148
- provideCompletionItems: () => {
149
- return {
150
- suggestions: getNunjucksSnippets(),
151
- };
152
- },
153
- });
154
- }
155
-
156
- RED.nodes.registerType("template.njk", {
157
- category: "function",
158
- color: "rgb(218, 162, 92)",
159
- icon: "template.png",
160
- /* paletteLabel: "Render", */
161
- defaults: {
162
- template: { value: "" },
163
- },
164
- inputs: 1,
165
- outputs: 1,
166
- label: function () {
167
- return this.name;
168
- },
169
- oneditprepare: function () {
170
- this.editor = RED.editor.createEditor({
171
- id: "node-input-template",
172
- mode: "ace/mode/twig",
173
- value: this.template,
174
- });
175
- },
176
- oneditsave: function () {
177
- $("#node-input-template").val(this.editor.getValue());
178
- this.editor.destroy();
179
- delete this.editor;
180
- },
181
- oneditcancel: function () {
182
- this.editor.destroy();
183
- delete this.editor;
184
- },
185
- });
186
- </script>
187
-
188
- <script type="text/html" data-template-name="template.njk">
189
- <div
190
- style="height: 100%"
191
- class="node-text-editor"
192
- id="node-input-template"
193
- ></div>
194
- </script>
195
-
196
- <script type="text/html" data-help-name="template.njk">
197
- <p>
198
- A powerful templating engine with inheritance, asynchronous control, and
199
- more (jinja2 inspired) (by mozilla)
200
- </p>
201
- </script>
package/template.njk.js DELETED
@@ -1,138 +0,0 @@
1
- const nunjucks = require("nunjucks");
2
- const fs = require("fs");
3
-
4
- class NodeTemplateLoader {
5
- constructor(templates, folders=['templates']) {
6
- this.async = false;
7
- this.templates = templates;
8
- this.folders = folders;
9
- }
10
-
11
- resolve(parentName, filename) {
12
- return filename;
13
- }
14
-
15
- getSource(filePath) {
16
- if(this.templates[filePath]) {
17
- return {
18
- src: this.templates[filePath],
19
- path: filePath,
20
- noCache: true
21
- };
22
- } else{
23
- for (let folder of this.folders) {
24
- const path = `${folder}/${filePath}`;
25
-
26
- if(fs.existsSync(path)) {
27
- return {
28
- src: fs.readFileSync(path, "utf8"),
29
- path: filePath,
30
- noCache: true,
31
- }
32
- }
33
- }
34
- }
35
-
36
- return null;
37
- }
38
- }
39
-
40
- module.exports = function (RED) {
41
- let filters = {};
42
- let extensions = {};
43
- let globals = {};
44
-
45
- const addFilter = (name, filter) => {
46
- filters[name] = filter;
47
- };
48
-
49
- const getFilter = (name) => {
50
- return filters[name];
51
- }
52
-
53
- const addExtension = (name, extension) => {
54
- extensions[name] = extension;
55
- }
56
-
57
- const getExtension = (name) => {
58
- return extensions[name];
59
- }
60
-
61
- const removeExtension = (name) => {
62
- delete extensions[name];
63
- }
64
-
65
- const hasExtension = (name) => {
66
- return extensions[name] !== undefined;
67
- }
68
-
69
- const getTemplate = (templates, name) => {
70
- return templates[name];
71
- }
72
-
73
- const addGlobal = (name, value) => {
74
- globals[name] = value;
75
- }
76
-
77
- const getGlobal = (name) => {
78
- return globals[name];
79
- }
80
-
81
- const renderString = (template, context) => {
82
- return nunjucks.renderString(template, context);
83
- }
84
-
85
- function nunjucks_render(config) {
86
- RED.nodes.createNode(this, config);
87
-
88
- const node = this;
89
- const globalContext = this.context().global;
90
- const templates = {};
91
- const settings = RED.settings.nunjucks || {};
92
-
93
- filters = {};
94
- extensions = {};
95
- globals = {};
96
-
97
- globalContext.set("nj.addFilter", addFilter);
98
- globalContext.set("nj.getFilter", getFilter);
99
- globalContext.set("nj.addExtension", addExtension);
100
- globalContext.set("nj.getExtension", getExtension);
101
- globalContext.set("nj.hasExtension", hasExtension);
102
- globalContext.set("nj.removeExtension", removeExtension);
103
- globalContext.set("nj.getTemplate", (name) => getTemplate(templates, name));
104
- globalContext.set("nj.addGlobal", addGlobal);
105
- globalContext.set("nj.getGlobal", getGlobal);
106
- globalContext.set("nj.renderString", renderString);
107
-
108
- node.on("input", function (msg) {
109
- RED.nodes.eachNode(function (n) {
110
- if (n.type === "nunjucks") {
111
- templates[n.name] = n.template;
112
- }
113
- });
114
-
115
- const env = new nunjucks.Environment(
116
- new NodeTemplateLoader(templates, settings.folders || []),
117
- settings.options || {}
118
- );
119
-
120
- Object.entries(filters).forEach(([name, filter]) => env.addFilter(name, filter))
121
- Object.entries(extensions).forEach(([name, ext]) => env.addExtension(name, ext))
122
- Object.entries(globals).forEach(([name, value]) => env.addGlobal(name, value))
123
-
124
- try {
125
- msg.payload = env.renderString(config.template, {
126
- ...settings.globals || {},
127
- ...msg
128
- });
129
- } catch(err) {
130
- console.error(err)
131
- msg.payload = `Error rendering ${config.template}: ${err.message}`;
132
- }
133
-
134
- node.send(msg);
135
- });
136
- }
137
- RED.nodes.registerType("template.njk", nunjucks_render);
138
- };
@@ -1,312 +0,0 @@
1
- <!--* header -->
2
- <script type="text/markdown" data-help-name="thrd.function">
3
- ## Overview
4
- Runs system commands on a queue and returns its output.
5
-
6
- ## How to use
7
- The template text on this node works exactly the same as the template node. On the `Command` input it allows you to use the command line. The template text written is a file called `$file`. Below there are some possible commands to run with it (considering these commands are installed on the system):
8
-
9
- * `bash $file`
10
- * `node $file`
11
- * `python3 $file`
12
- * `python3 -u $file` (spawn)
13
- * `Rscript $file`
14
- * `awk -f $file`
15
- * `psql postgresql://user:passwds@host:port/database -f $file`
16
- * `ogr2ogr -f GEOJSON /vsistdout/ PG:"host=host port=portnumber user=user password=password dbname=dbname" -sql "@$file"`
17
- * `ogr2ogr -f GEOJSON /vsistdout/ WFS:"http://wfspage" layername -sql "@$file"`
18
- * `cat $file | ssh -i /path/key user@ip bash -s`
19
- * `cat $file | ssh -i /path/key user@ip node -s`
20
- * `cat $file | ssh -i /path/key user@ip python3 -s`
21
- * `mv $file $file.mjs; node $file.mjs; rm $file.mjs`
22
- * `/usr/bin/time bash $file`
23
- * `valgrind bash $file`
24
-
25
- See more examples [here](https://www.npmjs.com/package/node-red-contrib-thrd.function).
26
- </script>
27
- <!--* node-design -->
28
- <script type="text/html" data-template-name="thrd.function">
29
- <div class="form-row">
30
- <label for="node-input-name">
31
- <i class="fa fa-tag"></i>
32
- <span data-i18n="node-red:common.label.name"></span>
33
- </label>
34
-
35
- <div style="display: inline-block; width: calc(100% - 105px)">
36
- <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
37
- </div>
38
-
39
- </div>
40
-
41
- <div class="form-row">
42
- <label for="node-input-command">
43
- <i class="fa fa-file"></i>
44
- <span data-i18n="node-red:exec.label.command"></span>
45
- </label>
46
- <input style="display: inline-block; width: calc(100% - 108px);" type="text" id="node-input-command" data-i18n="[placeholder]node-red:exec.label.command">
47
-
48
- </div>
49
-
50
- <div class="form-row" style="position: relative;">
51
- <label>
52
- <i class="fa fa-sign-out"></i>
53
- <span>Queue</span>
54
- </label>
55
- <input style="width:60px" type="number" id="node-input-queue" value="1">
56
-
57
- <div style="position: absolute; right:0;display:inline-block; text-align: right; font-size: 0.8em;">
58
-
59
- <span style="margin-right:10px;font-size:9px;">No Output</span>
60
- <input type="checkbox" id="node-input-outputEmpty" style="display:inline-block; width:auto;margin-right:30px;">
61
-
62
- <span style="margin-right:10px;font-size:9px;">Cmd Template</span>
63
- <!-- <input type="checkbox" id="node-input-addpayCB" style="display:inline-block; width:auto;margin-right:30px;"> -->
64
- <input type="checkbox" id="node-input-cmdTemplate" style="display:inline-block; width:auto;margin-right:30px;">
65
-
66
- <input type="hidden" id="node-input-template" autofocus="autofocus">
67
-
68
- <span style="font-size:9px;" data-i18n="node-red:template.label.format"></span>:
69
- <select id="node-input-format" style="width:110px; font-size: 10px !important; height: 24px; padding:0;">
70
- <option value="handlebars">Mustache</option>
71
- <option value="javascript">Javascript</option>
72
- <option value="python">Python</option>
73
- <option value="sh">Shell</option>
74
- <option value="r">R</option>
75
- <option value="pgsql">PGSQL</option>
76
- <option value="nginx">NGINX</option>
77
- <option value="apache_conf">Apache</option>
78
- <option value="dockerfile">Dockerfile</option>
79
- <option value="terraform">Terraform</option>
80
- <option value="text" data-i18n="node-red:template.label.none"></option>
81
- </select>
82
- <button id="node-template-expand-editor" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button>
83
- </div>
84
- </div>
85
- <div class="form-row node-text-editor-row">
86
- <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-template-editor" ></div>
87
- </div>
88
-
89
- <div class="form-row" style="margin-bottom:0px;">
90
- <label for="node-input-output"><i class="fa fa-long-arrow-right"></i> <span data-i18n="node-red:template.label.output"></span></label>
91
- <select id="node-input-output" style="width:170px;">
92
- <option value="str">Plain text</option>
93
- <option value="parsedJSON">Parsed JSON</option>
94
- <option value="parsedYAML">Parsed YAML</option>
95
- <option value="parsedXML">Parsed XML</option>
96
- </select>
97
-
98
-
99
- <label style="margin-left: 25px;">
100
- <i class="fa fa-sign-out"></i>
101
- <span>Mode</span>
102
- </label>
103
- <select type="text" id="node-input-useSpawn" style="width:12%;margin-left:-30px;">
104
- <option value="false">exec mode- when the command is complete</option>
105
- <option value="true">spawn mode- while the command is running</option>
106
- </select>
107
-
108
- <label style="margin-left: 25px;" for="node-input-field"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
109
- <input style="margin-left:-20px;width:130px;"type="text" id="node-input-field" placeholder="payload" >
110
- <input style="margin-left:-20px;width:130px;"type="hidden" id="node-input-fieldType">
111
-
112
- <span style="margin-left:20px;font-size:11px;">Split \n</span>
113
- <input type="checkbox" id="node-input-splitLine" style="display:inline-block; width:auto;margin-left:10px;">
114
- </div>
115
-
116
- </script>
117
- <!--* javascript -->
118
- <script type="text/javascript">
119
- //** defining-variables
120
- RED.nodes.registerType('thrd.function',{
121
- //color:"rgb(180, 100, 100)",
122
- color:"rgb(234, 198, 194)",
123
- /* color:"rgb(215, 188, 225)", */
124
- category: 'function',
125
- defaults: {
126
- name: {value:""},
127
- currentLine: {row:0, column:0},
128
- command: {value:"node $file"},
129
- outputs: {value: 1},
130
- useSpawn: {value:"false"},
131
- field: {value:"payload", validate:RED.validators.typedInput("fieldType")},
132
- fieldType: {value:"msg"},
133
- format: {value:"javascript"},
134
- template: {value:`console.log(\`\n{\n\t"value": "thrd.function",\n\t"purpose":"putting the ideas from the exec, template and queue nodes together"\n}\n\`)`},
135
- output: {value:"str"},
136
- outputEmpty: {value:false},
137
- queue: {value:1},
138
- cmdTemplate: {value:true},
139
- splitLine: {value:false},
140
- cleanQueue: {value:false}
141
- },
142
- inputs:1,
143
- outputs: 1,
144
- icon: "function.svg",
145
- //** function: label
146
- label: function() {
147
- return this.name||this._("thrd.function");;
148
- },
149
- //** function: labelStyle
150
- labelStyle: function() {
151
- return this.name?"node_label_italic":"";
152
- },
153
- //** function: oneditprepare
154
- oneditprepare: function() {
155
- var that = this;
156
-
157
- if (!this.field) {
158
- this.field = 'payload';
159
- $("#node-input-field").val("payload");
160
- }
161
- if (!this.fieldType) {
162
- this.fieldType = 'msg';
163
- }
164
- $("#node-input-field").typedInput({
165
- default: 'msg',
166
- types: ['msg','flow','global'],
167
- typeField: $("#node-input-fieldType")
168
- });
169
-
170
- $("#node-input-field").typedInput({
171
- default: 'msg',
172
- types: ['msg','flow','global'],
173
- typeField: $("#node-input-fieldType")
174
- });
175
-
176
- if (this.cmdTemplate === "true" || this.cmdTemplate === true) {
177
- $("#node-input-cmdTemplate").prop("checked",true);
178
- } else {
179
- $("#node-input-cmdTemplate").prop("checked",false);
180
- }
181
-
182
- this.editor = RED.editor.createEditor({
183
- id: 'node-input-template-editor',
184
- mode: 'ace/mode/html',
185
- value: $("#node-input-template").val()
186
- });
187
-
188
- RED.library.create({
189
- url:"templates", // where to get the data from
190
- type:"template", // the type of object the library is for
191
- editor:that.editor, // the field name the main text body goes to
192
- fields:['name','format','output'],
193
- ext: "txt"
194
- });
195
- this.editor.focus();
196
-
197
- $("#node-input-format").on("change", function() {
198
- var mod = "ace/mode/"+$("#node-input-format").val();
199
- that.editor.getSession().setMode({
200
- path: mod,
201
- v: Date.now()
202
- });
203
- });
204
-
205
-
206
- //registerController = Vim.getRegisterController()
207
- //RegisterController.pushText(registerController)
208
- /* let firstTime_vimMode = true
209
- * $("#node-input-vimMode").on("change", function() {
210
- * try {
211
- * if ( that.vimMode === "true" || that.vimMode === true ){
212
- * if ( firstTime_vimMode ){
213
- * that.editor.setKeyboardHandler("ace/keyboard/vim")
214
- * } else {
215
- * that.vimMode = false
216
- * that.editor.setKeyboardHandler(null)
217
- * }
218
- * } else {
219
- * if ( firstTime_vimMode ){
220
- * that.editor.setKeyboardHandler(null)
221
- * } else {
222
- * that.vimMode = true
223
- * that.editor.setKeyboardHandler("ace/keyboard/vim")
224
- * }
225
- * }
226
- * } catch (e) {
227
- * console.log("Vim Mode only works with the Ace editor")
228
- * }
229
- setTimeout(function() {
230
- let panel = $(".ace_text-input");
231
- panel.focus();
232
- firstTime_vimMode = false
233
- }, 600);
234
- * });
235
- */
236
- let firstTime_outputEmpty = true
237
- $("#node-input-outputEmpty").on("change", function() {
238
- if ( that.outputEmpty === "true" || that.outputEmpty === true ){
239
- if ( firstTime_outputEmpty ){
240
- that.outputs = 0
241
- } else {
242
- that.outputEmpty = false
243
- that.outputs = 1
244
- }
245
- } else {
246
- if ( firstTime_outputEmpty ){
247
- that.outputs = 1
248
- } else {
249
- that.outputEmpty = true
250
- that.outputs = 0
251
- }
252
- }
253
- setTimeout(function() {
254
- firstTime_outputEmpty = false
255
- }, 600);
256
- });
257
-
258
- if ( this.currentLine === undefined ){ this.currentLine = 1 }
259
- this.editor.resize(true);
260
- this.editor.scrollToLine(this.currentLine.row+1, true, true, function () {});
261
- this.editor.gotoLine(this.currentLine.row+1,this.currentLine.column+1,true);
262
- RED.popover.tooltip($("#node-template-expand-editor"), RED._("node-red:common.label.expand"));
263
- $("#node-template-expand-editor").on("click", function(e) {
264
- e.preventDefault();
265
- var value = that.editor.getValue();
266
- RED.editor.editText({
267
- mode: $("#node-input-format").val(),
268
- value: value,
269
- width: "Infinity",
270
- cursor: that.editor.getCursorPosition(),
271
- complete: function(v,cursor) {
272
- that.editor.setValue(v, -1);
273
- that.editor.gotoLine(cursor.row+1,cursor.column,false);
274
- setTimeout(function() {
275
- that.editor.focus();
276
- try {
277
- that.editor.setKeyboardHandler("ace/keyboard/vim")
278
- } catch (e) {
279
- console.log("Vim Mode only works with the Ace editor")
280
- }
281
- }, 300);
282
- }
283
- })
284
- })
285
- },
286
- //** function: oneditsave
287
- oneditsave: function() {
288
- this.cleanQueue = true
289
- this.currentLine = this.editor.getCursorPosition()
290
- $("#node-input-template").val(this.editor.getValue());
291
- this.editor.destroy();
292
- delete this.editor;
293
- },
294
- //** function: oneditcancel
295
- oneditcancel: function() {
296
- this.editor.destroy();
297
- delete this.editor;
298
- },
299
- //** function: oneditresize
300
- oneditresize: function(size) {
301
- var rows = $("#dialog-form>div:not(.node-text-editor-row)");
302
- var height = $("#dialog-form").height();
303
- for (var i=0; i<rows.length; i++) {
304
- height -= $(rows[i]).outerHeight(true);
305
- }
306
- var editorRow = $("#dialog-form>div.node-text-editor-row");
307
- height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
308
- $(".node-text-editor").css("height",height+"px");
309
- this.editor.resize();
310
- }
311
- });
312
- </script>