123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * ScriptDialog.js
- *
- * @author realor
- */
- import { Dialog } from './Dialog.js'
- import { Controls } from './Controls.js'
- import { GeometryUtils } from '../utils/GeometryUtils.js'
- import { ObjectUtils } from '../utils/ObjectUtils.js'
- import { MessageDialog } from '../ui/MessageDialog.js'
- import { ConfirmDialog } from '../ui/ConfirmDialog.js'
- import { Toast } from '../ui/Toast.js'
- import { Solid } from '../core/Solid.js'
- import { SolidGeometry } from '../core/SolidGeometry.js'
- import { Cord } from '../core/Cord.js'
- import { CordGeometry } from '../core/CordGeometry.js'
- import { Profile } from '../core/Profile.js'
- import { ProfileGeometry } from '../core/ProfileGeometry.js'
- import { I18N } from '../i18n/I18N.js'
- import { Metadata, Result } from '../io/FileService.js'
- import * as THREE from '../lib/three.module.js'
- class ScriptDialog extends Dialog {
- static GLOBALS = {
- THREE,
- ObjectUtils,
- GeometryUtils,
- Solid,
- SolidGeometry,
- Cord,
- CordGeometry,
- Profile,
- ProfileGeometry,
- Dialog,
- MessageDialog,
- ConfirmDialog,
- Controls,
- Toast
- }
- constructor(application, saveAction) {
- super('title.script_editor')
- this.application = application
- this.setI18N(this.application.i18n)
- this.scriptName = ''
- this.scriptCode = ''
- this.saved = true
- this.setSize(760, 600)
- const editorHeight = 75
- const consoleHeight = 100 - editorHeight
- this.nameField = this.addTextField('name', 'tool.script.name', '', 'script_name')
- this.editorView = this.addCodeEditor('editor', 'label.formula.expression', '', { language: 'javascript', height: 'calc(' + editorHeight + '% - 38px)' })
- this.consoleElem = document.createElement('div')
- this.consoleElem.className = 'console'
- this.consoleElem.style.height = consoleHeight + '%'
- this.bodyElem.appendChild(this.consoleElem)
- this.runButton = this.addButton('run', 'button.run', () => {
- this.endEdition()
- this.run()
- })
- this.saveButton = this.addButton('save', 'button.save', () => {
- this.endEdition()
- saveAction(this.scriptName, this.scriptCode)
- })
- this.saveButton.style.display = saveAction ? '' : 'none'
- this.closeButton = this.addButton('cancel', 'button.close', () => {
- this.endEdition()
- this.hide()
- })
- this.nameField.addEventListener('input', () => {
- this.saveButton.disabled = this.nameField.value.trim().length === 0
- })
- // Make classes needed for scripting always global.
- for (let name in ScriptDialog.GLOBALS) {
- window[name] = ScriptDialog.GLOBALS[name]
- }
- }
- onShow() {
- this.nameField.value = this.scriptName
- const state = this.editorView.state
- const tx = state.update({ changes: { from: 0, to: state.doc.length, insert: this.scriptCode } })
- this.editorView.dispatch(tx)
- this.saveButton.disabled = this.nameField.value.trim().length === 0
- if (this.scriptName === '') {
- this.nameField.focus()
- } else {
- this.editorView.focus()
- }
- }
- clearConsole() {
- this.consoleElem.innerHTML = ''
- }
- run() {
- let error = null
- this.enterConsole()
- try {
- this.consoleElem.innerHTML = ''
- const fn = new Function(this.scriptCode)
- let t0 = Date.now()
- let result = fn()
- let t1 = Date.now()
- if (result instanceof Dialog) {
- result.show()
- } else {
- this.log('info', 'Execution completed in ' + (t1 - t0) + ' ms.')
- if (result !== undefined) this.log('info', 'Result: ' + result)
- Toast.create('message.script_executed')
- .setI18N(this.application.i18n)
- .show()
- }
- } catch (ex) {
- this.log('error', ex)
- error = ex
- } finally {
- this.exitConsole()
- }
- return error
- }
- endEdition() {
- this.scriptName = this.nameField.value
- let code = this.editorView.state.doc.toString()
- if (code !== this.scriptCode) {
- this.scriptCode = code
- this.saved = false
- }
- }
- log(className, ...args) {
- for (let arg of args) {
- let message = document.createElement('div')
- message.className = className
- message.innerHTML = String(arg)
- this.consoleElem.appendChild(message)
- }
- }
- enterConsole() {
- this.console = console
- window.console = {
- log: (...args) => this.log('info', ...args),
- info: (...args) => this.log('info', ...args),
- warn: (...args) => this.log('warn', ...args),
- error: (...args) => this.log('error', ...args)
- }
- }
- exitConsole() {
- window.console = this.console
- }
- }
- export { ScriptDialog }
|