@jscad/web 2.5.6 → 2.5.10
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/CHANGELOG.md +43 -0
- package/README.md +7 -7
- package/css/codemirror.css +10 -15
- package/css/demo.css +37 -35
- package/css/style.css +0 -124
- package/demo.html +3 -2
- package/dist/jscad-web.min.js +1367 -1371
- package/examples/CHANGELOG.md +16 -0
- package/examples/README.md +4 -4
- package/examples/core/extrusions/nutsAndBolts.js +94 -0
- package/examples/examples.json +1 -1
- package/examples/package.json +2 -1
- package/locales/de.json +0 -6
- package/locales/en.json +0 -6
- package/locales/fr.json +0 -6
- package/locales/hr.json +0 -6
- package/locales/ja.json +0 -6
- package/package.json +13 -12
- package/src/sideEffects/worker/index.js +9 -5
- package/src/ui/flow/design.js +13 -3
- package/src/ui/views/editor.js +116 -195
- package/src/ui/views/main.js +1 -1
- package/src/ui/views/options.js +0 -14
- package/src/ui/views/parameterControls.js +3 -3
- package/src/ui/views/status.js +21 -14
- package/src/ui/views/toolbar.js +3 -3
- package/css/big.css +0 -107
- package/css/editor.css +0 -428
- package/css/min.css +0 -107
- package/css/openjscad.css +0 -135
- package/imgs/closeButton.png +0 -0
- package/imgs/editHandle.png +0 -0
- package/imgs/editHandleIn.png +0 -0
- package/imgs/editHandleOut.png +0 -0
- package/imgs/menuHandle.png +0 -0
- package/imgs/menuHandleHD.png +0 -0
- package/imgs/menuHandleHU.png +0 -0
- package/imgs/menuHandleVL.png +0 -0
- package/imgs/menuHandleVLIn.png +0 -0
- package/imgs/menuHandleVLOut.png +0 -0
- package/imgs/menuHandleVR.png +0 -0
- package/imgs/misc.svg +0 -1038
- package/imgs/title.png +0 -0
- package/src/sideEffects/localFs/walkFileTree.js +0 -224
- package/src/ui/views/editor2.js +0 -130
package/src/ui/views/editor.js
CHANGED
|
@@ -1,212 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// --- Global Variables
|
|
16
|
-
const ace = require('brace')
|
|
17
|
-
require('brace/ext/language_tools.js')
|
|
18
|
-
ace.acequire('ace/ext/language_tools')
|
|
19
|
-
require('brace/mode/javascript')
|
|
20
|
-
require('brace/mode/scad')
|
|
21
|
-
require('brace/theme/chrome')
|
|
22
|
-
require('brace/theme/monokai')
|
|
23
|
-
const openscadOpenJscadParser = require('@jscad/openscad-openjscad-translator')
|
|
24
|
-
|
|
25
|
-
// See http://ace.ajax.org/#nav=howto
|
|
26
|
-
const setUpEditor = (element, gProcessor) => {
|
|
27
|
-
const langTools = ace.acequire('ace/ext/language_tools')
|
|
28
|
-
|
|
29
|
-
const flowCompleter = {
|
|
30
|
-
getCompletions: (editor, session, pos, prefix, callback) => {
|
|
31
|
-
// your code
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
langTools.addCompleter(flowCompleter)
|
|
35
|
-
|
|
36
|
-
let gEditor = null
|
|
37
|
-
gEditor = ace.edit(element)
|
|
38
|
-
gEditor.$blockScrolling = Infinity
|
|
39
|
-
gEditor.getSession().setMode('ace/mode/javascript')
|
|
40
|
-
gEditor.setTheme('ace/theme/monokai')
|
|
41
|
-
// gEditor.getSession().setMode("ace/mode/javascript");
|
|
42
|
-
// gEditor.setTheme("ace/theme/ambiance")
|
|
43
|
-
// gEditor.setTheme("ace/theme/chaos")
|
|
44
|
-
// gEditor.setTheme('ace/theme/chrome')
|
|
45
|
-
// gEditor.setTheme("ace/theme/clouds")
|
|
46
|
-
// gEditor.setTheme("ace/theme/cobalt")
|
|
47
|
-
// gEditor.setTheme("ace/theme/dawn") // nice
|
|
48
|
-
// gEditor.setTheme("ace/theme/dreamweaver")
|
|
49
|
-
// gEditor.setTheme("ace/theme/eclipse")
|
|
50
|
-
// gEditor.setTheme("ace/theme/github")
|
|
51
|
-
// gEditor.setTheme("ace/theme/idle_fingers")
|
|
52
|
-
// gEditor.setTheme("ace/theme/katzenmilch")
|
|
53
|
-
// gEditor.setTheme("ace/theme/kr_theme")
|
|
54
|
-
// gEditor.setTheme("ace/theme/kuroir")
|
|
55
|
-
// gEditor.setTheme("ace/theme/merbivore")
|
|
56
|
-
// gEditor.setTheme("ace/theme/mono_industrial")
|
|
57
|
-
// gEditor.setTheme("ace/theme/monokai")
|
|
58
|
-
// gEditor.setTheme("ace/theme/pastel_on_dark")
|
|
59
|
-
// gEditor.setTheme("ace/theme/solarized_dark")
|
|
60
|
-
// gEditor.setTheme("ace/theme/solarized_light")
|
|
61
|
-
// gEditor.setTheme("ace/theme/terminal")
|
|
62
|
-
// gEditor.setTheme("ace/theme/textmate")
|
|
63
|
-
// gEditor.setTheme("ace/theme/tomorrow")
|
|
64
|
-
// gEditor.setTheme("ace/theme/tomorrow_night")
|
|
65
|
-
// gEditor.setTheme("ace/theme/tomorrow_night_blue")
|
|
66
|
-
// gEditor.setTheme("ace/theme/tomorrow_night_bright")
|
|
67
|
-
// gEditor.setTheme("ace/theme/tomorrow_night_eighties")
|
|
68
|
-
// gEditor.setTheme("ace/theme/twilight")
|
|
69
|
-
// gEditor.setTheme("ace/theme/vibrant_ink")
|
|
70
|
-
// gEditor.setTheme("ace/theme/xcode")
|
|
71
|
-
|
|
72
|
-
const runExec = (editor) => {
|
|
73
|
-
let src = editor.getValue()
|
|
74
|
-
if (src.match(/^\/\/!OpenSCAD/i)) {
|
|
75
|
-
editor.getSession().setMode('ace/mode/scad')
|
|
76
|
-
// FIXME test for the global function first
|
|
77
|
-
src = openscadOpenJscadParser.parse(src)
|
|
78
|
-
} else {
|
|
79
|
-
editor.getSession().setMode('ace/mode/javascript')
|
|
80
|
-
}
|
|
81
|
-
if (gProcessor !== null) {
|
|
82
|
-
// gProcessor.setJsCad(src)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// enable special keystrokes
|
|
86
|
-
gEditor.commands.addCommand({
|
|
87
|
-
name: 'setJSCAD',
|
|
88
|
-
bindKey: { win: 'F5|Shift-Return', mac: 'F5|Shift-Return' },
|
|
89
|
-
exec: runExec
|
|
90
|
-
})
|
|
91
|
-
document.body.addEventListener('keydown', (evt) => {
|
|
92
|
-
if (evt.key === 'F5') {
|
|
93
|
-
evt.preventDefault()
|
|
94
|
-
runExec(gEditor)
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
gEditor.commands.addCommand({
|
|
98
|
-
name: 'viewerReset',
|
|
99
|
-
bindKey: { win: 'Ctrl-Return', mac: 'Command-Return' },
|
|
100
|
-
exec: function (editor) {
|
|
101
|
-
if (gProcessor !== null) {
|
|
102
|
-
gProcessor.viewer.resetCamera()
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
gEditor.commands.addCommand({
|
|
107
|
-
name: 'saveSource',
|
|
108
|
-
bindKey: { win: 'Ctrl-S', mac: 'Command-S' },
|
|
109
|
-
exec: function (editor) {
|
|
110
|
-
const src = editor.getValue()
|
|
111
|
-
localStorage.editorContent = src
|
|
112
|
-
gProcessor.setStatus('saved', 'Saved source to browser storage')
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
gEditor.commands.addCommand({
|
|
116
|
-
name: 'loadSource',
|
|
117
|
-
bindKey: { win: 'Ctrl-L', mac: 'Command-L' },
|
|
118
|
-
exec: function (editor) {
|
|
119
|
-
const src = localStorage.editorContent
|
|
120
|
-
if (src && src.length) editor.setValue(src, 1)
|
|
121
|
-
gEditor.commands.exec('setJSCAD', editor)
|
|
122
|
-
gProcessor.setStatus('loaded', 'Loaded source from browser storage')
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
gEditor.commands.addCommand({
|
|
126
|
-
name: 'downloadSource',
|
|
127
|
-
bindKey: { win: 'Ctrl-Shift-S', mac: 'Command-Shift-S' },
|
|
128
|
-
exec: function (editor) {
|
|
129
|
-
const src = editor.getValue()
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
const blob = new Blob([src], { type: 'text/plain' })
|
|
132
|
-
const objectUrl = URL.createObjectURL(blob)
|
|
133
|
-
const saveLink = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
|
|
134
|
-
saveLink.href = objectUrl
|
|
135
|
-
saveLink.download = 'MyDesign.jscad'
|
|
136
|
-
|
|
137
|
-
const event = new MouseEvent('click')
|
|
138
|
-
saveLink.dispatchEvent(event)
|
|
139
|
-
}, 0)
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
gEditor.commands.addCommand({
|
|
143
|
-
name: 'clearStorage',
|
|
144
|
-
bindKey: { win: 'Ctrl-Shift-\\', mac: 'Command-Shift-\\' },
|
|
145
|
-
exec: function (editor) {
|
|
146
|
-
localStorage.clear()
|
|
147
|
-
gProcessor.setStatus('cleared', 'Cleared browser storage')
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
return gEditor
|
|
1
|
+
const html = require('nanohtml')
|
|
2
|
+
|
|
3
|
+
const CodeMirror = require('codemirror')
|
|
4
|
+
require('codemirror/mode/javascript/javascript')
|
|
5
|
+
require('codemirror/addon/hint/javascript-hint')
|
|
6
|
+
|
|
7
|
+
const editorOptions = {
|
|
8
|
+
mode: 'javascript',
|
|
9
|
+
indentUnit: 2,
|
|
10
|
+
smartIndent: false,
|
|
11
|
+
indentWithTabs: false,
|
|
12
|
+
lineNumbers: true,
|
|
13
|
+
autofocus: true
|
|
152
14
|
}
|
|
153
15
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
16
|
+
let editor
|
|
17
|
+
let wrapper
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* Create a file tree from the contents of the editor
|
|
21
|
+
*/
|
|
22
|
+
const createFileTree = (editor) => {
|
|
23
|
+
const source = editor.getValue()
|
|
24
|
+
if (source && source.length > 0) {
|
|
25
|
+
return [{ ext: 'js', fullPath: '/changes.js', mimetype: 'javascript', name: 'changes.js', source }]
|
|
162
26
|
}
|
|
27
|
+
return null
|
|
163
28
|
}
|
|
164
29
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
30
|
+
/*
|
|
31
|
+
* Create a HTML wrapper for the editor (single instance)
|
|
32
|
+
*/
|
|
33
|
+
const createWrapper = (state, callbackToStream) => {
|
|
34
|
+
if (!wrapper) {
|
|
35
|
+
wrapper = html`
|
|
36
|
+
<section class='popup-menu' id='editor' key='editor' style='visibility:${state.activeTool === 'editor' ? 'visible' : 'hidden'}'>
|
|
37
|
+
<textarea></textarea>
|
|
38
|
+
</section>
|
|
39
|
+
`
|
|
40
|
+
wrapper.onkeydown = (e) => e.stopPropagation()
|
|
41
|
+
wrapper.onkeyup = (e) => e.stopPropagation()
|
|
42
|
+
|
|
43
|
+
// and add the editor
|
|
44
|
+
editor = CodeMirror.fromTextArea(wrapper.firstChild, editorOptions)
|
|
45
|
+
|
|
46
|
+
editor.setOption('extraKeys', {
|
|
47
|
+
Tab: (cm) => {
|
|
48
|
+
const spaces = Array(cm.getOption('indentUnit') + 1).join(' ')
|
|
49
|
+
cm.replaceSelection(spaces)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// inject style sheet for the editor
|
|
54
|
+
const head = document.getElementsByTagName('HEAD')[0]
|
|
55
|
+
const link = document.createElement('LINK')
|
|
56
|
+
link.rel = 'stylesheet'
|
|
57
|
+
link.href = './css/codemirror.css'
|
|
58
|
+
head.appendChild(link)
|
|
168
59
|
}
|
|
169
|
-
return
|
|
60
|
+
return wrapper
|
|
170
61
|
}
|
|
171
|
-
const html = require('bel')
|
|
172
62
|
|
|
63
|
+
/*
|
|
64
|
+
* Create the editor wrapper for handling changes to file contents.
|
|
65
|
+
*
|
|
66
|
+
* Note: Only the contents of a single file are loaded into the editor. No projects.
|
|
67
|
+
* Note: Only the contents of javascript files are loaded into the editor. No external formats.
|
|
68
|
+
*/
|
|
173
69
|
const editorWrapper = (state, editorCallbackToStream) => {
|
|
174
|
-
const el =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
70
|
+
const el = createWrapper(state, editorCallbackToStream)
|
|
71
|
+
|
|
72
|
+
// and adjust the state
|
|
73
|
+
if (state.activeTool === 'editor') {
|
|
74
|
+
el.style.visibility = 'visible'
|
|
75
|
+
el.focus()
|
|
76
|
+
|
|
77
|
+
let compileShortcut = state.shortcuts.find((shortcut) => shortcut.args === 'reevaluate')
|
|
78
|
+
if (!compileShortcut) compileShortcut = { args: 'Shift-Enter' }
|
|
79
|
+
let key = compileShortcut.key.toUpperCase()
|
|
80
|
+
// can you say PAIN? codemirror has very specific control prefixes!
|
|
81
|
+
key = key.replace(/enter/i, 'Enter')
|
|
82
|
+
key = key.replace(/alt[+-]/i, 'Alt-')
|
|
83
|
+
key = key.replace(/cmd[+-]/i, 'Cmd-')
|
|
84
|
+
key = key.replace(/control[+-]/i, 'Ctrl-')
|
|
85
|
+
key = key.replace(/shift[+-]/i, 'Shift-')
|
|
86
|
+
|
|
87
|
+
const extraKeys = {
|
|
88
|
+
Tab: (cm) => {
|
|
89
|
+
const spaces = Array(cm.getOption('indentUnit') + 1).join(' ')
|
|
90
|
+
cm.replaceSelection(spaces)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
extraKeys[key] = (cm) => {
|
|
94
|
+
const fileTree = createFileTree(cm)
|
|
95
|
+
if (fileTree) editorCallbackToStream.callback({ type: 'read', id: 'loadRemote', data: fileTree })
|
|
96
|
+
}
|
|
97
|
+
editor.setOption('extraKeys', extraKeys)
|
|
98
|
+
|
|
99
|
+
editor.focus()
|
|
100
|
+
editor.scrollIntoView({ line: 0, ch: 0 })
|
|
101
|
+
// workaround to make content appear without clicking the editor after loading an example
|
|
102
|
+
// call the refresh in a setTimeout to force js to run it in the next global event loop
|
|
103
|
+
setTimeout(() => editor.refresh(), 0)
|
|
104
|
+
} else {
|
|
105
|
+
el.style.visibility = 'hidden'
|
|
106
|
+
}
|
|
197
107
|
|
|
108
|
+
// and adjust the contents if any
|
|
109
|
+
if (state.design && state.design.filesAndFolders) {
|
|
110
|
+
if (state.design.filesAndFolders.length === 1) {
|
|
111
|
+
const file0 = state.design.filesAndFolders[0]
|
|
112
|
+
let source = file0.source ? file0.source : ''
|
|
113
|
+
if (file0.mimetype) {
|
|
114
|
+
if (file0.mimetype.indexOf('javascript') < 0) source = '// imported from external format'
|
|
115
|
+
} else {
|
|
116
|
+
source = '// imported from project'
|
|
117
|
+
}
|
|
118
|
+
const prevsource = editor.getValue()
|
|
119
|
+
if (source !== prevsource) {
|
|
120
|
+
editor.focus()
|
|
121
|
+
editor.setValue(source)
|
|
122
|
+
editor.setCursor(0, 0)
|
|
123
|
+
editor.refresh()
|
|
124
|
+
}
|
|
125
|
+
}
|
|
198
126
|
}
|
|
199
|
-
module.exports = {main}
|
|
200
|
-
`
|
|
201
|
-
// state.design.source
|
|
202
127
|
|
|
203
|
-
putSourceInEditor(editor, source)
|
|
204
128
|
return el
|
|
205
129
|
}
|
|
206
130
|
|
|
207
131
|
module.exports = {
|
|
208
|
-
editorWrapper
|
|
209
|
-
setUpEditor,
|
|
210
|
-
putSourceInEditor,
|
|
211
|
-
getSourceFromEditor
|
|
132
|
+
editorWrapper
|
|
212
133
|
}
|
package/src/ui/views/main.js
CHANGED
|
@@ -11,7 +11,7 @@ const dom = (state, i18n, paramsCallbacktoStream, editorCallbackToStream) => {
|
|
|
11
11
|
const help = require('./help')(state, i18n)
|
|
12
12
|
|
|
13
13
|
const io = require('./io')(state, i18n)
|
|
14
|
-
const editor = require('./
|
|
14
|
+
const editor = require('./editor').editorWrapper(state, editorCallbackToStream, i18n)
|
|
15
15
|
const toolBar = require('./toolbar')(state, i18n)
|
|
16
16
|
|
|
17
17
|
const viewer = require('./viewer')(state, i18n)
|
package/src/ui/views/options.js
CHANGED
|
@@ -38,20 +38,6 @@ const options = (state, i18n) => {
|
|
|
38
38
|
</label>
|
|
39
39
|
</fieldset>
|
|
40
40
|
|
|
41
|
-
<fieldset>
|
|
42
|
-
<legend> <h3> ${i18n`Storage`} </h3> </legend>
|
|
43
|
-
<label>${i18n`settings storage path`} ${i18n`not settable`}
|
|
44
|
-
<input type='text' disabled value='${state.storage.path}' disabled />
|
|
45
|
-
</label>
|
|
46
|
-
</fieldset>
|
|
47
|
-
|
|
48
|
-
<fieldset>
|
|
49
|
-
<legend> <h3> ${i18n`File Handling`} </h3> </legend>
|
|
50
|
-
<label>${i18n`enable conversion to scripts`}
|
|
51
|
-
<input type='checkbox' checked=false id='design-convertSupportedTypes' checked=${state.design.convertSupportedTypes}/>
|
|
52
|
-
</label>
|
|
53
|
-
</fieldset>
|
|
54
|
-
|
|
55
41
|
${shortcuts}
|
|
56
42
|
|
|
57
43
|
</section>`
|
|
@@ -263,19 +263,19 @@ const createInputControl = (definition, prevValue) => {
|
|
|
263
263
|
|
|
264
264
|
// check for required parameters
|
|
265
265
|
if (!('type' in definition)) {
|
|
266
|
-
throw new Error(
|
|
266
|
+
throw new Error(`Parameter definition (${definition.name}) must include a 'type' parameter`)
|
|
267
267
|
}
|
|
268
268
|
let typeData = controlList.filter((x) => definition.type === x.type)
|
|
269
269
|
typeData = (typeData && typeData.length > 0) ? typeData[0] : undefined
|
|
270
270
|
if (!typeData) {
|
|
271
|
-
throw new Error(
|
|
271
|
+
throw new Error(`Parameter definition (${definition.name}), invalid type "${definition.type}"`)
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
// validate fields
|
|
275
275
|
const definitionFields = Object.keys(definition)
|
|
276
276
|
typeData.required.forEach((requiredField) => {
|
|
277
277
|
if (!definitionFields.includes(requiredField)) {
|
|
278
|
-
throw new Error(`Parameter definition
|
|
278
|
+
throw new Error(`Parameter definition of type "${definition.type}" must include a "${requiredField}" parameter`)
|
|
279
279
|
}
|
|
280
280
|
})
|
|
281
281
|
|
package/src/ui/views/status.js
CHANGED
|
@@ -3,29 +3,36 @@ const html = require('nanohtml')
|
|
|
3
3
|
// status display
|
|
4
4
|
const status = (state, paramsCallbacktoStream) => {
|
|
5
5
|
const status = state.status
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
let errorWhere = ''
|
|
7
|
+
let errorMessage = ''
|
|
8
|
+
let errorStack = ''
|
|
9
|
+
if (status.error) {
|
|
10
|
+
if (status.error.fileName && !status.error.fileName.startsWith('blob')) {
|
|
11
|
+
// syntax errors provide file name, line, and column number
|
|
12
|
+
errorWhere = `${status.error.fileName}:${status.error.lineNumber}:${status.error.columnNumber}`
|
|
13
|
+
}
|
|
14
|
+
errorMessage = `${status.error.name}: ${status.error.message}`
|
|
15
|
+
if (status.error.stack) {
|
|
16
|
+
errorStack = status.error.stack.trim().split('\n').map((s) => html`<ul>${s}</ul>`)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
const statusMessage = status.error !== undefined
|
|
11
21
|
? html`<span>
|
|
12
|
-
<div>
|
|
13
|
-
|
|
22
|
+
<div id='errormessage'>
|
|
23
|
+
<p>
|
|
24
|
+
${errorWhere}
|
|
25
|
+
</p>
|
|
26
|
+
<p>
|
|
27
|
+
${errorMessage}
|
|
28
|
+
</p>
|
|
14
29
|
</div>
|
|
15
|
-
<div>
|
|
16
|
-
${errorMessage}
|
|
17
|
-
</div>
|
|
18
|
-
<div>
|
|
19
|
-
${errorLine}
|
|
20
|
-
</div>
|
|
21
|
-
<div>
|
|
30
|
+
<div id='stacktrace'>
|
|
22
31
|
${errorStack}
|
|
23
32
|
</div>
|
|
24
33
|
</span>`
|
|
25
34
|
: ''
|
|
26
35
|
|
|
27
|
-
// ? `Error: ${status.error.message} line: ${status.error.lineno}, filename:${status.error.filename} stack: ${status.error.stack}` : ''
|
|
28
|
-
// ${statusMessage}
|
|
29
36
|
const busy = status.busy
|
|
30
37
|
return html`
|
|
31
38
|
<span id='status'>
|
package/src/ui/views/toolbar.js
CHANGED
|
@@ -6,13 +6,13 @@ const toolbar = (state, i18n) => {
|
|
|
6
6
|
const helpIcon = html`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12" y2="17"/></svg>`
|
|
7
7
|
|
|
8
8
|
return html`<span id='toolbar'>
|
|
9
|
-
<button id='toggleOptions'>
|
|
9
|
+
<button id='toggleOptions' aria-label='options'>
|
|
10
10
|
${optionsIcon}
|
|
11
11
|
</button>
|
|
12
|
-
<button id='toggleEditor'>
|
|
12
|
+
<button id='toggleEditor' aria-label='editor'>
|
|
13
13
|
${editorIcon}
|
|
14
14
|
</button>
|
|
15
|
-
<button id='toggleHelp'>
|
|
15
|
+
<button id='toggleHelp' aria-label='help'>
|
|
16
16
|
${helpIcon}
|
|
17
17
|
</button>
|
|
18
18
|
</span>`
|
package/css/big.css
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* min.css for OpenJSCAD.org viewer
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
.jscad-container {
|
|
6
|
-
margin: 5px 15px 5px 5px; /* not inherited */
|
|
7
|
-
padding: 20px; /* not inherited */
|
|
8
|
-
color: Black;
|
|
9
|
-
font-weight: bold;
|
|
10
|
-
font-family: Helvetica, Arial, Sans;
|
|
11
|
-
border: thin solid black;
|
|
12
|
-
min-width: 410px;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
#header {
|
|
16
|
-
margin: 5px; /* not inherited */
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
#viewerContext {
|
|
20
|
-
margin: 5px; /* not inherited */
|
|
21
|
-
border: thin solid gray; /* not inherited */
|
|
22
|
-
padding: 0px; /* not inherited */
|
|
23
|
-
|
|
24
|
-
background: white;
|
|
25
|
-
width: 1200px;
|
|
26
|
-
height: 900px;
|
|
27
|
-
|
|
28
|
-
top: 0px;
|
|
29
|
-
bottom: 0px;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
canvas {
|
|
33
|
-
margin: 0px; /* not inherited */
|
|
34
|
-
border: 0px none gray; /* not inherited */
|
|
35
|
-
padding: 0px; /* not inherited */
|
|
36
|
-
|
|
37
|
-
width: 100%;
|
|
38
|
-
height: 100%;
|
|
39
|
-
|
|
40
|
-
cursor: move;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
#parametersdiv {
|
|
44
|
-
margin: 5px; /* not inherited */
|
|
45
|
-
border: thin solid rgb(200,200,200);
|
|
46
|
-
border-radius: 1em;
|
|
47
|
-
padding: 10px;
|
|
48
|
-
|
|
49
|
-
background: white;
|
|
50
|
-
opacity: 0.8;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
#parametersdiv table {
|
|
54
|
-
margin-bottom: 5px;
|
|
55
|
-
|
|
56
|
-
text-align: left;
|
|
57
|
-
font-size: 0.8em;
|
|
58
|
-
font-weight: normal;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#parametersdiv th {
|
|
62
|
-
margin: 0px; /* not inherited */
|
|
63
|
-
border: 0px none gray; /* not inherited */
|
|
64
|
-
padding: 5px; /* not inherited */
|
|
65
|
-
|
|
66
|
-
font-weight: bold;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
#parametersdiv th.caption {
|
|
70
|
-
text-decoration: underline;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
#parametersdiv td.caption {
|
|
74
|
-
text-align: right;
|
|
75
|
-
font-weight: bold;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
#parametersdiv td {
|
|
79
|
-
margin: 0px; /* not inherited */
|
|
80
|
-
border: 0px none gray; /* not inherited */
|
|
81
|
-
padding: 0px; /* not inherited */
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
#parametersdiv input, #parametersdiv textarea, #parametersdiv select {
|
|
85
|
-
font-size: 0.9em;
|
|
86
|
-
background: #fea;
|
|
87
|
-
border: none;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
#updateButton {
|
|
91
|
-
margin: 5px; /* not inherited */
|
|
92
|
-
border: thin solid Black; /* not inherited */
|
|
93
|
-
padding: 2px; /* not inherited */
|
|
94
|
-
border-radius: 4px;
|
|
95
|
-
background: white;
|
|
96
|
-
|
|
97
|
-
margin-left: 1em;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
#tail {
|
|
101
|
-
margin: 5px; /* not inherited */
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
#busy {
|
|
105
|
-
vertical-align: middle;
|
|
106
|
-
}
|
|
107
|
-
|