@lvce-editor/shared-process 0.9.2 → 0.10.1
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/config/builtinCommands.json +9 -0
- package/config/defaultKeyBindings.json +5 -0
- package/config/defaultSettings.json +8 -1
- package/config/fileMap.json +1 -1
- package/extensions/builtin.language-basics-css/src/tokenizeCss.js +22 -15
- package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +7 -3
- package/extensions/builtin.language-basics-json/src/tokenizeJson.js +12 -12
- package/extensions/builtin.language-basics-perl/extension.json +1 -1
- package/extensions/builtin.language-basics-perl/src/tokenizePerl.js +125 -10
- package/extensions/builtin.language-basics-yaml/src/tokenizeYaml.js +20 -1
- package/extensions/builtin.theme-slime/color-theme.json +4 -0
- package/index.js +7 -0
- package/package.json +6 -5
- package/src/parts/ChromeExtension/ChromeExtension.ipc.js +6 -0
- package/src/parts/ChromeExtension/ChromeExtension.js +48 -0
- package/src/parts/ExportStatic/ExportStatic.js +447 -0
- package/src/parts/ExtractZip/ExtractZip.js +12 -0
- package/src/parts/Module/Module.js +2 -0
- package/src/parts/ModuleId/ModuleId.js +1 -0
- package/src/parts/ModuleMap/ModuleMap.js +3 -0
- package/src/parts/Platform/Platform.js +8 -0
|
@@ -416,5 +416,14 @@
|
|
|
416
416
|
{
|
|
417
417
|
"id": "Window.zoomReset",
|
|
418
418
|
"label": "Window: Reset Zoom"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"id": "Main.openUri",
|
|
422
|
+
"label": "Simple Browser: Open",
|
|
423
|
+
"args": ["simple-browser://"]
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"id": "SimpleBrowser.openDevtools",
|
|
427
|
+
"label": "Simple Browser: Open Dev Devtools"
|
|
419
428
|
}
|
|
420
429
|
]
|
|
@@ -31,5 +31,12 @@
|
|
|
31
31
|
"workbench.sideBar.visible": true,
|
|
32
32
|
"workbench.saveStateOnVisibilityChange": false,
|
|
33
33
|
|
|
34
|
-
"workspace.defaultWorkspace": "fetch:///playground"
|
|
34
|
+
"workspace.defaultWorkspace": "fetch:///playground",
|
|
35
|
+
|
|
36
|
+
"keyBindings.fallTroughBrowserView": [
|
|
37
|
+
"ctrl+p",
|
|
38
|
+
"ctrl+shift+p",
|
|
39
|
+
"ctrl+b",
|
|
40
|
+
"ctrl+m"
|
|
41
|
+
]
|
|
35
42
|
}
|
package/config/fileMap.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"/playground/languages/index.jl",
|
|
10
10
|
"/playground/languages/index.js",
|
|
11
11
|
"/playground/languages/index.kt",
|
|
12
|
-
"/playground/languages/index.
|
|
12
|
+
"/playground/languages/index.pl",
|
|
13
13
|
"/playground/languages/index.py",
|
|
14
14
|
"/playground/languages/index.ts",
|
|
15
15
|
"/playground/languages/scrolling.txt",
|
|
@@ -14,6 +14,7 @@ export const State = {
|
|
|
14
14
|
AfterQuery: 10,
|
|
15
15
|
InsideRound: 11,
|
|
16
16
|
AfterQueryWithRules: 12,
|
|
17
|
+
InsideRule: 13,
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export const StateMap = {
|
|
@@ -60,7 +61,7 @@ export const TokenMap = {
|
|
|
60
61
|
[TokenType.CurlyClose]: 'Punctuation',
|
|
61
62
|
[TokenType.PropertyColon]: 'Punctuation',
|
|
62
63
|
[TokenType.CssPropertySemicolon]: 'Punctuation',
|
|
63
|
-
[TokenType.Variable]: '
|
|
64
|
+
[TokenType.Variable]: 'VariableName',
|
|
64
65
|
[TokenType.None]: 'None',
|
|
65
66
|
[TokenType.CssPropertyValue]: 'CssPropertyValue',
|
|
66
67
|
[TokenType.Unknown]: 'Unknown',
|
|
@@ -68,12 +69,12 @@ export const TokenMap = {
|
|
|
68
69
|
[TokenType.Numeric]: 'Numeric',
|
|
69
70
|
[TokenType.NewLine]: 'NewLine',
|
|
70
71
|
[TokenType.Comment]: 'Comment',
|
|
71
|
-
[TokenType.Query]: '
|
|
72
|
+
[TokenType.Query]: 'CssAtRule',
|
|
72
73
|
[TokenType.Text]: 'Text',
|
|
73
74
|
[TokenType.CssSelectorId]: 'CssSelectorId',
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
const RE_SELECTOR = /^[\.a-zA-Z\d
|
|
77
|
+
const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>\+\~\_%]+/
|
|
77
78
|
const RE_SELECTOR_ID = /^#\w+/
|
|
78
79
|
const RE_WHITESPACE = /^ +/
|
|
79
80
|
const RE_CURLY_OPEN = /^\{/
|
|
@@ -151,17 +152,19 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
151
152
|
token = TokenType.Punctuation
|
|
152
153
|
state = State.InsideAttributeSelector
|
|
153
154
|
} else if ((next = part.match(RE_QUERY))) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
switch (next[0]) {
|
|
156
|
+
case '@font-face':
|
|
157
|
+
case '@-ms-viewport':
|
|
158
|
+
case '@-o-viewport':
|
|
159
|
+
case '@viewport':
|
|
160
|
+
token = TokenType.Query
|
|
161
|
+
state = State.AfterQueryWithRules
|
|
162
|
+
break
|
|
163
|
+
case '@keyframes':
|
|
164
|
+
default:
|
|
165
|
+
token = TokenType.Query
|
|
166
|
+
state = State.AfterQuery
|
|
167
|
+
break
|
|
165
168
|
}
|
|
166
169
|
} else if ((next = part.match(RE_STAR))) {
|
|
167
170
|
token = TokenType.CssSelector
|
|
@@ -238,7 +241,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
238
241
|
case State.InsideBlockComment:
|
|
239
242
|
if ((next = part.match(RE_BLOCK_COMMENT_END))) {
|
|
240
243
|
token = TokenType.Comment
|
|
241
|
-
state = State.TopLevelContent
|
|
244
|
+
state = stack.pop() || State.TopLevelContent
|
|
242
245
|
} else if ((next = part.match(RE_BLOCK_COMMENT_CONTENT))) {
|
|
243
246
|
token = TokenType.Comment
|
|
244
247
|
state = State.InsideBlockComment
|
|
@@ -257,6 +260,10 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
257
260
|
if (next[0].startsWith('--')) {
|
|
258
261
|
token = TokenType.Variable
|
|
259
262
|
}
|
|
263
|
+
} else if ((next = part.match(RE_BLOCK_COMMENT_START))) {
|
|
264
|
+
token = TokenType.Comment
|
|
265
|
+
state = State.InsideBlockComment
|
|
266
|
+
stack.push(State.InsideSelector)
|
|
260
267
|
} else if ((next = part.match(RE_ANYTHING_UNTIL_CLOSE_BRACE))) {
|
|
261
268
|
token = TokenType.Unknown
|
|
262
269
|
state = State.InsideSelector
|
|
@@ -85,6 +85,7 @@ const RE_COMMA = /^,/
|
|
|
85
85
|
const RE_COLON = /^:/
|
|
86
86
|
const RE_NUMERIC =
|
|
87
87
|
/^((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)\b/
|
|
88
|
+
const RE_NUMERIC_OCTAL = /0(?:o|O)?[0-7][0-7_]*(n)?\b/
|
|
88
89
|
const RE_LINE_COMMENT_START = /^\/\//
|
|
89
90
|
const RE_LINE_COMMENT_CONTENT = /^[^\n]+/
|
|
90
91
|
const RE_NEWLINE_WHITESPACE = /^\n\s*/
|
|
@@ -94,14 +95,14 @@ const RE_BLOCK_COMMENT_END = /^\*\//
|
|
|
94
95
|
const RE_UNKNOWN_VALUE = /^[^\}\{\s,"]+/
|
|
95
96
|
const RE_IMPORT = /^[a-zA-Z\.]+/
|
|
96
97
|
const RE_SEMICOLON = /^;/
|
|
97
|
-
const RE_VARIABLE_NAME = /^[a-zA-Z_][a-zA-Z\d\_]*/
|
|
98
|
+
const RE_VARIABLE_NAME = /^[a-zA-Z_$][a-zA-Z\d\_]*/
|
|
98
99
|
const RE_LINE_COMMENT = /^\/\/[^\n]*/
|
|
99
100
|
const RE_ROUND_OPEN = /^\(/
|
|
100
101
|
const RE_ROUND_CLOSE = /^\)/
|
|
101
102
|
const RE_DOT = /^\./
|
|
102
103
|
const RE_EQUAL_SIGN = /^=/
|
|
103
104
|
const RE_SINGLE_QUOTE = /^'/
|
|
104
|
-
const RE_PUNCTUATION = /^[\(\)=\+\-><\.:;\{\}\[\]
|
|
105
|
+
const RE_PUNCTUATION = /^[\(\)=\+\-><\.:;\{\}\[\]!,&\|\^\?\*%]/
|
|
105
106
|
const RE_SLASH = /^\//
|
|
106
107
|
const RE_ANYTHING_UNTIL_END = /^.+/s
|
|
107
108
|
const RE_WHITESPACE = /^\s+/
|
|
@@ -198,7 +199,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
198
199
|
token = TokenType.Comment
|
|
199
200
|
state = State.InsideLineComment
|
|
200
201
|
} else {
|
|
201
|
-
next = part.match(
|
|
202
|
+
next = part.match(RE_SLASH)
|
|
202
203
|
token = TokenType.Punctuation
|
|
203
204
|
state = State.TopLevelContent
|
|
204
205
|
}
|
|
@@ -211,6 +212,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
211
212
|
} else if ((next = part.match(RE_QUOTE_BACKTICK))) {
|
|
212
213
|
token = TokenType.Punctuation
|
|
213
214
|
state = State.InsideBacktickString
|
|
215
|
+
} else if ((next = part.match(RE_NUMERIC_OCTAL))) {
|
|
216
|
+
token = TokenType.Numeric
|
|
217
|
+
state = State.TopLevelContent
|
|
214
218
|
} else {
|
|
215
219
|
line.slice(0, index) //?
|
|
216
220
|
part //?
|
|
@@ -93,8 +93,10 @@ const RE_ANYTHING = /^.+/s
|
|
|
93
93
|
const RE_NUMERIC =
|
|
94
94
|
/^((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)\b/
|
|
95
95
|
const RE_TEXT = /^[^\s\{\}\[\]]+/
|
|
96
|
-
const RE_ESCAPED_QUOTE = /^\\"/
|
|
97
|
-
const RE_BACK_SLASH = /^\\/
|
|
96
|
+
// const RE_ESCAPED_QUOTE = /^\\"/
|
|
97
|
+
// const RE_BACK_SLASH = /^\\/
|
|
98
|
+
const RE_STRING_ESCAPE = /^\\.?/
|
|
99
|
+
const RE_WORD = /^\w+/
|
|
98
100
|
|
|
99
101
|
export const initialLineState = {
|
|
100
102
|
state: State.TopLevelContent,
|
|
@@ -165,7 +167,6 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
165
167
|
}
|
|
166
168
|
break
|
|
167
169
|
case State.AfterCurlyOpen:
|
|
168
|
-
part
|
|
169
170
|
if ((next = part.match(RE_WHITESPACE))) {
|
|
170
171
|
token = TokenType.Whitespace
|
|
171
172
|
state = State.AfterCurlyOpen
|
|
@@ -182,6 +183,12 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
182
183
|
} else if ((next = part.match(RE_LINE_COMMENT))) {
|
|
183
184
|
token = TokenType.Comment
|
|
184
185
|
state = State.AfterCurlyOpen
|
|
186
|
+
} else if ((next = part.match(RE_WORD))) {
|
|
187
|
+
token = TokenType.Text
|
|
188
|
+
state = State.AfterPropertyName
|
|
189
|
+
} else if ((next = part.match(RE_ANYTHING))) {
|
|
190
|
+
token = TokenType.Text
|
|
191
|
+
state = State.AfterCurlyOpen
|
|
185
192
|
} else {
|
|
186
193
|
part //?
|
|
187
194
|
throw new Error('no')
|
|
@@ -195,10 +202,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
195
202
|
token = TokenType.Punctuation
|
|
196
203
|
state = stack.pop()
|
|
197
204
|
state
|
|
198
|
-
} else if ((next = part.match(
|
|
199
|
-
token = TokenType.JsonPropertyName
|
|
200
|
-
state = State.InsidePropertyNameString
|
|
201
|
-
} else if ((next = part.match(RE_BACK_SLASH))) {
|
|
205
|
+
} else if ((next = part.match(RE_STRING_ESCAPE))) {
|
|
202
206
|
token = TokenType.JsonPropertyName
|
|
203
207
|
state = State.InsidePropertyNameString
|
|
204
208
|
} else {
|
|
@@ -212,10 +216,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
212
216
|
} else if ((next = part.match(RE_DOUBLE_QUOTE))) {
|
|
213
217
|
token = TokenType.Punctuation
|
|
214
218
|
state = stack.pop()
|
|
215
|
-
} else if ((next = part.match(
|
|
216
|
-
token = TokenType.String
|
|
217
|
-
state = State.InsideString
|
|
218
|
-
} else if ((next = part.match(RE_BACK_SLASH))) {
|
|
219
|
+
} else if ((next = part.match(RE_STRING_ESCAPE))) {
|
|
219
220
|
token = TokenType.String
|
|
220
221
|
state = State.InsideString
|
|
221
222
|
} else {
|
|
@@ -239,7 +240,6 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
239
240
|
}
|
|
240
241
|
break
|
|
241
242
|
case State.AfterPropertyNameAfterColon:
|
|
242
|
-
part
|
|
243
243
|
if ((next = part.match(RE_WHITESPACE))) {
|
|
244
244
|
token = TokenType.Whitespace
|
|
245
245
|
state = State.AfterPropertyNameAfterColon
|
|
@@ -1,31 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @enum number
|
|
3
|
+
*/
|
|
4
|
+
export const State = {
|
|
5
|
+
TopLevelContent: 1,
|
|
6
|
+
InsideString: 2,
|
|
7
|
+
InsideLineComment: 3,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const StateMap = {
|
|
11
|
+
[State.TopLevelContent]: 'TopLevelContent',
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
/**
|
|
2
15
|
* @enum number
|
|
3
16
|
*/
|
|
4
17
|
export const TokenType = {
|
|
5
|
-
|
|
18
|
+
None: 1,
|
|
19
|
+
Whitespace: 2,
|
|
20
|
+
PunctuationString: 3,
|
|
21
|
+
String: 4,
|
|
22
|
+
Keyword: 5,
|
|
23
|
+
Numeric: 6,
|
|
24
|
+
Punctuation: 7,
|
|
25
|
+
VariableName: 8,
|
|
26
|
+
Comment: 885,
|
|
27
|
+
Text: 9,
|
|
6
28
|
}
|
|
7
29
|
|
|
8
30
|
export const TokenMap = {
|
|
31
|
+
[TokenType.None]: 'None',
|
|
32
|
+
[TokenType.Whitespace]: 'Whitespace',
|
|
33
|
+
[TokenType.PunctuationString]: 'PunctuationString',
|
|
34
|
+
[TokenType.String]: 'String',
|
|
35
|
+
[TokenType.Keyword]: 'Keyword',
|
|
36
|
+
[TokenType.Numeric]: 'Numeric',
|
|
37
|
+
[TokenType.Punctuation]: 'Punctuation',
|
|
38
|
+
[TokenType.VariableName]: 'VariableName',
|
|
39
|
+
[TokenType.Comment]: 'Comment',
|
|
9
40
|
[TokenType.Text]: 'Text',
|
|
10
41
|
}
|
|
11
42
|
|
|
43
|
+
const RE_LINE_COMMENT = /^#.*/s
|
|
44
|
+
const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>]+/
|
|
45
|
+
const RE_WHITESPACE = /^ +/
|
|
46
|
+
const RE_CURLY_OPEN = /^\{/
|
|
47
|
+
const RE_CURLY_CLOSE = /^\}/
|
|
48
|
+
const RE_PROPERTY_NAME = /^[a-zA-Z\-]+\b/
|
|
49
|
+
const RE_COLON = /^:/
|
|
50
|
+
const RE_PROPERTY_VALUE = /^[^;\}]+/
|
|
51
|
+
const RE_SEMICOLON = /^;/
|
|
52
|
+
const RE_COMMA = /^,/
|
|
53
|
+
const RE_ANYTHING = /^.+/s
|
|
54
|
+
const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
|
|
55
|
+
const RE_QUOTE_DOUBLE = /^"/
|
|
56
|
+
const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
|
|
57
|
+
const RE_KEYWORD =
|
|
58
|
+
/^(?:case|continue|default|die|no|else|elsif|eval|exit|for|foreach|given|goto|if|last|next|redo|require|return|select|switch|unless|until|use|wait|when|while)\b/
|
|
59
|
+
|
|
60
|
+
const RE_VARIABLE_NAME = /^[a-zA-Z\_]+/
|
|
61
|
+
const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)<>]/
|
|
62
|
+
const RE_NUMERIC = /^\d+/
|
|
63
|
+
|
|
12
64
|
export const initialLineState = {
|
|
13
|
-
state:
|
|
65
|
+
state: State.TopLevelContent,
|
|
14
66
|
tokens: [],
|
|
15
67
|
}
|
|
16
68
|
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param {any} lineStateA
|
|
72
|
+
* @param {any} lineStateB
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
export const isEqualLineState = (lineStateA, lineStateB) => {
|
|
76
|
+
return lineStateA.state === lineStateB.state
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const hasArrayReturn = true
|
|
80
|
+
|
|
17
81
|
/**
|
|
18
82
|
* @param {string} line
|
|
83
|
+
* @param {any} lineState
|
|
19
84
|
*/
|
|
20
|
-
export const tokenizeLine = (line) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
85
|
+
export const tokenizeLine = (line, lineState) => {
|
|
86
|
+
let next = null
|
|
87
|
+
let index = 0
|
|
88
|
+
let tokens = []
|
|
89
|
+
let token = TokenType.None
|
|
90
|
+
let state = lineState.state
|
|
91
|
+
while (index < line.length) {
|
|
92
|
+
const part = line.slice(index)
|
|
93
|
+
switch (state) {
|
|
94
|
+
case State.TopLevelContent:
|
|
95
|
+
if ((next = part.match(RE_WHITESPACE))) {
|
|
96
|
+
token = TokenType.Whitespace
|
|
97
|
+
state = State.TopLevelContent
|
|
98
|
+
} else if ((next = part.match(RE_KEYWORD))) {
|
|
99
|
+
token = TokenType.Keyword
|
|
100
|
+
state = State.TopLevelContent
|
|
101
|
+
} else if ((next = part.match(RE_PUNCTUATION))) {
|
|
102
|
+
token = TokenType.Punctuation
|
|
103
|
+
state = State.TopLevelContent
|
|
104
|
+
} else if ((next = part.match(RE_VARIABLE_NAME))) {
|
|
105
|
+
token = TokenType.VariableName
|
|
106
|
+
state = State.TopLevelContent
|
|
107
|
+
} else if ((next = part.match(RE_NUMERIC))) {
|
|
108
|
+
token = TokenType.Numeric
|
|
109
|
+
state = State.TopLevelContent
|
|
110
|
+
} else if ((next = part.match(RE_QUOTE_DOUBLE))) {
|
|
111
|
+
token = TokenType.PunctuationString
|
|
112
|
+
state = State.InsideString
|
|
113
|
+
} else if ((next = part.match(RE_LINE_COMMENT))) {
|
|
114
|
+
token = TokenType.Comment
|
|
115
|
+
state = State.TopLevelContent
|
|
116
|
+
} else if ((next = part.match(RE_ANYTHING))) {
|
|
117
|
+
token = TokenType.Text
|
|
118
|
+
state = State.TopLevelContent
|
|
119
|
+
} else {
|
|
120
|
+
part //?
|
|
121
|
+
throw new Error('no')
|
|
122
|
+
}
|
|
123
|
+
break
|
|
124
|
+
case State.InsideString:
|
|
125
|
+
if ((next = part.match(RE_QUOTE_DOUBLE))) {
|
|
126
|
+
token = TokenType.PunctuationString
|
|
127
|
+
state = State.TopLevelContent
|
|
128
|
+
} else if ((next = part.match(RE_STRING_DOUBLE_QUOTE_CONTENT))) {
|
|
129
|
+
token = TokenType.String
|
|
130
|
+
state = State.InsideString
|
|
131
|
+
} else {
|
|
132
|
+
throw new Error('no')
|
|
133
|
+
}
|
|
134
|
+
break
|
|
135
|
+
default:
|
|
136
|
+
throw new Error('no')
|
|
137
|
+
}
|
|
138
|
+
const tokenLength = next[0].length
|
|
139
|
+
index += tokenLength
|
|
140
|
+
tokens.push(token, tokenLength)
|
|
141
|
+
}
|
|
27
142
|
return {
|
|
28
|
-
state
|
|
143
|
+
state,
|
|
29
144
|
tokens,
|
|
30
145
|
}
|
|
31
146
|
}
|
|
@@ -38,6 +38,8 @@ export const TokenType = {
|
|
|
38
38
|
String: 188,
|
|
39
39
|
YamlPropertyName: 123,
|
|
40
40
|
YamlPropertyValueString: 124,
|
|
41
|
+
Alias: 125,
|
|
42
|
+
Anchor: 126,
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export const TokenMap = {
|
|
@@ -55,6 +57,8 @@ export const TokenMap = {
|
|
|
55
57
|
[TokenType.String]: 'String',
|
|
56
58
|
[TokenType.YamlPropertyName]: 'YamlPropertyName',
|
|
57
59
|
[TokenType.YamlPropertyValueString]: 'YamlPropertyValueString',
|
|
60
|
+
[TokenType.Alias]: 'VariableName',
|
|
61
|
+
[TokenType.Anchor]: 'VariableName',
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
const RE_LINE_COMMENT_START = /^#/
|
|
@@ -64,7 +68,7 @@ const RE_CURLY_CLOSE = /^\}/
|
|
|
64
68
|
const RE_PROPERTY_NAME = /^[\:@\/\\a-zA-Z\-\_\d\.]+(?=\s*:(\s+|$))/
|
|
65
69
|
const RE_PROPERTY_NAME_2 =
|
|
66
70
|
/^[\:@\/\\a-zA-Z\-\_\d\.\s]*[@\/\\a-zA-Z\-\_\d\.](?=\s*:(\s+|$))/
|
|
67
|
-
const RE_PROPERTY_VALUE_1 =
|
|
71
|
+
const RE_PROPERTY_VALUE_1 = /^[^&].*(?=\s+#)/s
|
|
68
72
|
const RE_SEMICOLON = /^;/
|
|
69
73
|
const RE_COMMA = /^,/
|
|
70
74
|
const RE_ANYTHING = /^.+/s
|
|
@@ -93,6 +97,9 @@ const RE_MULTI_LINE_STRING_START = /^(?:\||>\-|>)/
|
|
|
93
97
|
const RE_KEY_PRE = /^\s*(\-\s*)?/
|
|
94
98
|
const RE_SINGLE_QUOTE = /^'/
|
|
95
99
|
const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
|
|
100
|
+
const RE_ALIAS = /^\*.+/
|
|
101
|
+
const RE_ANCHOR = /^\&.+/
|
|
102
|
+
const RE_MERGE_KEY = /^<<\:(?=\s)/
|
|
96
103
|
|
|
97
104
|
export const initialLineState = {
|
|
98
105
|
state: State.TopLevelContent,
|
|
@@ -158,6 +165,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
158
165
|
} else if ((next = part.match(RE_SINGLE_QUOTE))) {
|
|
159
166
|
token = TokenType.Punctuation
|
|
160
167
|
state = State.InsidePropertyNameString
|
|
168
|
+
} else if ((next = part.match(RE_MERGE_KEY))) {
|
|
169
|
+
token = TokenType.Punctuation
|
|
170
|
+
state = State.AfterPropertyNameAfterColon
|
|
161
171
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
162
172
|
token = TokenType.Text
|
|
163
173
|
state = State.TopLevelContent
|
|
@@ -204,6 +214,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
204
214
|
} else if ((next = part.match(RE_PROPERTY_VALUE_1))) {
|
|
205
215
|
token = TokenType.YamlPropertyValueString
|
|
206
216
|
state = State.AfterPropertyValue
|
|
217
|
+
} else if ((next = part.match(RE_ANCHOR))) {
|
|
218
|
+
token = TokenType.Anchor
|
|
219
|
+
state = State.AfterPropertyNameAfterColon
|
|
207
220
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
208
221
|
token = TokenType.YamlPropertyValueString
|
|
209
222
|
state = State.TopLevelContent
|
|
@@ -247,6 +260,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
247
260
|
} else if ((next = part.match(RE_MULTI_LINE_STRING_START))) {
|
|
248
261
|
token = TokenType.Punctuation
|
|
249
262
|
state = State.AfterPipe
|
|
263
|
+
} else if ((next = part.match(RE_ALIAS))) {
|
|
264
|
+
token = TokenType.Alias
|
|
265
|
+
state = State.TopLevelContent
|
|
250
266
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
251
267
|
token = TokenType.YamlPropertyValueString
|
|
252
268
|
state = State.TopLevelContent
|
|
@@ -309,6 +325,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
309
325
|
} else if ((next = part.match(RE_DASH))) {
|
|
310
326
|
token = TokenType.Punctuation
|
|
311
327
|
state = State.AfterDash
|
|
328
|
+
} else if ((next = part.match(RE_LINE_COMMENT_START))) {
|
|
329
|
+
token = TokenType.Comment
|
|
330
|
+
state = State.InsideLineComment
|
|
312
331
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
313
332
|
token = TokenType.Text
|
|
314
333
|
state = State.TopLevelContent
|
package/index.js
CHANGED
|
@@ -4,3 +4,10 @@ import { fileURLToPath } from 'node:url'
|
|
|
4
4
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
5
5
|
|
|
6
6
|
export const sharedProcessPath = join(__dirname, 'src', 'sharedProcessMain.js')
|
|
7
|
+
|
|
8
|
+
export const exportStatic = async () => {
|
|
9
|
+
const fn = await import('./src/parts/ExportStatic/ExportStatic.js')
|
|
10
|
+
const root = process.cwd()
|
|
11
|
+
const pathPrefix = process.env.PATH_PREFIX || ''
|
|
12
|
+
await fn.exportStatic({ root, pathPrefix })
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"node": ">=16"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@lvce-editor/extension-host": "0.
|
|
24
|
-
"@lvce-editor/pty-host": "0.
|
|
23
|
+
"@lvce-editor/extension-host": "0.10.1",
|
|
24
|
+
"@lvce-editor/pty-host": "0.10.1",
|
|
25
25
|
"debug": "^4.3.4",
|
|
26
26
|
"execa": "^6.1.0",
|
|
27
27
|
"exit-hook": "^3.1.0",
|
|
28
|
-
"got": "^12.5.
|
|
28
|
+
"got": "^12.5.2",
|
|
29
29
|
"is-object": "^1.0.2",
|
|
30
30
|
"lines-and-columns": "^2.0.3",
|
|
31
31
|
"open": "^8.4.0",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"optionalDependencies": {
|
|
43
43
|
"electron-clipboard-ex": "^1.3.3",
|
|
44
44
|
"keytar": "^7.9.0",
|
|
45
|
-
"vscode-ripgrep-with-github-api-error-fix": "^2.5.0"
|
|
45
|
+
"vscode-ripgrep-with-github-api-error-fix": "^2.5.0",
|
|
46
|
+
"extract-zip": "^2.0.1"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/debug": "^4.1.7",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import VError from 'verror'
|
|
2
|
+
import * as Assert from '../Assert/Assert.js'
|
|
3
|
+
import * as Download from '../Download/Download.js'
|
|
4
|
+
import * as ExtractZip from '../ExtractZip/ExtractZip.js'
|
|
5
|
+
import * as FileSystem from '../FileSystem/FileSystem.js'
|
|
6
|
+
import * as Path from '../Path/Path.js'
|
|
7
|
+
import * as Platform from '../Platform/Platform.js'
|
|
8
|
+
|
|
9
|
+
const getExtensionPath = async (tmpDir) => {
|
|
10
|
+
const dirents = await FileSystem.readDirWithFileTypes(tmpDir)
|
|
11
|
+
if (dirents.length === 1 && dirents[0].type === 'directory') {
|
|
12
|
+
return Path.join(tmpDir, dirents[0].name)
|
|
13
|
+
}
|
|
14
|
+
return tmpDir
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const install = async (name, url) => {
|
|
18
|
+
try {
|
|
19
|
+
Assert.string(name)
|
|
20
|
+
Assert.string(url)
|
|
21
|
+
const cachedChromeExtensionsPath = Platform.getCachedExtensionsPath()
|
|
22
|
+
const tempFileCompressed = Path.join(
|
|
23
|
+
cachedChromeExtensionsPath,
|
|
24
|
+
`${name}.zip`
|
|
25
|
+
)
|
|
26
|
+
const tmpDir = Path.join(cachedChromeExtensionsPath, name)
|
|
27
|
+
const chromeExtensionsPath = Platform.getChromeExtensionsPath()
|
|
28
|
+
await Download.download(url, tempFileCompressed)
|
|
29
|
+
await ExtractZip.extractZip({ inFile: tempFileCompressed, outDir: tmpDir })
|
|
30
|
+
const cachedExtensionPath = await getExtensionPath(tmpDir)
|
|
31
|
+
const outDir = Path.join(chromeExtensionsPath, name)
|
|
32
|
+
await FileSystem.remove(outDir)
|
|
33
|
+
await FileSystem.rename(cachedExtensionPath, outDir)
|
|
34
|
+
} catch (error) {
|
|
35
|
+
throw new VError(error, `Failed to install chrome extension ${name}`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const uninstall = async (name) => {
|
|
40
|
+
try {
|
|
41
|
+
Assert.string(name)
|
|
42
|
+
// TODO
|
|
43
|
+
// figure out extension path
|
|
44
|
+
// remove file
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new VError(error, `Failed to uninstall chrome extension ${name}`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import fs, { cpSync, readdirSync, readFileSync, writeFileSync } from 'fs'
|
|
2
|
+
import path, { join } from 'path'
|
|
3
|
+
|
|
4
|
+
// TODO
|
|
5
|
+
// - implement this for syntax highlighting projects
|
|
6
|
+
// - implement this for language features web extensions
|
|
7
|
+
|
|
8
|
+
const readExtensionManifest = (path) => {
|
|
9
|
+
const content = readFileSync(path, 'utf8')
|
|
10
|
+
return { ...JSON.parse(content), path }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const getThemeName = (dirent) => {
|
|
14
|
+
return dirent.slice('builtin.theme-'.length)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param {{root:string, pathPrefix:string }} param0
|
|
20
|
+
*/
|
|
21
|
+
export const exportStatic = async ({ root, pathPrefix }) => {
|
|
22
|
+
const dirents = readdirSync(
|
|
23
|
+
join(root, 'node_modules', '@lvce-editor', 'server', 'static')
|
|
24
|
+
)
|
|
25
|
+
const RE_COMMIT_HASH = /^[a-z\d]+$/
|
|
26
|
+
const isCommitHash = (dirent) => {
|
|
27
|
+
return dirent.length === 7 && dirent.match(RE_COMMIT_HASH)
|
|
28
|
+
}
|
|
29
|
+
const commitHash = dirents.find(isCommitHash) || ''
|
|
30
|
+
|
|
31
|
+
const extensionJson = readExtensionManifest(join(root, 'extension.json'))
|
|
32
|
+
const colorThemeName = extensionJson.id.slice('builtin.theme-'.length)
|
|
33
|
+
const name = extensionJson.name || extensionJson.id || ''
|
|
34
|
+
const description = extensionJson.description || ''
|
|
35
|
+
fs.rmSync(join(root, 'dist'), { recursive: true, force: true })
|
|
36
|
+
|
|
37
|
+
fs.mkdirSync(path.join(root, 'dist'))
|
|
38
|
+
|
|
39
|
+
fs.mkdirSync(
|
|
40
|
+
join(
|
|
41
|
+
root,
|
|
42
|
+
'dist',
|
|
43
|
+
commitHash,
|
|
44
|
+
'extensions',
|
|
45
|
+
`builtin.theme-${colorThemeName}`
|
|
46
|
+
),
|
|
47
|
+
{
|
|
48
|
+
recursive: true,
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
fs.cpSync(
|
|
52
|
+
join(root, 'node_modules', '@lvce-editor', 'server', 'static'),
|
|
53
|
+
join(root, 'dist'),
|
|
54
|
+
{
|
|
55
|
+
recursive: true,
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const replaceSync = (path, occurrence, replacement) => {
|
|
60
|
+
const oldContent = readFileSync(path, 'utf8')
|
|
61
|
+
if (!oldContent.includes(occurrence)) {
|
|
62
|
+
throw new Error(`failed to replace occurrence ${occurrence}: Not found`)
|
|
63
|
+
}
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
const newContent = oldContent.replaceAll(occurrence, replacement)
|
|
66
|
+
writeFileSync(path, newContent)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
replaceSync(
|
|
70
|
+
join(
|
|
71
|
+
root,
|
|
72
|
+
'dist',
|
|
73
|
+
commitHash,
|
|
74
|
+
'packages',
|
|
75
|
+
'renderer-process',
|
|
76
|
+
'dist',
|
|
77
|
+
'rendererProcessMain.js'
|
|
78
|
+
),
|
|
79
|
+
'platform = getPlatform();',
|
|
80
|
+
'platform = "web"'
|
|
81
|
+
)
|
|
82
|
+
replaceSync(
|
|
83
|
+
join(
|
|
84
|
+
root,
|
|
85
|
+
'dist',
|
|
86
|
+
commitHash,
|
|
87
|
+
'packages',
|
|
88
|
+
'renderer-process',
|
|
89
|
+
'dist',
|
|
90
|
+
'rendererProcessMain.js'
|
|
91
|
+
),
|
|
92
|
+
`return "/${commitHash}";`,
|
|
93
|
+
`return "${pathPrefix}/${commitHash}";`
|
|
94
|
+
)
|
|
95
|
+
replaceSync(
|
|
96
|
+
join(
|
|
97
|
+
root,
|
|
98
|
+
'dist',
|
|
99
|
+
commitHash,
|
|
100
|
+
'packages',
|
|
101
|
+
'renderer-worker',
|
|
102
|
+
'dist',
|
|
103
|
+
'rendererWorkerMain.js'
|
|
104
|
+
),
|
|
105
|
+
'platform = getPlatform();',
|
|
106
|
+
'platform = "web"'
|
|
107
|
+
)
|
|
108
|
+
replaceSync(
|
|
109
|
+
join(
|
|
110
|
+
root,
|
|
111
|
+
'dist',
|
|
112
|
+
commitHash,
|
|
113
|
+
'packages',
|
|
114
|
+
'renderer-worker',
|
|
115
|
+
'dist',
|
|
116
|
+
'rendererWorkerMain.js'
|
|
117
|
+
),
|
|
118
|
+
`platform2 = "remote";`,
|
|
119
|
+
'platform2 = "web";'
|
|
120
|
+
)
|
|
121
|
+
replaceSync(
|
|
122
|
+
join(
|
|
123
|
+
root,
|
|
124
|
+
'dist',
|
|
125
|
+
commitHash,
|
|
126
|
+
'packages',
|
|
127
|
+
'renderer-worker',
|
|
128
|
+
'dist',
|
|
129
|
+
'rendererWorkerMain.js'
|
|
130
|
+
),
|
|
131
|
+
`return "/${commitHash}";`,
|
|
132
|
+
`return "${pathPrefix}/${commitHash}";`
|
|
133
|
+
)
|
|
134
|
+
replaceSync(
|
|
135
|
+
join(
|
|
136
|
+
root,
|
|
137
|
+
'dist',
|
|
138
|
+
commitHash,
|
|
139
|
+
'packages',
|
|
140
|
+
'renderer-worker',
|
|
141
|
+
'dist',
|
|
142
|
+
'rendererWorkerMain.js'
|
|
143
|
+
),
|
|
144
|
+
`getColorThemeUrlWeb = (colorThemeId) => {
|
|
145
|
+
return \`/extensions/builtin.theme-\${colorThemeId}/color-theme.json\`;
|
|
146
|
+
};`,
|
|
147
|
+
`const getColorThemeUrlWeb = (colorThemeId) => {
|
|
148
|
+
const assetDir = getAssetDir()
|
|
149
|
+
return \`\${assetDir}/themes/\${colorThemeId}.json\`
|
|
150
|
+
}`
|
|
151
|
+
)
|
|
152
|
+
replaceSync(
|
|
153
|
+
join(
|
|
154
|
+
root,
|
|
155
|
+
'dist',
|
|
156
|
+
commitHash,
|
|
157
|
+
'packages',
|
|
158
|
+
'renderer-worker',
|
|
159
|
+
'dist',
|
|
160
|
+
'rendererWorkerMain.js'
|
|
161
|
+
),
|
|
162
|
+
`getIconThemeUrl = (iconThemeId) => {
|
|
163
|
+
return \`/extensions/builtin.\${iconThemeId}/icon-theme.json\`;
|
|
164
|
+
}`,
|
|
165
|
+
`getIconThemeUrl = (iconThemeId) => {
|
|
166
|
+
const assetDir = getAssetDir()
|
|
167
|
+
return \`\${assetDir}/icon-themes/\${iconThemeId}.json\`
|
|
168
|
+
}`
|
|
169
|
+
)
|
|
170
|
+
replaceSync(
|
|
171
|
+
join(
|
|
172
|
+
root,
|
|
173
|
+
'dist',
|
|
174
|
+
commitHash,
|
|
175
|
+
'packages',
|
|
176
|
+
'renderer-worker',
|
|
177
|
+
'dist',
|
|
178
|
+
'rendererWorkerMain.js'
|
|
179
|
+
),
|
|
180
|
+
`return \`\${extensionPath}\${value}\``,
|
|
181
|
+
`return \`${pathPrefix}/${commitHash}/file-icons/\${value.slice(7)}\``
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
// workaround for firefox bug
|
|
185
|
+
replaceSync(
|
|
186
|
+
join(
|
|
187
|
+
root,
|
|
188
|
+
'dist',
|
|
189
|
+
commitHash,
|
|
190
|
+
'packages',
|
|
191
|
+
'renderer-worker',
|
|
192
|
+
'dist',
|
|
193
|
+
'rendererWorkerMain.js'
|
|
194
|
+
),
|
|
195
|
+
`//# sourceMappingURL`,
|
|
196
|
+
`export {}
|
|
197
|
+
//# sourceMappingURL`
|
|
198
|
+
)
|
|
199
|
+
replaceSync(
|
|
200
|
+
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
201
|
+
`"workbench.colorTheme": "slime"`,
|
|
202
|
+
`"workbench.colorTheme": "${colorThemeName}"`
|
|
203
|
+
)
|
|
204
|
+
replaceSync(
|
|
205
|
+
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
206
|
+
`"workbench.saveStateOnVisibilityChange": false`,
|
|
207
|
+
`"workbench.saveStateOnVisibilityChange": true`
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
const extensionDirents = readdirSync(
|
|
211
|
+
join(root, 'node_modules', '@lvce-editor', 'shared-process', 'extensions')
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
const isLanguageBasics = (dirent) => {
|
|
215
|
+
return dirent.startsWith('builtin.language-basics')
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const isTheme = (dirent) => {
|
|
219
|
+
return dirent.startsWith('builtin.theme-')
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const isIconTheme = (dirent) => {
|
|
223
|
+
return dirent === 'builtin.vscode-icons'
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const languageBasicsDirents = extensionDirents.filter(isLanguageBasics)
|
|
227
|
+
const themeDirents = extensionDirents.filter(isTheme)
|
|
228
|
+
const iconThemeDirents = extensionDirents.filter(isIconTheme)
|
|
229
|
+
|
|
230
|
+
const writeJson = (path, json) => {
|
|
231
|
+
const content = JSON.stringify(json, null, 2) + '\n'
|
|
232
|
+
writeFileSync(path, content)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const getManifestPath = (dirent) => {
|
|
236
|
+
return join(
|
|
237
|
+
root,
|
|
238
|
+
'node_modules',
|
|
239
|
+
'@lvce-editor',
|
|
240
|
+
'shared-process',
|
|
241
|
+
'extensions',
|
|
242
|
+
dirent,
|
|
243
|
+
'extension.json'
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
const getLanguages = (extension) => {
|
|
247
|
+
const languages = []
|
|
248
|
+
for (const language of extension.languages || []) {
|
|
249
|
+
languages.push({
|
|
250
|
+
...language,
|
|
251
|
+
tokenize: `${pathPrefix}/${commitHash}/extensions/${extension.id}/${language.tokenize}`,
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
return languages
|
|
255
|
+
}
|
|
256
|
+
const languages = languageBasicsDirents
|
|
257
|
+
.map(getManifestPath)
|
|
258
|
+
.map(readExtensionManifest)
|
|
259
|
+
.flatMap(getLanguages)
|
|
260
|
+
writeJson(
|
|
261
|
+
join(root, 'dist', commitHash, 'config', 'languages.json'),
|
|
262
|
+
languages
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
for (const languageBasicsDirent of languageBasicsDirents) {
|
|
266
|
+
cpSync(
|
|
267
|
+
join(
|
|
268
|
+
root,
|
|
269
|
+
'node_modules',
|
|
270
|
+
'@lvce-editor',
|
|
271
|
+
'shared-process',
|
|
272
|
+
'extensions',
|
|
273
|
+
languageBasicsDirent
|
|
274
|
+
),
|
|
275
|
+
join(root, 'dist', commitHash, 'extensions', languageBasicsDirent),
|
|
276
|
+
{
|
|
277
|
+
recursive: true,
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
for (const themeDirent of themeDirents) {
|
|
283
|
+
const themeId = getThemeName(themeDirent)
|
|
284
|
+
cpSync(
|
|
285
|
+
join(
|
|
286
|
+
root,
|
|
287
|
+
'node_modules',
|
|
288
|
+
'@lvce-editor',
|
|
289
|
+
'shared-process',
|
|
290
|
+
'extensions',
|
|
291
|
+
themeDirent,
|
|
292
|
+
'color-theme.json'
|
|
293
|
+
),
|
|
294
|
+
join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const compare = (a, b) => {
|
|
299
|
+
return a.localeCompare(b)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const toSorted = (objects, compare) => {
|
|
303
|
+
return [...objects].sort(compare)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const mergeThemes = (builtinThemes, extensionThemes) => {
|
|
307
|
+
const seen = []
|
|
308
|
+
const merged = []
|
|
309
|
+
for (const extensionTheme of extensionThemes) {
|
|
310
|
+
seen.push(extensionTheme)
|
|
311
|
+
merged.push(extensionTheme)
|
|
312
|
+
}
|
|
313
|
+
for (const builtinTheme of builtinThemes) {
|
|
314
|
+
if (seen.includes(builtinTheme)) {
|
|
315
|
+
continue
|
|
316
|
+
}
|
|
317
|
+
merged.push(builtinTheme)
|
|
318
|
+
}
|
|
319
|
+
const sorted = toSorted(merged, compare)
|
|
320
|
+
return sorted
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const themeIds = mergeThemes(themeDirents.map(getThemeName), [colorThemeName])
|
|
324
|
+
writeJson(join(root, 'dist', commitHash, 'config', 'themes.json'), themeIds)
|
|
325
|
+
|
|
326
|
+
for (const iconThemeDirent of iconThemeDirents) {
|
|
327
|
+
const iconThemeId = iconThemeDirent.slice('builtin.'.length)
|
|
328
|
+
cpSync(
|
|
329
|
+
join(
|
|
330
|
+
root,
|
|
331
|
+
'node_modules',
|
|
332
|
+
'@lvce-editor',
|
|
333
|
+
'shared-process',
|
|
334
|
+
'extensions',
|
|
335
|
+
iconThemeDirent,
|
|
336
|
+
'icon-theme.json'
|
|
337
|
+
),
|
|
338
|
+
join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
339
|
+
)
|
|
340
|
+
cpSync(
|
|
341
|
+
join(
|
|
342
|
+
root,
|
|
343
|
+
'node_modules',
|
|
344
|
+
'@lvce-editor',
|
|
345
|
+
'shared-process',
|
|
346
|
+
'extensions',
|
|
347
|
+
iconThemeDirent,
|
|
348
|
+
'icons'
|
|
349
|
+
),
|
|
350
|
+
join(root, 'dist', commitHash, 'file-icons'),
|
|
351
|
+
{
|
|
352
|
+
recursive: true,
|
|
353
|
+
}
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
cpSync(
|
|
358
|
+
join(root, 'color-theme.json'),
|
|
359
|
+
join(root, 'dist', commitHash, 'themes', `${colorThemeName}.json`)
|
|
360
|
+
)
|
|
361
|
+
replaceSync(
|
|
362
|
+
join(root, 'dist', 'index.html'),
|
|
363
|
+
`/${commitHash}`,
|
|
364
|
+
`${pathPrefix}/${commitHash}`
|
|
365
|
+
)
|
|
366
|
+
replaceSync(
|
|
367
|
+
join(root, 'dist', 'index.html'),
|
|
368
|
+
`/manifest.json`,
|
|
369
|
+
`${pathPrefix}/manifest.json`
|
|
370
|
+
)
|
|
371
|
+
replaceSync(
|
|
372
|
+
join(root, 'dist', 'index.html'),
|
|
373
|
+
'<title>Code Editor</title>',
|
|
374
|
+
`<title>${name}</title>`
|
|
375
|
+
)
|
|
376
|
+
replaceSync(
|
|
377
|
+
join(root, 'dist', 'manifest.json'),
|
|
378
|
+
`"name": "Code Editor Web - OSS"`,
|
|
379
|
+
`"name": "${name}"`
|
|
380
|
+
)
|
|
381
|
+
replaceSync(
|
|
382
|
+
join(root, 'dist', 'manifest.json'),
|
|
383
|
+
`"short_name": "Web - OSS"`,
|
|
384
|
+
`"short_name": "${name}"`
|
|
385
|
+
)
|
|
386
|
+
replaceSync(
|
|
387
|
+
join(root, 'dist', 'manifest.json'),
|
|
388
|
+
`"description": "Web Code Editor."`,
|
|
389
|
+
`"description": "${description}"`
|
|
390
|
+
)
|
|
391
|
+
replaceSync(
|
|
392
|
+
join(root, 'dist', 'index.html'),
|
|
393
|
+
'<meta name="description" content="Online Code Editor" />',
|
|
394
|
+
`<meta name="description" content="${description}" />`
|
|
395
|
+
)
|
|
396
|
+
replaceSync(
|
|
397
|
+
join(root, 'dist', 'index.html'),
|
|
398
|
+
'</title>',
|
|
399
|
+
`</title>
|
|
400
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">`
|
|
401
|
+
)
|
|
402
|
+
replaceSync(
|
|
403
|
+
join(root, 'dist', 'manifest.json'),
|
|
404
|
+
`/${commitHash}`,
|
|
405
|
+
`${pathPrefix}/${commitHash}`
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
fs.copyFileSync(
|
|
409
|
+
join(root, 'README.md'),
|
|
410
|
+
join(
|
|
411
|
+
root,
|
|
412
|
+
'dist',
|
|
413
|
+
commitHash,
|
|
414
|
+
'extensions',
|
|
415
|
+
`builtin.theme-${colorThemeName}`,
|
|
416
|
+
'README.md'
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
fs.copyFileSync(
|
|
420
|
+
join(root, 'extension.json'),
|
|
421
|
+
join(
|
|
422
|
+
root,
|
|
423
|
+
'dist',
|
|
424
|
+
commitHash,
|
|
425
|
+
'extensions',
|
|
426
|
+
`builtin.theme-${colorThemeName}`,
|
|
427
|
+
'extension.json'
|
|
428
|
+
)
|
|
429
|
+
)
|
|
430
|
+
fs.copyFileSync(
|
|
431
|
+
join(root, 'color-theme.json'),
|
|
432
|
+
join(
|
|
433
|
+
root,
|
|
434
|
+
'dist',
|
|
435
|
+
commitHash,
|
|
436
|
+
'extensions',
|
|
437
|
+
`builtin.theme-${colorThemeName}`,
|
|
438
|
+
'color-theme.json'
|
|
439
|
+
)
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
replaceSync(
|
|
443
|
+
join(root, 'dist', commitHash, 'css', 'App.css'),
|
|
444
|
+
`/${commitHash}`,
|
|
445
|
+
`${pathPrefix}/${commitHash}`
|
|
446
|
+
)
|
|
447
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import extract from 'extract-zip'
|
|
2
|
+
import { mkdir } from 'node:fs/promises'
|
|
3
|
+
import VError from 'verror'
|
|
4
|
+
|
|
5
|
+
export const extractZip = async ({ inFile, outDir }) => {
|
|
6
|
+
try {
|
|
7
|
+
await mkdir(outDir, { recursive: true })
|
|
8
|
+
await extract(inFile, { dir: outDir })
|
|
9
|
+
} catch (error) {
|
|
10
|
+
throw new VError(error, `Failed to extract ${inFile}`)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -2,6 +2,8 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
|
|
|
2
2
|
|
|
3
3
|
export const load = (moduleId) => {
|
|
4
4
|
switch (moduleId) {
|
|
5
|
+
case ModuleId.ChromeExtension:
|
|
6
|
+
return import('../ChromeExtension/ChromeExtension.ipc.js')
|
|
5
7
|
case ModuleId.ClipBoard:
|
|
6
8
|
return import('../ClipBoard/ClipBoard.ipc.js')
|
|
7
9
|
case ModuleId.Developer:
|
|
@@ -2,6 +2,9 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
|
|
|
2
2
|
|
|
3
3
|
export const getModuleId = (commandId) => {
|
|
4
4
|
switch (commandId) {
|
|
5
|
+
case 'ChromeExtension.install':
|
|
6
|
+
case 'ChromeExtension.uninstall':
|
|
7
|
+
return ModuleId.ChromeExtension
|
|
5
8
|
case 'ClipBoard.readFiles':
|
|
6
9
|
case 'ClipBoard.writeFiles':
|
|
7
10
|
return ModuleId.ClipBoard
|
|
@@ -38,10 +38,18 @@ export const getCachedExtensionsPath = () => {
|
|
|
38
38
|
return Path.join(cacheDir, 'cached-extensions')
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export const getCachedChromeExtensionsPath = () => {
|
|
42
|
+
return Path.join(cacheDir, 'cached-electron-browser-view-chrome-extensions')
|
|
43
|
+
}
|
|
44
|
+
|
|
41
45
|
export const getLinkedExtensionsPath = () => {
|
|
42
46
|
return Path.join(dataDir, 'linked-extensions')
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
export const getChromeExtensionsPath = () => {
|
|
50
|
+
return Path.join(dataDir, 'electron-browser-view-chrome-extensions')
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
export const getMarketplaceUrl = () => {
|
|
46
54
|
return (
|
|
47
55
|
process.env.LVCE_MARKETPLACE_URL ||
|