@jscad/web 2.5.4 → 2.5.8
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 +38 -0
- package/css/codemirror.css +10 -15
- package/css/demo.css +1 -1
- package/css/style.css +0 -124
- package/demo.html +0 -1
- package/dist/jscad-web.min.js +1330 -1264
- package/examples/CHANGELOG.md +8 -0
- package/examples/package.json +1 -1
- package/package.json +12 -12
- package/src/ui/views/editor.js +116 -195
- package/src/ui/views/main.js +1 -1
- package/src/ui/views/viewer.js +1 -1
- package/src/utils/logger.js +1 -1
- package/css/editor.css +0 -428
- 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/examples/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.3.2](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.3.1...@jscad/examples@2.3.2) (2022-02-19)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @jscad/examples
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [2.3.1](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.3.0...@jscad/examples@2.3.1) (2021-09-27)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @jscad/examples
|
package/examples/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jscad/web",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.8",
|
|
4
4
|
"description": "Web Application for JSCAD",
|
|
5
5
|
"repository": "https://github.com/jscad/OpenJSCAD.org",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -34,18 +34,18 @@
|
|
|
34
34
|
],
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@jscad/array-utils": "2.1.
|
|
38
|
-
"@jscad/core": "2.5.
|
|
39
|
-
"@jscad/examples": "2.3.
|
|
40
|
-
"@jscad/io": "2.
|
|
41
|
-
"@jscad/modeling": "2.
|
|
42
|
-
"@jscad/regl-renderer": "2.5.
|
|
37
|
+
"@jscad/array-utils": "2.1.3",
|
|
38
|
+
"@jscad/core": "2.5.8",
|
|
39
|
+
"@jscad/examples": "2.3.3",
|
|
40
|
+
"@jscad/io": "2.3.1",
|
|
41
|
+
"@jscad/modeling": "2.9.2",
|
|
42
|
+
"@jscad/regl-renderer": "2.5.8",
|
|
43
43
|
"@most/create": "2.0.1",
|
|
44
44
|
"brace": "0.11.1",
|
|
45
|
-
"codemirror": "5.
|
|
45
|
+
"codemirror": "5.65.2",
|
|
46
46
|
"es2015-i18n-tag": "1.6.1",
|
|
47
|
-
"file-saver": "2.0.
|
|
48
|
-
"is-electron": "2.2.
|
|
47
|
+
"file-saver": "2.0.5",
|
|
48
|
+
"is-electron": "2.2.1",
|
|
49
49
|
"morphdom": "2.6.1",
|
|
50
50
|
"most": "1.8.0",
|
|
51
51
|
"most-proxy": "3.3.0",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"browserify": "16.5.1",
|
|
59
59
|
"budo": "11.6.4",
|
|
60
60
|
"copy-dir": "1.3.0",
|
|
61
|
-
"docblock": "0.4.
|
|
61
|
+
"docblock": "0.4.5",
|
|
62
62
|
"uglifyify": "5.0.2"
|
|
63
63
|
},
|
|
64
64
|
"collective": {
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"url": "https://opencollective.com/openjscad",
|
|
67
67
|
"logo": "https://opencollective.com/openjscad/logo.txt"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "0cebde0166c104e3c08cc05d2c03d9defc7eca26"
|
|
70
70
|
}
|
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/viewer.js
CHANGED
|
@@ -143,7 +143,7 @@ const viewer = (state, i18n) => {
|
|
|
143
143
|
} else {
|
|
144
144
|
// only generate entities when the solids change
|
|
145
145
|
// themes, options, etc also change the viewer state
|
|
146
|
-
const solids = state.design.solids
|
|
146
|
+
const solids = state.design.solids.filter((solid) => solid && (solid instanceof Object))
|
|
147
147
|
if (prevSolids) {
|
|
148
148
|
const theme = state.themes.themeSettings.viewer
|
|
149
149
|
const color = theme.rendering.meshColor
|