@ssml-builder-js/ssml-editor-react 2.8.0 → 2.9.0
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 +19 -0
- package/dist/index.d.mts +16 -5
- package/dist/index.d.ts +16 -5
- package/dist/index.js +595 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +593 -64
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/SsmlEditor.tsx +178 -59
- package/src/buttonVisibility.ts +1 -0
- package/src/components/VisualSsmlEditor.tsx +240 -0
- package/src/constants/azureVoiceStyleMap.generated.ts +94 -0
- package/src/constants/ssmlPresets.ts +23 -2
- package/src/formatXml.ts +1 -0
- package/src/hooks/useSsmlEditorState.ts +3 -3
- package/src/index.tsx +3 -0
- package/src/locales.ts +14 -0
- package/src/ssmlCodeLens.ts +19 -4
- package/src/ssmlCompletion.ts +20 -0
- package/src/ssmlHover.ts +68 -0
- package/src/ssmlInsertions.ts +24 -1
- package/src/styles/editorStyles.ts +8 -0
- package/test/index.test.ts +21 -2
- package/test/ui-components.test.tsx +13 -0
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
SSML_HOVER_COPY: () => SSML_HOVER_COPY,
|
|
37
37
|
SSML_INSERTIONS: () => SSML_INSERTIONS,
|
|
38
38
|
SsmlEditor: () => SsmlEditor,
|
|
39
|
+
VisualSsmlEditor: () => VisualSsmlEditor,
|
|
39
40
|
createSsmlEditorInsertionDefinition: () => createSsmlEditorInsertionDefinition,
|
|
40
41
|
registerSsmlCodeLens: () => registerSsmlCodeLens,
|
|
41
42
|
updateTagAttribute: () => updateTagAttribute
|
|
@@ -43,8 +44,8 @@ __export(index_exports, {
|
|
|
43
44
|
module.exports = __toCommonJS(index_exports);
|
|
44
45
|
|
|
45
46
|
// src/SsmlEditor.tsx
|
|
46
|
-
var
|
|
47
|
-
var
|
|
47
|
+
var import_react4 = require("react");
|
|
48
|
+
var import_react5 = __toESM(require("@monaco-editor/react"));
|
|
48
49
|
|
|
49
50
|
// src/buttonVisibility.ts
|
|
50
51
|
function isSsmlEditorButtonVisible(buttonVisibility, button) {
|
|
@@ -54,6 +55,8 @@ function isSsmlEditorButtonVisible(buttonVisibility, button) {
|
|
|
54
55
|
// src/constants/ssmlPresets.ts
|
|
55
56
|
var ssmlPresets_exports = {};
|
|
56
57
|
__export(ssmlPresets_exports, {
|
|
58
|
+
AUDIO_DURATION_DESCRIPTIONS: () => AUDIO_DURATION_DESCRIPTIONS,
|
|
59
|
+
AUDIO_DURATION_PRESETS: () => AUDIO_DURATION_PRESETS,
|
|
57
60
|
BREAK_STRENGTH_PRESETS: () => BREAK_STRENGTH_PRESETS,
|
|
58
61
|
BREAK_TIME_DESCRIPTIONS: () => BREAK_TIME_DESCRIPTIONS,
|
|
59
62
|
BREAK_TIME_PRESETS: () => BREAK_TIME_PRESETS,
|
|
@@ -86,6 +89,103 @@ __export(ssmlPresets_exports, {
|
|
|
86
89
|
getExpressAsStyleCategory: () => getExpressAsStyleCategory,
|
|
87
90
|
resolveExpressAsStyles: () => resolveExpressAsStyles
|
|
88
91
|
});
|
|
92
|
+
|
|
93
|
+
// src/constants/azureVoiceStyleMap.generated.ts
|
|
94
|
+
var AZURE_VOICE_STYLE_MAP = {
|
|
95
|
+
"de-DE-ConradNeural": ["cheerful", "sad"],
|
|
96
|
+
"de-DE-KatjaNeural": ["cheerful", "sad"],
|
|
97
|
+
"en-US-AndrewNeural": ["empathetic", "relieved"],
|
|
98
|
+
"en-US-GuyNeural": [
|
|
99
|
+
"angry",
|
|
100
|
+
"cheerful",
|
|
101
|
+
"excited",
|
|
102
|
+
"friendly",
|
|
103
|
+
"hopeful",
|
|
104
|
+
"newscast",
|
|
105
|
+
"sad",
|
|
106
|
+
"shouting",
|
|
107
|
+
"terrified",
|
|
108
|
+
"unfriendly",
|
|
109
|
+
"whispering"
|
|
110
|
+
],
|
|
111
|
+
"en-US-JennyMultilingualNeural": [
|
|
112
|
+
"cheerful",
|
|
113
|
+
"empathetic",
|
|
114
|
+
"excited",
|
|
115
|
+
"friendly",
|
|
116
|
+
"hopeful",
|
|
117
|
+
"sad",
|
|
118
|
+
"shouting",
|
|
119
|
+
"terrified",
|
|
120
|
+
"unfriendly",
|
|
121
|
+
"whispering"
|
|
122
|
+
],
|
|
123
|
+
"en-US-JennyNeural": [
|
|
124
|
+
"assistant",
|
|
125
|
+
"chat",
|
|
126
|
+
"customerservice",
|
|
127
|
+
"newscast",
|
|
128
|
+
"cheerful",
|
|
129
|
+
"empathetic",
|
|
130
|
+
"excited",
|
|
131
|
+
"friendly",
|
|
132
|
+
"hopeful",
|
|
133
|
+
"sad",
|
|
134
|
+
"shouting",
|
|
135
|
+
"terrified",
|
|
136
|
+
"unfriendly",
|
|
137
|
+
"whispering"
|
|
138
|
+
],
|
|
139
|
+
"es-ES-ElviraNeural": [],
|
|
140
|
+
"fil-PH-AngeloNeural": [],
|
|
141
|
+
"fr-FR-DeniseNeural": ["cheerful", "sad"],
|
|
142
|
+
"fr-FR-HenriNeural": ["cheerful", "sad"],
|
|
143
|
+
"id-ID-GadisNeural": [],
|
|
144
|
+
"it-IT-ElsaNeural": ["cheerful", "sad"],
|
|
145
|
+
"ja-JP-KeitaNeural": ["chat"],
|
|
146
|
+
"ja-JP-MayuNeural": ["calm", "cheerful", "sad"],
|
|
147
|
+
"ja-JP-NanamiNeural": ["chat", "customerservice", "cheerful", "whispering", "sad"],
|
|
148
|
+
"ko-KR-SunHiNeural": ["cheerful", "sad"],
|
|
149
|
+
"ms-MY-YasminNeural": [],
|
|
150
|
+
"pt-BR-FranciscaNeural": ["calm"],
|
|
151
|
+
"ru-RU-SvetlanaNeural": ["cheerful", "sad", "angry", "disgruntled", "embarrassed", "fearful"],
|
|
152
|
+
"th-TH-PremwadeeNeural": [],
|
|
153
|
+
"vi-VN-HoaiMyNeural": [],
|
|
154
|
+
"zh-CN-XiaoxiaoNeural": [
|
|
155
|
+
"assistant",
|
|
156
|
+
"chat",
|
|
157
|
+
"customerservice",
|
|
158
|
+
"newscast",
|
|
159
|
+
"cheerful",
|
|
160
|
+
"empathetic",
|
|
161
|
+
"excited",
|
|
162
|
+
"friendly",
|
|
163
|
+
"hopeful",
|
|
164
|
+
"sad",
|
|
165
|
+
"terrified",
|
|
166
|
+
"whispering",
|
|
167
|
+
"poetry-reading",
|
|
168
|
+
"sports_commentary",
|
|
169
|
+
"sports_commentary_excited",
|
|
170
|
+
"story"
|
|
171
|
+
],
|
|
172
|
+
"zh-CN-YunxiNeural": [
|
|
173
|
+
"narration-relaxed",
|
|
174
|
+
"embarrassed",
|
|
175
|
+
"fearful",
|
|
176
|
+
"sad",
|
|
177
|
+
"disgruntled",
|
|
178
|
+
"serious",
|
|
179
|
+
"angry",
|
|
180
|
+
"depressed",
|
|
181
|
+
"chat",
|
|
182
|
+
"cheerful",
|
|
183
|
+
"assistant"
|
|
184
|
+
],
|
|
185
|
+
"zh-TW-HsiaoChenNeural": []
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// src/constants/ssmlPresets.ts
|
|
89
189
|
var SSML_PRESETS = [
|
|
90
190
|
{
|
|
91
191
|
id: "basic",
|
|
@@ -185,7 +285,7 @@ function getExpressAsStyleCategory(style) {
|
|
|
185
285
|
}
|
|
186
286
|
return "other";
|
|
187
287
|
}
|
|
188
|
-
var
|
|
288
|
+
var LEGACY_VOICE_STYLE_MAP = {
|
|
189
289
|
"ja-JP-MayuNeural": ["calm", "cheerful", "sad"],
|
|
190
290
|
"ja-JP-KeitaNeural": ["chat"],
|
|
191
291
|
"ja-JP-NanamiNeural": ["chat", "customerservice", "cheerful", "whispering", "sad"],
|
|
@@ -271,6 +371,7 @@ var VOICE_STYLE_MAP = {
|
|
|
271
371
|
"de-DE-ConradNeural": ["cheerful", "sad"],
|
|
272
372
|
"ru-RU-SvetlanaNeural": ["cheerful", "sad", "angry", "disgruntled", "embarrassed", "fearful"]
|
|
273
373
|
};
|
|
374
|
+
var VOICE_STYLE_MAP = Object.keys(AZURE_VOICE_STYLE_MAP).length > 0 ? AZURE_VOICE_STYLE_MAP : LEGACY_VOICE_STYLE_MAP;
|
|
274
375
|
var VOICE_STYLE_MAP_BY_NORMALIZED_NAME = new Map(
|
|
275
376
|
Object.entries(VOICE_STYLE_MAP).map(([voiceName, styles]) => [voiceName.toLowerCase(), styles])
|
|
276
377
|
);
|
|
@@ -313,6 +414,7 @@ var SAY_AS_PRESETS = [
|
|
|
313
414
|
];
|
|
314
415
|
var LANGUAGE_PRESETS = ["ja-JP", "en-US", "de-DE", "fr-FR"];
|
|
315
416
|
var SILENCE_VALUE_PRESETS = ["300ms", "500ms", "1s"];
|
|
417
|
+
var AUDIO_DURATION_PRESETS = ["5s", "10s", "30s"];
|
|
316
418
|
var SILENCE_TYPE_PRESETS = [
|
|
317
419
|
"Leading",
|
|
318
420
|
"Tailing",
|
|
@@ -321,6 +423,11 @@ var SILENCE_TYPE_PRESETS = [
|
|
|
321
423
|
"Semicolon",
|
|
322
424
|
"Enumerationcomma"
|
|
323
425
|
];
|
|
426
|
+
var AUDIO_DURATION_DESCRIPTIONS = {
|
|
427
|
+
"5s": { ja: "5\u79D2", en: "5 seconds" },
|
|
428
|
+
"10s": { ja: "10\u79D2", en: "10 seconds" },
|
|
429
|
+
"30s": { ja: "30\u79D2", en: "30 seconds" }
|
|
430
|
+
};
|
|
324
431
|
var PHONEME_ALPHABET_PRESETS = ["ipa", "sapi", "ups", "x-sampa"];
|
|
325
432
|
var VISEME_TYPE_PRESETS = ["redlips_front", "FacialExpression"];
|
|
326
433
|
var SSML_ATTRIBUTE_PRESETS = {
|
|
@@ -364,6 +471,14 @@ var SSML_ATTRIBUTE_PRESETS = {
|
|
|
364
471
|
type: SILENCE_TYPE_PRESETS,
|
|
365
472
|
value: SILENCE_VALUE_PRESETS
|
|
366
473
|
},
|
|
474
|
+
"mstts:audioduration": {
|
|
475
|
+
value: AUDIO_DURATION_PRESETS
|
|
476
|
+
},
|
|
477
|
+
"mstts:backgroundaudio": {
|
|
478
|
+
volume: PROSODY_VOLUME_PRESETS,
|
|
479
|
+
fadein: AUDIO_DURATION_PRESETS,
|
|
480
|
+
fadeout: AUDIO_DURATION_PRESETS
|
|
481
|
+
},
|
|
367
482
|
silence: {
|
|
368
483
|
type: SILENCE_TYPE_PRESETS,
|
|
369
484
|
value: SILENCE_VALUE_PRESETS
|
|
@@ -910,6 +1025,13 @@ var SSML_HOVER_COPY = {
|
|
|
910
1025
|
parameters: {
|
|
911
1026
|
type: { title: "type", description: "\u30D3\u30BC\u30FC\u30E0\u30A4\u30D9\u30F3\u30C8\u306E\u5F62\u5F0F\u3002" }
|
|
912
1027
|
}
|
|
1028
|
+
},
|
|
1029
|
+
"mstts:audioduration": {
|
|
1030
|
+
title: "\u97F3\u58F0\u9577",
|
|
1031
|
+
description: "\u5408\u6210\u97F3\u58F0\u306E\u76EE\u6A19\u6642\u9593\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002",
|
|
1032
|
+
parameters: {
|
|
1033
|
+
value: { title: "value", description: "\u76EE\u6A19\u6642\u9593\u3002\u4F8B: `10s`\u3001`5000ms`\u3001`00:00:10`\u3002" }
|
|
1034
|
+
}
|
|
913
1035
|
}
|
|
914
1036
|
}
|
|
915
1037
|
},
|
|
@@ -1067,6 +1189,13 @@ var SSML_HOVER_COPY = {
|
|
|
1067
1189
|
parameters: {
|
|
1068
1190
|
type: { title: "type", description: "The viseme event format." }
|
|
1069
1191
|
}
|
|
1192
|
+
},
|
|
1193
|
+
"mstts:audioduration": {
|
|
1194
|
+
title: "Audio duration",
|
|
1195
|
+
description: "Sets the target duration of synthesized audio.",
|
|
1196
|
+
parameters: {
|
|
1197
|
+
value: { title: "value", description: "The target duration, such as `10s`, `5000ms`, or `00:00:10`." }
|
|
1198
|
+
}
|
|
1070
1199
|
}
|
|
1071
1200
|
}
|
|
1072
1201
|
}
|
|
@@ -1166,6 +1295,14 @@ var editorStyles = {
|
|
|
1166
1295
|
display: "grid",
|
|
1167
1296
|
gap: "0.5rem"
|
|
1168
1297
|
},
|
|
1298
|
+
visual: {
|
|
1299
|
+
display: "grid",
|
|
1300
|
+
gap: "0.75rem",
|
|
1301
|
+
minHeight: "8rem",
|
|
1302
|
+
padding: "0.75rem",
|
|
1303
|
+
border: "1px solid var(--ssml-editor-control-border)",
|
|
1304
|
+
borderRadius: "0.25rem"
|
|
1305
|
+
},
|
|
1169
1306
|
toolbarIconOnly: {
|
|
1170
1307
|
justifyContent: "center",
|
|
1171
1308
|
minWidth: "2.25rem",
|
|
@@ -1604,6 +1741,7 @@ var INTRINSICALLY_EMPTY_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
1604
1741
|
"lexicon",
|
|
1605
1742
|
"mark",
|
|
1606
1743
|
"mstts:silence",
|
|
1744
|
+
"mstts:audioduration",
|
|
1607
1745
|
"mstts:viseme",
|
|
1608
1746
|
"silence",
|
|
1609
1747
|
"viseme"
|
|
@@ -2450,7 +2588,7 @@ function findSsmlVoiceContext(source, offset) {
|
|
|
2450
2588
|
}
|
|
2451
2589
|
|
|
2452
2590
|
// src/hooks/useSsmlEditorState.ts
|
|
2453
|
-
var TIMING_INSERTION_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence"]);
|
|
2591
|
+
var TIMING_INSERTION_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence", "mstts:audioduration"]);
|
|
2454
2592
|
var PROSODY_INSERTION_TAGS = /* @__PURE__ */ new Set(["prosody", "mstts:express-as", "voice", "emphasis"]);
|
|
2455
2593
|
var TEXT_INSERTION_TAGS = /* @__PURE__ */ new Set(["sub", "say-as", "phoneme", "w", "lang"]);
|
|
2456
2594
|
var EMPTY_SELECTION_OVERLAY = {
|
|
@@ -3172,6 +3310,28 @@ var SSML_COMPLETION_SNIPPETS = [
|
|
|
3172
3310
|
label: "mstts:express-as",
|
|
3173
3311
|
insertText: `<mstts:express-as style="cheerful">\${1:text}</mstts:express-as>`
|
|
3174
3312
|
},
|
|
3313
|
+
{
|
|
3314
|
+
label: "mstts:audioduration",
|
|
3315
|
+
insertText: '<mstts:audioduration value="10s" />'
|
|
3316
|
+
},
|
|
3317
|
+
{
|
|
3318
|
+
label: "mstts:dialog",
|
|
3319
|
+
insertText: `<mstts:dialog>
|
|
3320
|
+
<mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>
|
|
3321
|
+
</mstts:dialog>`
|
|
3322
|
+
},
|
|
3323
|
+
{
|
|
3324
|
+
label: "mstts:turn",
|
|
3325
|
+
insertText: `<mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>`
|
|
3326
|
+
},
|
|
3327
|
+
{
|
|
3328
|
+
label: "mstts:backgroundaudio",
|
|
3329
|
+
insertText: `<mstts:backgroundaudio src="\${1:https://example.com/audio.mp3}" volume="\${2:-3dB}" />`
|
|
3330
|
+
},
|
|
3331
|
+
{
|
|
3332
|
+
label: "mstts:ttsembedding",
|
|
3333
|
+
insertText: `<mstts:ttsembedding>\${1:text}</mstts:ttsembedding>`
|
|
3334
|
+
},
|
|
3175
3335
|
{
|
|
3176
3336
|
label: "sub",
|
|
3177
3337
|
insertText: `<sub alias="\${1:\u8AAD\u307F}">\${2:\u6F22\u5B57}</sub>`
|
|
@@ -3447,7 +3607,7 @@ function registerSsmlCodeLens(monaco, editor, onOpenPopover) {
|
|
|
3447
3607
|
break;
|
|
3448
3608
|
}
|
|
3449
3609
|
const tag = source.slice(tagStart, tagEnd + 1);
|
|
3450
|
-
const tagName = tag.match(/^<\s*(prosody|break)\b/i)?.[1]?.toLowerCase();
|
|
3610
|
+
const tagName = tag.match(/^<\s*(prosody|break|mstts:audioduration)\b/i)?.[1]?.toLowerCase();
|
|
3451
3611
|
index = tagEnd + 1;
|
|
3452
3612
|
if (!tagName) {
|
|
3453
3613
|
continue;
|
|
@@ -3477,7 +3637,22 @@ function registerSsmlCodeLens(monaco, editor, onOpenPopover) {
|
|
|
3477
3637
|
elementRange
|
|
3478
3638
|
})
|
|
3479
3639
|
);
|
|
3480
|
-
} else if (/\/\s*>$/.test(tag)) {
|
|
3640
|
+
} else if (tagName === "mstts:audioduration" && /\/\s*>$/.test(tag)) {
|
|
3641
|
+
lenses.push(
|
|
3642
|
+
createLens(
|
|
3643
|
+
model,
|
|
3644
|
+
tagStart,
|
|
3645
|
+
tagEnd + 1,
|
|
3646
|
+
`\u26A1 Duration: ${getAttributeValue(tag, "value") ?? "default"} (Click to edit)`,
|
|
3647
|
+
{ type: "attribute", insertionId: "mstts:audioduration", attributeName: "value", tagRange }
|
|
3648
|
+
),
|
|
3649
|
+
createLens(model, tagStart, tagEnd + 1, "Delete", {
|
|
3650
|
+
type: "delete",
|
|
3651
|
+
tagRange,
|
|
3652
|
+
elementRange
|
|
3653
|
+
})
|
|
3654
|
+
);
|
|
3655
|
+
} else if (tagName === "break" && /\/\s*>$/.test(tag)) {
|
|
3481
3656
|
lenses.push(
|
|
3482
3657
|
createLens(
|
|
3483
3658
|
model,
|
|
@@ -3813,6 +3988,74 @@ var SSML_TAG_DEFINITIONS = [
|
|
|
3813
3988
|
values: VISEME_TYPE_PRESETS2
|
|
3814
3989
|
}
|
|
3815
3990
|
]
|
|
3991
|
+
},
|
|
3992
|
+
{
|
|
3993
|
+
name: "mstts:audioduration",
|
|
3994
|
+
description: "Sets the target duration of synthesized audio.",
|
|
3995
|
+
parameters: [
|
|
3996
|
+
{
|
|
3997
|
+
name: "value",
|
|
3998
|
+
description: "The target duration, such as `10s`, `5000ms`, or `00:00:10`.",
|
|
3999
|
+
example: "10s"
|
|
4000
|
+
}
|
|
4001
|
+
]
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
name: "mstts:dialog",
|
|
4005
|
+
description: "Groups multiple Azure dialog turns that can use different voices.",
|
|
4006
|
+
parameters: []
|
|
4007
|
+
},
|
|
4008
|
+
{
|
|
4009
|
+
name: "mstts:turn",
|
|
4010
|
+
description: "Adds one dialog turn using the required Azure voice name.",
|
|
4011
|
+
parameters: [
|
|
4012
|
+
{
|
|
4013
|
+
name: "voice",
|
|
4014
|
+
description: "The Azure voice used for this turn, such as `en-US-JennyNeural`.",
|
|
4015
|
+
example: "en-US-JennyNeural"
|
|
4016
|
+
}
|
|
4017
|
+
]
|
|
4018
|
+
},
|
|
4019
|
+
{
|
|
4020
|
+
name: "mstts:backgroundaudio",
|
|
4021
|
+
description: "Plays background audio while speech is synthesized.",
|
|
4022
|
+
parameters: [
|
|
4023
|
+
{
|
|
4024
|
+
name: "src",
|
|
4025
|
+
description: "An absolute HTTP(S) URL for the background audio file.",
|
|
4026
|
+
example: "https://example.com/music.mp3"
|
|
4027
|
+
},
|
|
4028
|
+
{
|
|
4029
|
+
name: "volume",
|
|
4030
|
+
description: "The background audio volume, for example `-3dB` or `medium`.",
|
|
4031
|
+
example: "-3dB"
|
|
4032
|
+
},
|
|
4033
|
+
{
|
|
4034
|
+
name: "fadein",
|
|
4035
|
+
description: "The fade-in duration, for example `1s`.",
|
|
4036
|
+
example: "1s"
|
|
4037
|
+
},
|
|
4038
|
+
{
|
|
4039
|
+
name: "fadeout",
|
|
4040
|
+
description: "The fade-out duration, for example `500ms`.",
|
|
4041
|
+
example: "500ms"
|
|
4042
|
+
}
|
|
4043
|
+
]
|
|
4044
|
+
},
|
|
4045
|
+
{
|
|
4046
|
+
name: "mstts:ttsembedding",
|
|
4047
|
+
description: "Embeds custom voice or speaker profile metadata for Azure Speech.",
|
|
4048
|
+
parameters: []
|
|
4049
|
+
},
|
|
4050
|
+
{
|
|
4051
|
+
name: "mstts:embedding",
|
|
4052
|
+
description: "Specifies embedding metadata for custom voice scenarios.",
|
|
4053
|
+
parameters: []
|
|
4054
|
+
},
|
|
4055
|
+
{
|
|
4056
|
+
name: "mstts:voiceconversion",
|
|
4057
|
+
description: "Specifies voice conversion metadata for custom voice scenarios.",
|
|
4058
|
+
parameters: []
|
|
3816
4059
|
}
|
|
3817
4060
|
];
|
|
3818
4061
|
var definitionsByName = /* @__PURE__ */ new Map();
|
|
@@ -4417,10 +4660,182 @@ function useSsmlMonaco({
|
|
|
4417
4660
|
return { editorRef, onMount };
|
|
4418
4661
|
}
|
|
4419
4662
|
|
|
4420
|
-
// src/
|
|
4663
|
+
// src/components/VisualSsmlEditor.tsx
|
|
4664
|
+
var import_react3 = require("react");
|
|
4665
|
+
var import_ssml_core4 = require("@ssml-builder-js/ssml-core");
|
|
4421
4666
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4667
|
+
function isElement(node) {
|
|
4668
|
+
return typeof node !== "string" && node.type !== "text";
|
|
4669
|
+
}
|
|
4670
|
+
function elementLabel(element) {
|
|
4671
|
+
return element.type === "custom" || element.type === "element" ? element.name : element.type;
|
|
4672
|
+
}
|
|
4673
|
+
function collectTextLeaves(nodes, path = [], ancestors = []) {
|
|
4674
|
+
return nodes.flatMap((node, index) => {
|
|
4675
|
+
const currentPath = [...path, index];
|
|
4676
|
+
if (typeof node === "string") return [{ ancestors, path: currentPath, value: node }];
|
|
4677
|
+
if (node.type === "text") return [{ ancestors, path: currentPath, value: node.value }];
|
|
4678
|
+
return collectTextLeaves(node.children ?? [], currentPath, [...ancestors, elementLabel(node)]);
|
|
4679
|
+
});
|
|
4680
|
+
}
|
|
4681
|
+
function updateNodesAtPath(nodes, path, update) {
|
|
4682
|
+
if (path.length === 0) return nodes;
|
|
4683
|
+
const [index, ...rest] = path;
|
|
4684
|
+
return nodes.flatMap((node, nodeIndex) => {
|
|
4685
|
+
if (nodeIndex !== index) return [node];
|
|
4686
|
+
if (rest.length === 0) {
|
|
4687
|
+
const next = update(node);
|
|
4688
|
+
return Array.isArray(next) ? next : [next];
|
|
4689
|
+
}
|
|
4690
|
+
if (!isElement(node)) return [node];
|
|
4691
|
+
return [{ ...node, children: updateNodesAtPath(node.children ?? [], rest, update) }];
|
|
4692
|
+
});
|
|
4693
|
+
}
|
|
4694
|
+
function updateTextAtPath(document2, path, value) {
|
|
4695
|
+
return { ...document2, children: updateNodesAtPath(document2.children ?? [], path, () => value) };
|
|
4696
|
+
}
|
|
4697
|
+
function wrapTextAtPath(document2, path, start, end, tag, attributes) {
|
|
4698
|
+
return {
|
|
4699
|
+
...document2,
|
|
4700
|
+
children: updateNodesAtPath(document2.children ?? [], path, (node) => {
|
|
4701
|
+
const value = typeof node === "string" ? node : node.type === "text" ? node.value : "";
|
|
4702
|
+
if (!value || start === end) return node;
|
|
4703
|
+
if (tag === "break") {
|
|
4704
|
+
return [
|
|
4705
|
+
value.slice(0, start),
|
|
4706
|
+
{ type: tag, attributes, children: [] },
|
|
4707
|
+
value.slice(start)
|
|
4708
|
+
].filter((part) => typeof part === "string" ? part.length > 0 : true);
|
|
4709
|
+
}
|
|
4710
|
+
const selected = value.slice(start, end);
|
|
4711
|
+
const wrapped = { type: tag, attributes, children: [selected] };
|
|
4712
|
+
return [value.slice(0, start), wrapped, value.slice(end)].filter(
|
|
4713
|
+
(part) => typeof part === "string" ? part.length > 0 : true
|
|
4714
|
+
);
|
|
4715
|
+
})
|
|
4716
|
+
};
|
|
4717
|
+
}
|
|
4718
|
+
function TreeNode({
|
|
4719
|
+
node,
|
|
4720
|
+
path,
|
|
4721
|
+
selectedPath,
|
|
4722
|
+
onSelect
|
|
4723
|
+
}) {
|
|
4724
|
+
if (!isElement(node)) return null;
|
|
4725
|
+
const name = elementLabel(node);
|
|
4726
|
+
const isSelected = selectedPath?.join(".") === path.join(".");
|
|
4727
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
|
|
4728
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path), children: `<${name}>` }),
|
|
4729
|
+
(node.children ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: node.children?.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4730
|
+
TreeNode,
|
|
4731
|
+
{
|
|
4732
|
+
node: child,
|
|
4733
|
+
path: [...path, index],
|
|
4734
|
+
selectedPath,
|
|
4735
|
+
onSelect
|
|
4736
|
+
},
|
|
4737
|
+
`${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`
|
|
4738
|
+
)) })
|
|
4739
|
+
] });
|
|
4740
|
+
}
|
|
4741
|
+
function VisualSsmlEditor({
|
|
4742
|
+
document: document2,
|
|
4743
|
+
readOnly = false,
|
|
4744
|
+
onChange,
|
|
4745
|
+
onPreviewSelection
|
|
4746
|
+
}) {
|
|
4747
|
+
const [selectedPath, setSelectedPath] = (0, import_react3.useState)(null);
|
|
4748
|
+
const [selection, setSelection] = (0, import_react3.useState)({ start: 0, end: 0 });
|
|
4749
|
+
const textLeaves = (0, import_react3.useMemo)(() => collectTextLeaves(document2.children ?? []), [document2]);
|
|
4750
|
+
const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
|
|
4751
|
+
const diagnostics = (0, import_react3.useMemo)(() => (0, import_ssml_core4.validateAzureSsml)((0, import_ssml_core4.buildSsml)(document2)), [document2]);
|
|
4752
|
+
const commit = (nextDocument) => onChange?.(nextDocument);
|
|
4753
|
+
const applyWrapper = (tag, attributes) => {
|
|
4754
|
+
if (readOnly || !selectedLeaf) return;
|
|
4755
|
+
const start = selection.start === selection.end ? 0 : selection.start;
|
|
4756
|
+
const end = selection.start === selection.end ? selectedLeaf.value.length : selection.end;
|
|
4757
|
+
commit(wrapTextAtPath(document2, selectedLeaf.path, start, end, tag, attributes));
|
|
4758
|
+
};
|
|
4759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ssml-editor-visual", "data-ssml-editor-visual": "", children: [
|
|
4760
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("fieldset", { className: "ssml-editor-visual-breadcrumb", children: [
|
|
4761
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("legend", { children: "SSML structure breadcrumb" }),
|
|
4762
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "<speak>" }),
|
|
4763
|
+
selectedLeaf?.ancestors.map((ancestor, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
4764
|
+
" / <",
|
|
4765
|
+
ancestor,
|
|
4766
|
+
">"
|
|
4767
|
+
] }, selectedLeaf?.ancestors.slice(0, index + 1).join("/"))),
|
|
4768
|
+
selectedPath && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => setSelectedPath(null), children: "Clear parent" })
|
|
4769
|
+
] }),
|
|
4770
|
+
diagnostics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { role: "alert", "aria-invalid": "true", className: "ssml-editor-visual-errors", children: diagnostics.map((diagnostic) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: diagnostic.message }, `${diagnostic.code}-${diagnostic.message}`)) }),
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ssml-editor-visual-layout", children: [
|
|
4772
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("nav", { "aria-label": "SSML structure tree", className: "ssml-editor-visual-tree", children: [
|
|
4773
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Structure" }),
|
|
4774
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: document2.children?.map((node, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4775
|
+
TreeNode,
|
|
4776
|
+
{
|
|
4777
|
+
node,
|
|
4778
|
+
path: [index],
|
|
4779
|
+
selectedPath,
|
|
4780
|
+
onSelect: setSelectedPath
|
|
4781
|
+
},
|
|
4782
|
+
isElement(node) ? elementLabel(node) : JSON.stringify(node)
|
|
4783
|
+
)) })
|
|
4784
|
+
] }),
|
|
4785
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ssml-editor-visual-form", children: selectedLeaf ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
4786
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
|
|
4787
|
+
"Text",
|
|
4788
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4789
|
+
"textarea",
|
|
4790
|
+
{
|
|
4791
|
+
value: selectedLeaf.value,
|
|
4792
|
+
readOnly,
|
|
4793
|
+
onSelect: (event) => setSelection({ start: event.currentTarget.selectionStart, end: event.currentTarget.selectionEnd }),
|
|
4794
|
+
onChange: (event) => commit(updateTextAtPath(document2, selectedLeaf.path, event.target.value))
|
|
4795
|
+
}
|
|
4796
|
+
)
|
|
4797
|
+
] }),
|
|
4798
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("fieldset", { className: "ssml-editor-visual-actions", children: [
|
|
4799
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("legend", { children: "Apply SSML formatting" }),
|
|
4800
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { rate: "slow" }), children: "Rate" }),
|
|
4801
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { pitch: "high" }), children: "Pitch" }),
|
|
4802
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4803
|
+
"button",
|
|
4804
|
+
{
|
|
4805
|
+
type: "button",
|
|
4806
|
+
disabled: readOnly,
|
|
4807
|
+
onClick: () => applyWrapper("mstts:express-as", { style: "cheerful" }),
|
|
4808
|
+
children: "Emotion"
|
|
4809
|
+
}
|
|
4810
|
+
),
|
|
4811
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("break", { time: "500ms" }), children: "Pause" }),
|
|
4812
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4813
|
+
"button",
|
|
4814
|
+
{
|
|
4815
|
+
type: "button",
|
|
4816
|
+
disabled: readOnly,
|
|
4817
|
+
onClick: () => applyWrapper("phoneme", { alphabet: "ipa", ph: selectedLeaf.value }),
|
|
4818
|
+
children: "Pronunciation"
|
|
4819
|
+
}
|
|
4820
|
+
),
|
|
4821
|
+
onPreviewSelection && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4822
|
+
"button",
|
|
4823
|
+
{
|
|
4824
|
+
type: "button",
|
|
4825
|
+
onClick: () => onPreviewSelection((0, import_ssml_core4.buildSsml)({ ...document2, children: [selectedLeaf.value] })),
|
|
4826
|
+
children: "Preview selection"
|
|
4827
|
+
}
|
|
4828
|
+
)
|
|
4829
|
+
] })
|
|
4830
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "Select an element or text node to edit it." }) })
|
|
4831
|
+
] })
|
|
4832
|
+
] });
|
|
4833
|
+
}
|
|
4834
|
+
|
|
4835
|
+
// src/SsmlEditor.tsx
|
|
4836
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
4422
4837
|
var UNGROUPED_TOOLBAR_GROUP = "__ssml-editor-ungrouped__";
|
|
4423
|
-
var TIMING_POPOVER_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence"]);
|
|
4838
|
+
var TIMING_POPOVER_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence", "mstts:audioduration"]);
|
|
4424
4839
|
var PROSODY_POPOVER_TAGS = /* @__PURE__ */ new Set(["prosody", "mstts:express-as", "voice", "emphasis"]);
|
|
4425
4840
|
var TEXT_POPOVER_TAGS = /* @__PURE__ */ new Set(["sub", "say-as", "phoneme", "w", "lang"]);
|
|
4426
4841
|
function localizedText(value) {
|
|
@@ -4648,13 +5063,34 @@ var SSML_INSERTIONS = [
|
|
|
4648
5063
|
suffix: "",
|
|
4649
5064
|
mode: "insert"
|
|
4650
5065
|
})
|
|
5066
|
+
},
|
|
5067
|
+
{
|
|
5068
|
+
id: "mstts:audioduration",
|
|
5069
|
+
icon: "\u25F7",
|
|
5070
|
+
tagName: "mstts:audioduration",
|
|
5071
|
+
selfClosing: true,
|
|
5072
|
+
labels: { ja: "\u97F3\u58F0\u9577", en: "Audio duration" },
|
|
5073
|
+
descriptions: {
|
|
5074
|
+
ja: "\u5408\u6210\u97F3\u58F0\u306E\u76EE\u6A19\u6642\u9593\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002",
|
|
5075
|
+
en: "Sets the target duration of synthesized audio."
|
|
5076
|
+
},
|
|
5077
|
+
parameterDescription: {
|
|
5078
|
+
ja: "\u76EE\u6A19\u6642\u9593\u3092\u9078\u629E\u3057\u307E\u3059\u3002",
|
|
5079
|
+
en: "Selects the target duration."
|
|
5080
|
+
},
|
|
5081
|
+
options: createInsertionOptions(AUDIO_DURATION_PRESETS, AUDIO_DURATION_DESCRIPTIONS),
|
|
5082
|
+
createTemplate: (value) => ({
|
|
5083
|
+
prefix: `<mstts:audioduration value="${value}"/>`,
|
|
5084
|
+
suffix: "",
|
|
5085
|
+
mode: "insert"
|
|
5086
|
+
})
|
|
4651
5087
|
}
|
|
4652
5088
|
];
|
|
4653
5089
|
var DEFAULT_INSERTION_GROUPS = [
|
|
4654
5090
|
{
|
|
4655
5091
|
id: "pauses",
|
|
4656
5092
|
labels: { ja: "\u9593\u30FB\u7121\u97F3", en: "Pauses" },
|
|
4657
|
-
insertionIds: ["break", "mstts:silence"]
|
|
5093
|
+
insertionIds: ["break", "mstts:silence", "mstts:audioduration"]
|
|
4658
5094
|
},
|
|
4659
5095
|
{
|
|
4660
5096
|
id: "prosody",
|
|
@@ -4863,6 +5299,60 @@ var STYLE_CSS = `
|
|
|
4863
5299
|
> .ssml-editor-help-settings-summary::before {
|
|
4864
5300
|
content: "\u25BE";
|
|
4865
5301
|
}
|
|
5302
|
+
[data-ssml-editor] .ssml-editor-visual-layout {
|
|
5303
|
+
display: grid;
|
|
5304
|
+
grid-template-columns: minmax(12rem, 0.35fr) minmax(16rem, 1fr);
|
|
5305
|
+
gap: 1rem;
|
|
5306
|
+
}
|
|
5307
|
+
[data-ssml-editor] .ssml-editor-visual-tree,
|
|
5308
|
+
[data-ssml-editor] .ssml-editor-visual-form {
|
|
5309
|
+
display: grid;
|
|
5310
|
+
gap: 0.5rem;
|
|
5311
|
+
align-content: start;
|
|
5312
|
+
}
|
|
5313
|
+
[data-ssml-editor] .ssml-editor-visual-tree ul {
|
|
5314
|
+
margin: 0;
|
|
5315
|
+
padding-left: 1.25rem;
|
|
5316
|
+
}
|
|
5317
|
+
[data-ssml-editor] .ssml-editor-visual-tree button,
|
|
5318
|
+
[data-ssml-editor] .ssml-editor-visual-breadcrumb button,
|
|
5319
|
+
[data-ssml-editor] .ssml-editor-visual-actions button {
|
|
5320
|
+
padding: 0.35rem 0.5rem;
|
|
5321
|
+
border: 1px solid var(--ssml-editor-control-border);
|
|
5322
|
+
border-radius: 0.25rem;
|
|
5323
|
+
color: var(--ssml-editor-color);
|
|
5324
|
+
background: var(--ssml-editor-control-bg);
|
|
5325
|
+
cursor: pointer;
|
|
5326
|
+
}
|
|
5327
|
+
[data-ssml-editor] .ssml-editor-visual-tree button[aria-current] {
|
|
5328
|
+
border-color: var(--ssml-editor-active-border);
|
|
5329
|
+
background: var(--ssml-editor-active-bg);
|
|
5330
|
+
}
|
|
5331
|
+
[data-ssml-editor] .ssml-editor-visual-breadcrumb,
|
|
5332
|
+
[data-ssml-editor] .ssml-editor-visual-actions {
|
|
5333
|
+
display: flex;
|
|
5334
|
+
flex-wrap: wrap;
|
|
5335
|
+
gap: 0.4rem;
|
|
5336
|
+
align-items: center;
|
|
5337
|
+
}
|
|
5338
|
+
[data-ssml-editor] .ssml-editor-visual-form textarea {
|
|
5339
|
+
box-sizing: border-box;
|
|
5340
|
+
width: 100%;
|
|
5341
|
+
min-height: 6rem;
|
|
5342
|
+
padding: 0.5rem;
|
|
5343
|
+
color: var(--ssml-editor-color);
|
|
5344
|
+
background: var(--ssml-editor-control-bg);
|
|
5345
|
+
border: 1px solid var(--ssml-editor-control-border);
|
|
5346
|
+
border-radius: 0.25rem;
|
|
5347
|
+
font: inherit;
|
|
5348
|
+
}
|
|
5349
|
+
[data-ssml-editor] .ssml-editor-visual-errors {
|
|
5350
|
+
padding: 0.5rem;
|
|
5351
|
+
color: var(--ssml-editor-error);
|
|
5352
|
+
background: var(--ssml-editor-error-bg);
|
|
5353
|
+
border: 1px solid var(--ssml-editor-error);
|
|
5354
|
+
border-radius: 0.25rem;
|
|
5355
|
+
}
|
|
4866
5356
|
`.trim();
|
|
4867
5357
|
function injectEditorTheme() {
|
|
4868
5358
|
if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
|
|
@@ -4879,10 +5369,10 @@ function ToolbarDecorationsSwitch({
|
|
|
4879
5369
|
decorationsVisible,
|
|
4880
5370
|
onVisibilityChange
|
|
4881
5371
|
}) {
|
|
4882
|
-
return /* @__PURE__ */ (0,
|
|
4883
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
4884
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
4885
|
-
/* @__PURE__ */ (0,
|
|
5372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: editorStyles.toolbarSwitch, children: [
|
|
5373
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2606" }),
|
|
5374
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.decorations }),
|
|
5375
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4886
5376
|
"button",
|
|
4887
5377
|
{
|
|
4888
5378
|
type: "button",
|
|
@@ -4893,12 +5383,12 @@ function ToolbarDecorationsSwitch({
|
|
|
4893
5383
|
"aria-label": copy.decorations,
|
|
4894
5384
|
title: decorationsVisible ? copy.decorationsHideTitle : copy.decorationsShowTitle,
|
|
4895
5385
|
onClick: () => onVisibilityChange(!decorationsVisible),
|
|
4896
|
-
children: /* @__PURE__ */ (0,
|
|
5386
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ssml-editor-switch-thumb", style: editorStyles.toolbarSwitchThumb, "aria-hidden": "true" })
|
|
4897
5387
|
}
|
|
4898
5388
|
)
|
|
4899
5389
|
] });
|
|
4900
5390
|
}
|
|
4901
|
-
var SsmlEditor = (0,
|
|
5391
|
+
var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
|
|
4902
5392
|
document: document2,
|
|
4903
5393
|
onChange,
|
|
4904
5394
|
onSsmlChange,
|
|
@@ -4936,8 +5426,11 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
4936
5426
|
toolbarStyle,
|
|
4937
5427
|
displayClassName,
|
|
4938
5428
|
displayStyle,
|
|
4939
|
-
loadingFallback
|
|
5429
|
+
loadingFallback,
|
|
5430
|
+
editMode: editModeProp = "code"
|
|
4940
5431
|
}, ref) {
|
|
5432
|
+
const [editMode, setEditMode] = (0, import_react4.useState)(editModeProp);
|
|
5433
|
+
(0, import_react4.useEffect)(() => setEditMode(editModeProp), [editModeProp]);
|
|
4941
5434
|
const resolvedEditorOptions = {
|
|
4942
5435
|
...settings,
|
|
4943
5436
|
...editorOptions,
|
|
@@ -5015,6 +5508,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5015
5508
|
);
|
|
5016
5509
|
const {
|
|
5017
5510
|
editorRef,
|
|
5511
|
+
draftDocument,
|
|
5018
5512
|
text,
|
|
5019
5513
|
selectionOverlay,
|
|
5020
5514
|
activeTags,
|
|
@@ -5026,6 +5520,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5026
5520
|
syntaxError,
|
|
5027
5521
|
setSyntaxError,
|
|
5028
5522
|
helpPanelId,
|
|
5523
|
+
commit,
|
|
5029
5524
|
handleTextChange,
|
|
5030
5525
|
handleInsert,
|
|
5031
5526
|
handleInsertBreak,
|
|
@@ -5073,7 +5568,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5073
5568
|
enableCodeLens,
|
|
5074
5569
|
onOpenPopover: handleCodeLensAction
|
|
5075
5570
|
});
|
|
5076
|
-
(0,
|
|
5571
|
+
(0, import_react4.useImperativeHandle)(
|
|
5077
5572
|
ref,
|
|
5078
5573
|
() => ({
|
|
5079
5574
|
getSelectedSsml: getSelectedSsml2,
|
|
@@ -5103,15 +5598,15 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5103
5598
|
onApply: isTimingPopover ? handleInsertBreak : isProsodyPopover ? handleInsertProsody : isTextPopover ? handleInsertText : handleInsert
|
|
5104
5599
|
};
|
|
5105
5600
|
if (isTimingPopover) {
|
|
5106
|
-
return /* @__PURE__ */ (0,
|
|
5601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TimingPopovers, { ...props, insertions: [insertion] });
|
|
5107
5602
|
}
|
|
5108
5603
|
if (isProsodyPopover) {
|
|
5109
|
-
return /* @__PURE__ */ (0,
|
|
5604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProsodyPopovers, { ...props, insertions: [insertion], voiceName: popoverVoiceName });
|
|
5110
5605
|
}
|
|
5111
5606
|
if (isTextPopover) {
|
|
5112
|
-
return /* @__PURE__ */ (0,
|
|
5607
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TextPopovers, { ...props, insertions: [insertion] });
|
|
5113
5608
|
}
|
|
5114
|
-
return /* @__PURE__ */ (0,
|
|
5609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5115
5610
|
InsertionPopover,
|
|
5116
5611
|
{
|
|
5117
5612
|
...props,
|
|
@@ -5124,7 +5619,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5124
5619
|
const toolbarItemRenderers = /* @__PURE__ */ new Map([
|
|
5125
5620
|
[
|
|
5126
5621
|
"undo",
|
|
5127
|
-
() => /* @__PURE__ */ (0,
|
|
5622
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5128
5623
|
"button",
|
|
5129
5624
|
{
|
|
5130
5625
|
type: "button",
|
|
@@ -5138,8 +5633,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5138
5633
|
}
|
|
5139
5634
|
},
|
|
5140
5635
|
children: [
|
|
5141
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
5142
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
5636
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21A9" }),
|
|
5637
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.undo })
|
|
5143
5638
|
]
|
|
5144
5639
|
},
|
|
5145
5640
|
"undo"
|
|
@@ -5147,7 +5642,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5147
5642
|
],
|
|
5148
5643
|
[
|
|
5149
5644
|
"redo",
|
|
5150
|
-
() => /* @__PURE__ */ (0,
|
|
5645
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5151
5646
|
"button",
|
|
5152
5647
|
{
|
|
5153
5648
|
type: "button",
|
|
@@ -5161,8 +5656,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5161
5656
|
}
|
|
5162
5657
|
},
|
|
5163
5658
|
children: [
|
|
5164
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
5165
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
5659
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21AA" }),
|
|
5660
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.redo })
|
|
5166
5661
|
]
|
|
5167
5662
|
},
|
|
5168
5663
|
"redo"
|
|
@@ -5170,7 +5665,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5170
5665
|
],
|
|
5171
5666
|
[
|
|
5172
5667
|
"clearAll",
|
|
5173
|
-
() => /* @__PURE__ */ (0,
|
|
5668
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5174
5669
|
"button",
|
|
5175
5670
|
{
|
|
5176
5671
|
type: "button",
|
|
@@ -5184,8 +5679,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5184
5679
|
}
|
|
5185
5680
|
},
|
|
5186
5681
|
children: [
|
|
5187
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
5188
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
5682
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\xD7" }),
|
|
5683
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.clearAll })
|
|
5189
5684
|
]
|
|
5190
5685
|
},
|
|
5191
5686
|
"clearAll"
|
|
@@ -5193,7 +5688,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5193
5688
|
],
|
|
5194
5689
|
[
|
|
5195
5690
|
"format",
|
|
5196
|
-
() => /* @__PURE__ */ (0,
|
|
5691
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5197
5692
|
"button",
|
|
5198
5693
|
{
|
|
5199
5694
|
type: "button",
|
|
@@ -5207,8 +5702,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5207
5702
|
}
|
|
5208
5703
|
},
|
|
5209
5704
|
children: [
|
|
5210
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
5211
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
5705
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2261" }),
|
|
5706
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.format })
|
|
5212
5707
|
]
|
|
5213
5708
|
},
|
|
5214
5709
|
"format"
|
|
@@ -5216,7 +5711,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5216
5711
|
],
|
|
5217
5712
|
[
|
|
5218
5713
|
"decorations",
|
|
5219
|
-
() => /* @__PURE__ */ (0,
|
|
5714
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5220
5715
|
ToolbarDecorationsSwitch,
|
|
5221
5716
|
{
|
|
5222
5717
|
copy,
|
|
@@ -5230,7 +5725,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5230
5725
|
],
|
|
5231
5726
|
[
|
|
5232
5727
|
"help",
|
|
5233
|
-
() => /* @__PURE__ */ (0,
|
|
5728
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5234
5729
|
"button",
|
|
5235
5730
|
{
|
|
5236
5731
|
type: "button",
|
|
@@ -5241,8 +5736,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5241
5736
|
"aria-controls": helpPanelId,
|
|
5242
5737
|
onClick: () => setIsHelpOpen((open) => !open),
|
|
5243
5738
|
children: [
|
|
5244
|
-
showToolbarIcons && /* @__PURE__ */ (0,
|
|
5245
|
-
showToolbarText && /* @__PURE__ */ (0,
|
|
5739
|
+
showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "?" }),
|
|
5740
|
+
showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.help })
|
|
5246
5741
|
]
|
|
5247
5742
|
},
|
|
5248
5743
|
"help"
|
|
@@ -5266,15 +5761,15 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5266
5761
|
previousRenderedGroupId = groupId;
|
|
5267
5762
|
hasRenderedToolbarItem = true;
|
|
5268
5763
|
renderedItems.push(
|
|
5269
|
-
/* @__PURE__ */ (0,
|
|
5270
|
-
showSeparator && /* @__PURE__ */ (0,
|
|
5764
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react4.Fragment, { children: [
|
|
5765
|
+
showSeparator && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
|
|
5271
5766
|
render()
|
|
5272
5767
|
] }, id)
|
|
5273
5768
|
);
|
|
5274
5769
|
}
|
|
5275
5770
|
return renderedItems;
|
|
5276
5771
|
};
|
|
5277
|
-
return /* @__PURE__ */ (0,
|
|
5772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5278
5773
|
"section",
|
|
5279
5774
|
{
|
|
5280
5775
|
className,
|
|
@@ -5283,62 +5778,93 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5283
5778
|
"data-ssml-editor": "",
|
|
5284
5779
|
"data-theme": isDarkTheme ? "dark" : "light",
|
|
5285
5780
|
children: [
|
|
5286
|
-
showToolbar && /* @__PURE__ */ (0,
|
|
5781
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5287
5782
|
"div",
|
|
5288
5783
|
{
|
|
5289
5784
|
className: toolbarClassName,
|
|
5290
5785
|
style: { ...editorStyles.toolbarContainer, ...toolbarStyle },
|
|
5291
5786
|
"data-ssml-editor-toolbar": "",
|
|
5292
|
-
children: /* @__PURE__ */ (0,
|
|
5787
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5293
5788
|
"div",
|
|
5294
5789
|
{
|
|
5295
5790
|
style: editorStyles.toolbarActions,
|
|
5296
5791
|
role: "toolbar",
|
|
5297
5792
|
"aria-label": copy.toolbarAriaLabel,
|
|
5298
5793
|
"data-ssml-editor-toolbar-actions": "",
|
|
5299
|
-
children:
|
|
5794
|
+
children: [
|
|
5795
|
+
renderToolbarItems(),
|
|
5796
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
|
|
5797
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5798
|
+
"button",
|
|
5799
|
+
{
|
|
5800
|
+
type: "button",
|
|
5801
|
+
style: editMode === "visual" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
|
|
5802
|
+
"aria-pressed": editMode === "visual",
|
|
5803
|
+
onClick: () => setEditMode("visual"),
|
|
5804
|
+
children: "Visual"
|
|
5805
|
+
}
|
|
5806
|
+
),
|
|
5807
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5808
|
+
"button",
|
|
5809
|
+
{
|
|
5810
|
+
type: "button",
|
|
5811
|
+
style: editMode === "code" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
|
|
5812
|
+
"aria-pressed": editMode === "code",
|
|
5813
|
+
onClick: () => setEditMode("code"),
|
|
5814
|
+
children: "Code"
|
|
5815
|
+
}
|
|
5816
|
+
)
|
|
5817
|
+
]
|
|
5300
5818
|
}
|
|
5301
5819
|
)
|
|
5302
5820
|
}
|
|
5303
5821
|
),
|
|
5304
|
-
/* @__PURE__ */ (0,
|
|
5305
|
-
isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */ (0,
|
|
5306
|
-
/* @__PURE__ */ (0,
|
|
5307
|
-
/* @__PURE__ */ (0,
|
|
5308
|
-
helpInsertions.length > 0 && /* @__PURE__ */ (0,
|
|
5309
|
-
/* @__PURE__ */ (0,
|
|
5310
|
-
/* @__PURE__ */ (0,
|
|
5311
|
-
/* @__PURE__ */ (0,
|
|
5312
|
-
/* @__PURE__ */ (0,
|
|
5822
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: displayClassName, style: { ...editorStyles.display, ...displayStyle }, "data-ssml-editor-display": "", children: [
|
|
5823
|
+
isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { id: helpPanelId, style: editorStyles.helpPanel, "aria-label": copy.helpHeading, children: [
|
|
5824
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: editorStyles.helpHeading, children: copy.helpHeading }),
|
|
5825
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: editorStyles.helpDescription, children: copy.helpDescription }),
|
|
5826
|
+
helpInsertions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { style: editorStyles.helpList, children: helpInsertions.map((insertion) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { style: editorStyles.helpItem, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { className: "ssml-editor-help-settings-accordion", style: editorStyles.helpSettingsAccordion, children: [
|
|
5827
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("summary", { className: "ssml-editor-help-settings-summary", style: editorStyles.helpSettingsSummary, children: [
|
|
5828
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.helpIcon, "aria-hidden": "true", children: insertion.icon }),
|
|
5829
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: editorStyles.helpSettingsSummaryContent, children: [
|
|
5830
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: insertion.labels[language] }),
|
|
5313
5831
|
" ",
|
|
5314
|
-
insertion.tagName && /* @__PURE__ */ (0,
|
|
5315
|
-
/* @__PURE__ */ (0,
|
|
5832
|
+
insertion.tagName && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
5833
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: `<${insertion.tagName}${insertion.selfClosing ? "/>" : ">"}` }),
|
|
5316
5834
|
" \u2014",
|
|
5317
5835
|
" "
|
|
5318
5836
|
] }),
|
|
5319
5837
|
insertion.descriptions[language]
|
|
5320
5838
|
] })
|
|
5321
5839
|
] }),
|
|
5322
|
-
/* @__PURE__ */ (0,
|
|
5323
|
-
/* @__PURE__ */ (0,
|
|
5840
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: editorStyles.helpSettingsDescription, children: [
|
|
5841
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
|
|
5324
5842
|
copy.parameters,
|
|
5325
5843
|
":"
|
|
5326
5844
|
] }),
|
|
5327
5845
|
" ",
|
|
5328
5846
|
insertion.parameterDescription[language]
|
|
5329
5847
|
] }),
|
|
5330
|
-
/* @__PURE__ */ (0,
|
|
5331
|
-
/* @__PURE__ */ (0,
|
|
5332
|
-
option.descriptions && /* @__PURE__ */ (0,
|
|
5848
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { style: editorStyles.helpSettingsList, children: insertion.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { children: [
|
|
5849
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: option.labels[language] }),
|
|
5850
|
+
option.descriptions && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
5333
5851
|
" \u2014 ",
|
|
5334
5852
|
option.descriptions[language]
|
|
5335
5853
|
] })
|
|
5336
5854
|
] }, option.value)) })
|
|
5337
5855
|
] }) }, insertion.id)) })
|
|
5338
5856
|
] }),
|
|
5339
|
-
/* @__PURE__ */ (0,
|
|
5340
|
-
|
|
5341
|
-
|
|
5857
|
+
editMode === "visual" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: editorStyles.visual, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5858
|
+
VisualSsmlEditor,
|
|
5859
|
+
{
|
|
5860
|
+
document: draftDocument,
|
|
5861
|
+
readOnly: isReadOnly,
|
|
5862
|
+
onChange: commit,
|
|
5863
|
+
onPreviewSelection
|
|
5864
|
+
}
|
|
5865
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight }, children: [
|
|
5866
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5867
|
+
import_react5.default,
|
|
5342
5868
|
{
|
|
5343
5869
|
height: editorHeight,
|
|
5344
5870
|
language: "xml",
|
|
@@ -5362,7 +5888,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5362
5888
|
onChange: (value) => handleTextChange(value ?? "")
|
|
5363
5889
|
}
|
|
5364
5890
|
),
|
|
5365
|
-
selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */ (0,
|
|
5891
|
+
selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5366
5892
|
"div",
|
|
5367
5893
|
{
|
|
5368
5894
|
role: "toolbar",
|
|
@@ -5376,12 +5902,12 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5376
5902
|
},
|
|
5377
5903
|
onMouseDown: (event) => event.preventDefault(),
|
|
5378
5904
|
children: [
|
|
5379
|
-
/* @__PURE__ */ (0,
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: editorStyles.selectionCount, "aria-live": "polite", children: [
|
|
5380
5906
|
selectionOverlay.characterCount,
|
|
5381
5907
|
copy.selectionCountSuffix
|
|
5382
5908
|
] }),
|
|
5383
|
-
/* @__PURE__ */ (0,
|
|
5384
|
-
/* @__PURE__ */ (0,
|
|
5909
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.selectionActionsDivider, "aria-hidden": "true" }),
|
|
5910
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
5385
5911
|
"button",
|
|
5386
5912
|
{
|
|
5387
5913
|
type: "button",
|
|
@@ -5390,7 +5916,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5390
5916
|
disabled: !canPreviewSelection,
|
|
5391
5917
|
onClick: previewSelection,
|
|
5392
5918
|
children: [
|
|
5393
|
-
/* @__PURE__ */ (0,
|
|
5919
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.selectionActionIcon, "aria-hidden": "true", children: "\u25B6" }),
|
|
5394
5920
|
copy.previewSelection
|
|
5395
5921
|
]
|
|
5396
5922
|
}
|
|
@@ -5399,7 +5925,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5399
5925
|
}
|
|
5400
5926
|
)
|
|
5401
5927
|
] }),
|
|
5402
|
-
syntaxError && /* @__PURE__ */ (0,
|
|
5928
|
+
syntaxError && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: editorStyles.error, role: "alert", children: [
|
|
5403
5929
|
copy.syntaxError,
|
|
5404
5930
|
": ",
|
|
5405
5931
|
syntaxError.message
|
|
@@ -5416,6 +5942,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
|
|
|
5416
5942
|
SSML_HOVER_COPY,
|
|
5417
5943
|
SSML_INSERTIONS,
|
|
5418
5944
|
SsmlEditor,
|
|
5945
|
+
VisualSsmlEditor,
|
|
5419
5946
|
createSsmlEditorInsertionDefinition,
|
|
5420
5947
|
registerSsmlCodeLens,
|
|
5421
5948
|
updateTagAttribute
|