@ssml-builder-js/ssml-editor-react 2.8.1 → 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 +11 -0
- package/dist/index.d.mts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +414 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +412 -58
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/SsmlEditor.tsx +153 -57
- package/src/components/VisualSsmlEditor.tsx +240 -0
- package/src/constants/ssmlPresets.ts +5 -0
- package/src/index.tsx +3 -0
- package/src/ssmlCompletion.ts +16 -0
- package/src/ssmlHover.ts +57 -0
- package/src/styles/editorStyles.ts +8 -0
- package/test/ui-components.test.tsx +13 -0
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/SsmlEditor.tsx
|
|
9
|
-
import { Fragment as
|
|
9
|
+
import { Fragment as Fragment4, forwardRef, useEffect as useEffect3, useImperativeHandle, useState as useState3 } from "react";
|
|
10
10
|
import Editor from "@monaco-editor/react";
|
|
11
11
|
|
|
12
12
|
// src/buttonVisibility.ts
|
|
@@ -436,6 +436,11 @@ var SSML_ATTRIBUTE_PRESETS = {
|
|
|
436
436
|
"mstts:audioduration": {
|
|
437
437
|
value: AUDIO_DURATION_PRESETS
|
|
438
438
|
},
|
|
439
|
+
"mstts:backgroundaudio": {
|
|
440
|
+
volume: PROSODY_VOLUME_PRESETS,
|
|
441
|
+
fadein: AUDIO_DURATION_PRESETS,
|
|
442
|
+
fadeout: AUDIO_DURATION_PRESETS
|
|
443
|
+
},
|
|
439
444
|
silence: {
|
|
440
445
|
type: SILENCE_TYPE_PRESETS,
|
|
441
446
|
value: SILENCE_VALUE_PRESETS
|
|
@@ -1252,6 +1257,14 @@ var editorStyles = {
|
|
|
1252
1257
|
display: "grid",
|
|
1253
1258
|
gap: "0.5rem"
|
|
1254
1259
|
},
|
|
1260
|
+
visual: {
|
|
1261
|
+
display: "grid",
|
|
1262
|
+
gap: "0.75rem",
|
|
1263
|
+
minHeight: "8rem",
|
|
1264
|
+
padding: "0.75rem",
|
|
1265
|
+
border: "1px solid var(--ssml-editor-control-border)",
|
|
1266
|
+
borderRadius: "0.25rem"
|
|
1267
|
+
},
|
|
1255
1268
|
toolbarIconOnly: {
|
|
1256
1269
|
justifyContent: "center",
|
|
1257
1270
|
minWidth: "2.25rem",
|
|
@@ -3263,6 +3276,24 @@ var SSML_COMPLETION_SNIPPETS = [
|
|
|
3263
3276
|
label: "mstts:audioduration",
|
|
3264
3277
|
insertText: '<mstts:audioduration value="10s" />'
|
|
3265
3278
|
},
|
|
3279
|
+
{
|
|
3280
|
+
label: "mstts:dialog",
|
|
3281
|
+
insertText: `<mstts:dialog>
|
|
3282
|
+
<mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>
|
|
3283
|
+
</mstts:dialog>`
|
|
3284
|
+
},
|
|
3285
|
+
{
|
|
3286
|
+
label: "mstts:turn",
|
|
3287
|
+
insertText: `<mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>`
|
|
3288
|
+
},
|
|
3289
|
+
{
|
|
3290
|
+
label: "mstts:backgroundaudio",
|
|
3291
|
+
insertText: `<mstts:backgroundaudio src="\${1:https://example.com/audio.mp3}" volume="\${2:-3dB}" />`
|
|
3292
|
+
},
|
|
3293
|
+
{
|
|
3294
|
+
label: "mstts:ttsembedding",
|
|
3295
|
+
insertText: `<mstts:ttsembedding>\${1:text}</mstts:ttsembedding>`
|
|
3296
|
+
},
|
|
3266
3297
|
{
|
|
3267
3298
|
label: "sub",
|
|
3268
3299
|
insertText: `<sub alias="\${1:\u8AAD\u307F}">\${2:\u6F22\u5B57}</sub>`
|
|
@@ -3930,6 +3961,63 @@ var SSML_TAG_DEFINITIONS = [
|
|
|
3930
3961
|
example: "10s"
|
|
3931
3962
|
}
|
|
3932
3963
|
]
|
|
3964
|
+
},
|
|
3965
|
+
{
|
|
3966
|
+
name: "mstts:dialog",
|
|
3967
|
+
description: "Groups multiple Azure dialog turns that can use different voices.",
|
|
3968
|
+
parameters: []
|
|
3969
|
+
},
|
|
3970
|
+
{
|
|
3971
|
+
name: "mstts:turn",
|
|
3972
|
+
description: "Adds one dialog turn using the required Azure voice name.",
|
|
3973
|
+
parameters: [
|
|
3974
|
+
{
|
|
3975
|
+
name: "voice",
|
|
3976
|
+
description: "The Azure voice used for this turn, such as `en-US-JennyNeural`.",
|
|
3977
|
+
example: "en-US-JennyNeural"
|
|
3978
|
+
}
|
|
3979
|
+
]
|
|
3980
|
+
},
|
|
3981
|
+
{
|
|
3982
|
+
name: "mstts:backgroundaudio",
|
|
3983
|
+
description: "Plays background audio while speech is synthesized.",
|
|
3984
|
+
parameters: [
|
|
3985
|
+
{
|
|
3986
|
+
name: "src",
|
|
3987
|
+
description: "An absolute HTTP(S) URL for the background audio file.",
|
|
3988
|
+
example: "https://example.com/music.mp3"
|
|
3989
|
+
},
|
|
3990
|
+
{
|
|
3991
|
+
name: "volume",
|
|
3992
|
+
description: "The background audio volume, for example `-3dB` or `medium`.",
|
|
3993
|
+
example: "-3dB"
|
|
3994
|
+
},
|
|
3995
|
+
{
|
|
3996
|
+
name: "fadein",
|
|
3997
|
+
description: "The fade-in duration, for example `1s`.",
|
|
3998
|
+
example: "1s"
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
name: "fadeout",
|
|
4002
|
+
description: "The fade-out duration, for example `500ms`.",
|
|
4003
|
+
example: "500ms"
|
|
4004
|
+
}
|
|
4005
|
+
]
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
name: "mstts:ttsembedding",
|
|
4009
|
+
description: "Embeds custom voice or speaker profile metadata for Azure Speech.",
|
|
4010
|
+
parameters: []
|
|
4011
|
+
},
|
|
4012
|
+
{
|
|
4013
|
+
name: "mstts:embedding",
|
|
4014
|
+
description: "Specifies embedding metadata for custom voice scenarios.",
|
|
4015
|
+
parameters: []
|
|
4016
|
+
},
|
|
4017
|
+
{
|
|
4018
|
+
name: "mstts:voiceconversion",
|
|
4019
|
+
description: "Specifies voice conversion metadata for custom voice scenarios.",
|
|
4020
|
+
parameters: []
|
|
3933
4021
|
}
|
|
3934
4022
|
];
|
|
3935
4023
|
var definitionsByName = /* @__PURE__ */ new Map();
|
|
@@ -4534,8 +4622,183 @@ function useSsmlMonaco({
|
|
|
4534
4622
|
return { editorRef, onMount };
|
|
4535
4623
|
}
|
|
4536
4624
|
|
|
4625
|
+
// src/components/VisualSsmlEditor.tsx
|
|
4626
|
+
import { useMemo, useState as useState2 } from "react";
|
|
4627
|
+
import {
|
|
4628
|
+
buildSsml as buildSsml3,
|
|
4629
|
+
validateAzureSsml
|
|
4630
|
+
} from "@ssml-builder-js/ssml-core";
|
|
4631
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4632
|
+
function isElement(node) {
|
|
4633
|
+
return typeof node !== "string" && node.type !== "text";
|
|
4634
|
+
}
|
|
4635
|
+
function elementLabel(element) {
|
|
4636
|
+
return element.type === "custom" || element.type === "element" ? element.name : element.type;
|
|
4637
|
+
}
|
|
4638
|
+
function collectTextLeaves(nodes, path = [], ancestors = []) {
|
|
4639
|
+
return nodes.flatMap((node, index) => {
|
|
4640
|
+
const currentPath = [...path, index];
|
|
4641
|
+
if (typeof node === "string") return [{ ancestors, path: currentPath, value: node }];
|
|
4642
|
+
if (node.type === "text") return [{ ancestors, path: currentPath, value: node.value }];
|
|
4643
|
+
return collectTextLeaves(node.children ?? [], currentPath, [...ancestors, elementLabel(node)]);
|
|
4644
|
+
});
|
|
4645
|
+
}
|
|
4646
|
+
function updateNodesAtPath(nodes, path, update) {
|
|
4647
|
+
if (path.length === 0) return nodes;
|
|
4648
|
+
const [index, ...rest] = path;
|
|
4649
|
+
return nodes.flatMap((node, nodeIndex) => {
|
|
4650
|
+
if (nodeIndex !== index) return [node];
|
|
4651
|
+
if (rest.length === 0) {
|
|
4652
|
+
const next = update(node);
|
|
4653
|
+
return Array.isArray(next) ? next : [next];
|
|
4654
|
+
}
|
|
4655
|
+
if (!isElement(node)) return [node];
|
|
4656
|
+
return [{ ...node, children: updateNodesAtPath(node.children ?? [], rest, update) }];
|
|
4657
|
+
});
|
|
4658
|
+
}
|
|
4659
|
+
function updateTextAtPath(document2, path, value) {
|
|
4660
|
+
return { ...document2, children: updateNodesAtPath(document2.children ?? [], path, () => value) };
|
|
4661
|
+
}
|
|
4662
|
+
function wrapTextAtPath(document2, path, start, end, tag, attributes) {
|
|
4663
|
+
return {
|
|
4664
|
+
...document2,
|
|
4665
|
+
children: updateNodesAtPath(document2.children ?? [], path, (node) => {
|
|
4666
|
+
const value = typeof node === "string" ? node : node.type === "text" ? node.value : "";
|
|
4667
|
+
if (!value || start === end) return node;
|
|
4668
|
+
if (tag === "break") {
|
|
4669
|
+
return [
|
|
4670
|
+
value.slice(0, start),
|
|
4671
|
+
{ type: tag, attributes, children: [] },
|
|
4672
|
+
value.slice(start)
|
|
4673
|
+
].filter((part) => typeof part === "string" ? part.length > 0 : true);
|
|
4674
|
+
}
|
|
4675
|
+
const selected = value.slice(start, end);
|
|
4676
|
+
const wrapped = { type: tag, attributes, children: [selected] };
|
|
4677
|
+
return [value.slice(0, start), wrapped, value.slice(end)].filter(
|
|
4678
|
+
(part) => typeof part === "string" ? part.length > 0 : true
|
|
4679
|
+
);
|
|
4680
|
+
})
|
|
4681
|
+
};
|
|
4682
|
+
}
|
|
4683
|
+
function TreeNode({
|
|
4684
|
+
node,
|
|
4685
|
+
path,
|
|
4686
|
+
selectedPath,
|
|
4687
|
+
onSelect
|
|
4688
|
+
}) {
|
|
4689
|
+
if (!isElement(node)) return null;
|
|
4690
|
+
const name = elementLabel(node);
|
|
4691
|
+
const isSelected = selectedPath?.join(".") === path.join(".");
|
|
4692
|
+
return /* @__PURE__ */ jsxs2("li", { children: [
|
|
4693
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path), children: `<${name}>` }),
|
|
4694
|
+
(node.children ?? []).length > 0 && /* @__PURE__ */ jsx6("ul", { children: node.children?.map((child, index) => /* @__PURE__ */ jsx6(
|
|
4695
|
+
TreeNode,
|
|
4696
|
+
{
|
|
4697
|
+
node: child,
|
|
4698
|
+
path: [...path, index],
|
|
4699
|
+
selectedPath,
|
|
4700
|
+
onSelect
|
|
4701
|
+
},
|
|
4702
|
+
`${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`
|
|
4703
|
+
)) })
|
|
4704
|
+
] });
|
|
4705
|
+
}
|
|
4706
|
+
function VisualSsmlEditor({
|
|
4707
|
+
document: document2,
|
|
4708
|
+
readOnly = false,
|
|
4709
|
+
onChange,
|
|
4710
|
+
onPreviewSelection
|
|
4711
|
+
}) {
|
|
4712
|
+
const [selectedPath, setSelectedPath] = useState2(null);
|
|
4713
|
+
const [selection, setSelection] = useState2({ start: 0, end: 0 });
|
|
4714
|
+
const textLeaves = useMemo(() => collectTextLeaves(document2.children ?? []), [document2]);
|
|
4715
|
+
const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
|
|
4716
|
+
const diagnostics = useMemo(() => validateAzureSsml(buildSsml3(document2)), [document2]);
|
|
4717
|
+
const commit = (nextDocument) => onChange?.(nextDocument);
|
|
4718
|
+
const applyWrapper = (tag, attributes) => {
|
|
4719
|
+
if (readOnly || !selectedLeaf) return;
|
|
4720
|
+
const start = selection.start === selection.end ? 0 : selection.start;
|
|
4721
|
+
const end = selection.start === selection.end ? selectedLeaf.value.length : selection.end;
|
|
4722
|
+
commit(wrapTextAtPath(document2, selectedLeaf.path, start, end, tag, attributes));
|
|
4723
|
+
};
|
|
4724
|
+
return /* @__PURE__ */ jsxs2("div", { className: "ssml-editor-visual", "data-ssml-editor-visual": "", children: [
|
|
4725
|
+
/* @__PURE__ */ jsxs2("fieldset", { className: "ssml-editor-visual-breadcrumb", children: [
|
|
4726
|
+
/* @__PURE__ */ jsx6("legend", { children: "SSML structure breadcrumb" }),
|
|
4727
|
+
/* @__PURE__ */ jsx6("span", { children: "<speak>" }),
|
|
4728
|
+
selectedLeaf?.ancestors.map((ancestor, index) => /* @__PURE__ */ jsxs2("span", { children: [
|
|
4729
|
+
" / <",
|
|
4730
|
+
ancestor,
|
|
4731
|
+
">"
|
|
4732
|
+
] }, selectedLeaf?.ancestors.slice(0, index + 1).join("/"))),
|
|
4733
|
+
selectedPath && /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setSelectedPath(null), children: "Clear parent" })
|
|
4734
|
+
] }),
|
|
4735
|
+
diagnostics.length > 0 && /* @__PURE__ */ jsx6("div", { role: "alert", "aria-invalid": "true", className: "ssml-editor-visual-errors", children: diagnostics.map((diagnostic) => /* @__PURE__ */ jsx6("div", { children: diagnostic.message }, `${diagnostic.code}-${diagnostic.message}`)) }),
|
|
4736
|
+
/* @__PURE__ */ jsxs2("div", { className: "ssml-editor-visual-layout", children: [
|
|
4737
|
+
/* @__PURE__ */ jsxs2("nav", { "aria-label": "SSML structure tree", className: "ssml-editor-visual-tree", children: [
|
|
4738
|
+
/* @__PURE__ */ jsx6("strong", { children: "Structure" }),
|
|
4739
|
+
/* @__PURE__ */ jsx6("ul", { children: document2.children?.map((node, index) => /* @__PURE__ */ jsx6(
|
|
4740
|
+
TreeNode,
|
|
4741
|
+
{
|
|
4742
|
+
node,
|
|
4743
|
+
path: [index],
|
|
4744
|
+
selectedPath,
|
|
4745
|
+
onSelect: setSelectedPath
|
|
4746
|
+
},
|
|
4747
|
+
isElement(node) ? elementLabel(node) : JSON.stringify(node)
|
|
4748
|
+
)) })
|
|
4749
|
+
] }),
|
|
4750
|
+
/* @__PURE__ */ jsx6("div", { className: "ssml-editor-visual-form", children: selectedLeaf ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
4751
|
+
/* @__PURE__ */ jsxs2("label", { children: [
|
|
4752
|
+
"Text",
|
|
4753
|
+
/* @__PURE__ */ jsx6(
|
|
4754
|
+
"textarea",
|
|
4755
|
+
{
|
|
4756
|
+
value: selectedLeaf.value,
|
|
4757
|
+
readOnly,
|
|
4758
|
+
onSelect: (event) => setSelection({ start: event.currentTarget.selectionStart, end: event.currentTarget.selectionEnd }),
|
|
4759
|
+
onChange: (event) => commit(updateTextAtPath(document2, selectedLeaf.path, event.target.value))
|
|
4760
|
+
}
|
|
4761
|
+
)
|
|
4762
|
+
] }),
|
|
4763
|
+
/* @__PURE__ */ jsxs2("fieldset", { className: "ssml-editor-visual-actions", children: [
|
|
4764
|
+
/* @__PURE__ */ jsx6("legend", { children: "Apply SSML formatting" }),
|
|
4765
|
+
/* @__PURE__ */ jsx6("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { rate: "slow" }), children: "Rate" }),
|
|
4766
|
+
/* @__PURE__ */ jsx6("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { pitch: "high" }), children: "Pitch" }),
|
|
4767
|
+
/* @__PURE__ */ jsx6(
|
|
4768
|
+
"button",
|
|
4769
|
+
{
|
|
4770
|
+
type: "button",
|
|
4771
|
+
disabled: readOnly,
|
|
4772
|
+
onClick: () => applyWrapper("mstts:express-as", { style: "cheerful" }),
|
|
4773
|
+
children: "Emotion"
|
|
4774
|
+
}
|
|
4775
|
+
),
|
|
4776
|
+
/* @__PURE__ */ jsx6("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("break", { time: "500ms" }), children: "Pause" }),
|
|
4777
|
+
/* @__PURE__ */ jsx6(
|
|
4778
|
+
"button",
|
|
4779
|
+
{
|
|
4780
|
+
type: "button",
|
|
4781
|
+
disabled: readOnly,
|
|
4782
|
+
onClick: () => applyWrapper("phoneme", { alphabet: "ipa", ph: selectedLeaf.value }),
|
|
4783
|
+
children: "Pronunciation"
|
|
4784
|
+
}
|
|
4785
|
+
),
|
|
4786
|
+
onPreviewSelection && /* @__PURE__ */ jsx6(
|
|
4787
|
+
"button",
|
|
4788
|
+
{
|
|
4789
|
+
type: "button",
|
|
4790
|
+
onClick: () => onPreviewSelection(buildSsml3({ ...document2, children: [selectedLeaf.value] })),
|
|
4791
|
+
children: "Preview selection"
|
|
4792
|
+
}
|
|
4793
|
+
)
|
|
4794
|
+
] })
|
|
4795
|
+
] }) : /* @__PURE__ */ jsx6("p", { children: "Select an element or text node to edit it." }) })
|
|
4796
|
+
] })
|
|
4797
|
+
] });
|
|
4798
|
+
}
|
|
4799
|
+
|
|
4537
4800
|
// src/SsmlEditor.tsx
|
|
4538
|
-
import { Fragment as
|
|
4801
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4539
4802
|
var UNGROUPED_TOOLBAR_GROUP = "__ssml-editor-ungrouped__";
|
|
4540
4803
|
var TIMING_POPOVER_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence", "mstts:audioduration"]);
|
|
4541
4804
|
var PROSODY_POPOVER_TAGS = /* @__PURE__ */ new Set(["prosody", "mstts:express-as", "voice", "emphasis"]);
|
|
@@ -5001,6 +5264,60 @@ var STYLE_CSS = `
|
|
|
5001
5264
|
> .ssml-editor-help-settings-summary::before {
|
|
5002
5265
|
content: "\u25BE";
|
|
5003
5266
|
}
|
|
5267
|
+
[data-ssml-editor] .ssml-editor-visual-layout {
|
|
5268
|
+
display: grid;
|
|
5269
|
+
grid-template-columns: minmax(12rem, 0.35fr) minmax(16rem, 1fr);
|
|
5270
|
+
gap: 1rem;
|
|
5271
|
+
}
|
|
5272
|
+
[data-ssml-editor] .ssml-editor-visual-tree,
|
|
5273
|
+
[data-ssml-editor] .ssml-editor-visual-form {
|
|
5274
|
+
display: grid;
|
|
5275
|
+
gap: 0.5rem;
|
|
5276
|
+
align-content: start;
|
|
5277
|
+
}
|
|
5278
|
+
[data-ssml-editor] .ssml-editor-visual-tree ul {
|
|
5279
|
+
margin: 0;
|
|
5280
|
+
padding-left: 1.25rem;
|
|
5281
|
+
}
|
|
5282
|
+
[data-ssml-editor] .ssml-editor-visual-tree button,
|
|
5283
|
+
[data-ssml-editor] .ssml-editor-visual-breadcrumb button,
|
|
5284
|
+
[data-ssml-editor] .ssml-editor-visual-actions button {
|
|
5285
|
+
padding: 0.35rem 0.5rem;
|
|
5286
|
+
border: 1px solid var(--ssml-editor-control-border);
|
|
5287
|
+
border-radius: 0.25rem;
|
|
5288
|
+
color: var(--ssml-editor-color);
|
|
5289
|
+
background: var(--ssml-editor-control-bg);
|
|
5290
|
+
cursor: pointer;
|
|
5291
|
+
}
|
|
5292
|
+
[data-ssml-editor] .ssml-editor-visual-tree button[aria-current] {
|
|
5293
|
+
border-color: var(--ssml-editor-active-border);
|
|
5294
|
+
background: var(--ssml-editor-active-bg);
|
|
5295
|
+
}
|
|
5296
|
+
[data-ssml-editor] .ssml-editor-visual-breadcrumb,
|
|
5297
|
+
[data-ssml-editor] .ssml-editor-visual-actions {
|
|
5298
|
+
display: flex;
|
|
5299
|
+
flex-wrap: wrap;
|
|
5300
|
+
gap: 0.4rem;
|
|
5301
|
+
align-items: center;
|
|
5302
|
+
}
|
|
5303
|
+
[data-ssml-editor] .ssml-editor-visual-form textarea {
|
|
5304
|
+
box-sizing: border-box;
|
|
5305
|
+
width: 100%;
|
|
5306
|
+
min-height: 6rem;
|
|
5307
|
+
padding: 0.5rem;
|
|
5308
|
+
color: var(--ssml-editor-color);
|
|
5309
|
+
background: var(--ssml-editor-control-bg);
|
|
5310
|
+
border: 1px solid var(--ssml-editor-control-border);
|
|
5311
|
+
border-radius: 0.25rem;
|
|
5312
|
+
font: inherit;
|
|
5313
|
+
}
|
|
5314
|
+
[data-ssml-editor] .ssml-editor-visual-errors {
|
|
5315
|
+
padding: 0.5rem;
|
|
5316
|
+
color: var(--ssml-editor-error);
|
|
5317
|
+
background: var(--ssml-editor-error-bg);
|
|
5318
|
+
border: 1px solid var(--ssml-editor-error);
|
|
5319
|
+
border-radius: 0.25rem;
|
|
5320
|
+
}
|
|
5004
5321
|
`.trim();
|
|
5005
5322
|
function injectEditorTheme() {
|
|
5006
5323
|
if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
|
|
@@ -5017,10 +5334,10 @@ function ToolbarDecorationsSwitch({
|
|
|
5017
5334
|
decorationsVisible,
|
|
5018
5335
|
onVisibilityChange
|
|
5019
5336
|
}) {
|
|
5020
|
-
return /* @__PURE__ */
|
|
5021
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5022
|
-
showToolbarText && /* @__PURE__ */
|
|
5023
|
-
/* @__PURE__ */
|
|
5337
|
+
return /* @__PURE__ */ jsxs3("div", { style: editorStyles.toolbarSwitch, children: [
|
|
5338
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2606" }),
|
|
5339
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.decorations }),
|
|
5340
|
+
/* @__PURE__ */ jsx7(
|
|
5024
5341
|
"button",
|
|
5025
5342
|
{
|
|
5026
5343
|
type: "button",
|
|
@@ -5031,7 +5348,7 @@ function ToolbarDecorationsSwitch({
|
|
|
5031
5348
|
"aria-label": copy.decorations,
|
|
5032
5349
|
title: decorationsVisible ? copy.decorationsHideTitle : copy.decorationsShowTitle,
|
|
5033
5350
|
onClick: () => onVisibilityChange(!decorationsVisible),
|
|
5034
|
-
children: /* @__PURE__ */
|
|
5351
|
+
children: /* @__PURE__ */ jsx7("span", { className: "ssml-editor-switch-thumb", style: editorStyles.toolbarSwitchThumb, "aria-hidden": "true" })
|
|
5035
5352
|
}
|
|
5036
5353
|
)
|
|
5037
5354
|
] });
|
|
@@ -5074,8 +5391,11 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5074
5391
|
toolbarStyle,
|
|
5075
5392
|
displayClassName,
|
|
5076
5393
|
displayStyle,
|
|
5077
|
-
loadingFallback
|
|
5394
|
+
loadingFallback,
|
|
5395
|
+
editMode: editModeProp = "code"
|
|
5078
5396
|
}, ref) {
|
|
5397
|
+
const [editMode, setEditMode] = useState3(editModeProp);
|
|
5398
|
+
useEffect3(() => setEditMode(editModeProp), [editModeProp]);
|
|
5079
5399
|
const resolvedEditorOptions = {
|
|
5080
5400
|
...settings,
|
|
5081
5401
|
...editorOptions,
|
|
@@ -5153,6 +5473,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5153
5473
|
);
|
|
5154
5474
|
const {
|
|
5155
5475
|
editorRef,
|
|
5476
|
+
draftDocument,
|
|
5156
5477
|
text,
|
|
5157
5478
|
selectionOverlay,
|
|
5158
5479
|
activeTags,
|
|
@@ -5164,6 +5485,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5164
5485
|
syntaxError,
|
|
5165
5486
|
setSyntaxError,
|
|
5166
5487
|
helpPanelId,
|
|
5488
|
+
commit,
|
|
5167
5489
|
handleTextChange,
|
|
5168
5490
|
handleInsert,
|
|
5169
5491
|
handleInsertBreak,
|
|
@@ -5241,15 +5563,15 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5241
5563
|
onApply: isTimingPopover ? handleInsertBreak : isProsodyPopover ? handleInsertProsody : isTextPopover ? handleInsertText : handleInsert
|
|
5242
5564
|
};
|
|
5243
5565
|
if (isTimingPopover) {
|
|
5244
|
-
return /* @__PURE__ */
|
|
5566
|
+
return /* @__PURE__ */ jsx7(TimingPopovers, { ...props, insertions: [insertion] });
|
|
5245
5567
|
}
|
|
5246
5568
|
if (isProsodyPopover) {
|
|
5247
|
-
return /* @__PURE__ */
|
|
5569
|
+
return /* @__PURE__ */ jsx7(ProsodyPopovers, { ...props, insertions: [insertion], voiceName: popoverVoiceName });
|
|
5248
5570
|
}
|
|
5249
5571
|
if (isTextPopover) {
|
|
5250
|
-
return /* @__PURE__ */
|
|
5572
|
+
return /* @__PURE__ */ jsx7(TextPopovers, { ...props, insertions: [insertion] });
|
|
5251
5573
|
}
|
|
5252
|
-
return /* @__PURE__ */
|
|
5574
|
+
return /* @__PURE__ */ jsx7(
|
|
5253
5575
|
InsertionPopover,
|
|
5254
5576
|
{
|
|
5255
5577
|
...props,
|
|
@@ -5262,7 +5584,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5262
5584
|
const toolbarItemRenderers = /* @__PURE__ */ new Map([
|
|
5263
5585
|
[
|
|
5264
5586
|
"undo",
|
|
5265
|
-
() => /* @__PURE__ */
|
|
5587
|
+
() => /* @__PURE__ */ jsxs3(
|
|
5266
5588
|
"button",
|
|
5267
5589
|
{
|
|
5268
5590
|
type: "button",
|
|
@@ -5276,8 +5598,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5276
5598
|
}
|
|
5277
5599
|
},
|
|
5278
5600
|
children: [
|
|
5279
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5280
|
-
showToolbarText && /* @__PURE__ */
|
|
5601
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21A9" }),
|
|
5602
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.undo })
|
|
5281
5603
|
]
|
|
5282
5604
|
},
|
|
5283
5605
|
"undo"
|
|
@@ -5285,7 +5607,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5285
5607
|
],
|
|
5286
5608
|
[
|
|
5287
5609
|
"redo",
|
|
5288
|
-
() => /* @__PURE__ */
|
|
5610
|
+
() => /* @__PURE__ */ jsxs3(
|
|
5289
5611
|
"button",
|
|
5290
5612
|
{
|
|
5291
5613
|
type: "button",
|
|
@@ -5299,8 +5621,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5299
5621
|
}
|
|
5300
5622
|
},
|
|
5301
5623
|
children: [
|
|
5302
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5303
|
-
showToolbarText && /* @__PURE__ */
|
|
5624
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21AA" }),
|
|
5625
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.redo })
|
|
5304
5626
|
]
|
|
5305
5627
|
},
|
|
5306
5628
|
"redo"
|
|
@@ -5308,7 +5630,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5308
5630
|
],
|
|
5309
5631
|
[
|
|
5310
5632
|
"clearAll",
|
|
5311
|
-
() => /* @__PURE__ */
|
|
5633
|
+
() => /* @__PURE__ */ jsxs3(
|
|
5312
5634
|
"button",
|
|
5313
5635
|
{
|
|
5314
5636
|
type: "button",
|
|
@@ -5322,8 +5644,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5322
5644
|
}
|
|
5323
5645
|
},
|
|
5324
5646
|
children: [
|
|
5325
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5326
|
-
showToolbarText && /* @__PURE__ */
|
|
5647
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\xD7" }),
|
|
5648
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.clearAll })
|
|
5327
5649
|
]
|
|
5328
5650
|
},
|
|
5329
5651
|
"clearAll"
|
|
@@ -5331,7 +5653,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5331
5653
|
],
|
|
5332
5654
|
[
|
|
5333
5655
|
"format",
|
|
5334
|
-
() => /* @__PURE__ */
|
|
5656
|
+
() => /* @__PURE__ */ jsxs3(
|
|
5335
5657
|
"button",
|
|
5336
5658
|
{
|
|
5337
5659
|
type: "button",
|
|
@@ -5345,8 +5667,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5345
5667
|
}
|
|
5346
5668
|
},
|
|
5347
5669
|
children: [
|
|
5348
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5349
|
-
showToolbarText && /* @__PURE__ */
|
|
5670
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2261" }),
|
|
5671
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.format })
|
|
5350
5672
|
]
|
|
5351
5673
|
},
|
|
5352
5674
|
"format"
|
|
@@ -5354,7 +5676,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5354
5676
|
],
|
|
5355
5677
|
[
|
|
5356
5678
|
"decorations",
|
|
5357
|
-
() => /* @__PURE__ */
|
|
5679
|
+
() => /* @__PURE__ */ jsx7(
|
|
5358
5680
|
ToolbarDecorationsSwitch,
|
|
5359
5681
|
{
|
|
5360
5682
|
copy,
|
|
@@ -5368,7 +5690,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5368
5690
|
],
|
|
5369
5691
|
[
|
|
5370
5692
|
"help",
|
|
5371
|
-
() => /* @__PURE__ */
|
|
5693
|
+
() => /* @__PURE__ */ jsxs3(
|
|
5372
5694
|
"button",
|
|
5373
5695
|
{
|
|
5374
5696
|
type: "button",
|
|
@@ -5379,8 +5701,8 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5379
5701
|
"aria-controls": helpPanelId,
|
|
5380
5702
|
onClick: () => setIsHelpOpen((open) => !open),
|
|
5381
5703
|
children: [
|
|
5382
|
-
showToolbarIcons && /* @__PURE__ */
|
|
5383
|
-
showToolbarText && /* @__PURE__ */
|
|
5704
|
+
showToolbarIcons && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "?" }),
|
|
5705
|
+
showToolbarText && /* @__PURE__ */ jsx7("span", { children: copy.help })
|
|
5384
5706
|
]
|
|
5385
5707
|
},
|
|
5386
5708
|
"help"
|
|
@@ -5404,15 +5726,15 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5404
5726
|
previousRenderedGroupId = groupId;
|
|
5405
5727
|
hasRenderedToolbarItem = true;
|
|
5406
5728
|
renderedItems.push(
|
|
5407
|
-
/* @__PURE__ */
|
|
5408
|
-
showSeparator && /* @__PURE__ */
|
|
5729
|
+
/* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
5730
|
+
showSeparator && /* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
|
|
5409
5731
|
render()
|
|
5410
5732
|
] }, id)
|
|
5411
5733
|
);
|
|
5412
5734
|
}
|
|
5413
5735
|
return renderedItems;
|
|
5414
5736
|
};
|
|
5415
|
-
return /* @__PURE__ */
|
|
5737
|
+
return /* @__PURE__ */ jsxs3(
|
|
5416
5738
|
"section",
|
|
5417
5739
|
{
|
|
5418
5740
|
className,
|
|
@@ -5421,61 +5743,92 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5421
5743
|
"data-ssml-editor": "",
|
|
5422
5744
|
"data-theme": isDarkTheme ? "dark" : "light",
|
|
5423
5745
|
children: [
|
|
5424
|
-
showToolbar && /* @__PURE__ */
|
|
5746
|
+
showToolbar && /* @__PURE__ */ jsx7(
|
|
5425
5747
|
"div",
|
|
5426
5748
|
{
|
|
5427
5749
|
className: toolbarClassName,
|
|
5428
5750
|
style: { ...editorStyles.toolbarContainer, ...toolbarStyle },
|
|
5429
5751
|
"data-ssml-editor-toolbar": "",
|
|
5430
|
-
children: /* @__PURE__ */
|
|
5752
|
+
children: /* @__PURE__ */ jsxs3(
|
|
5431
5753
|
"div",
|
|
5432
5754
|
{
|
|
5433
5755
|
style: editorStyles.toolbarActions,
|
|
5434
5756
|
role: "toolbar",
|
|
5435
5757
|
"aria-label": copy.toolbarAriaLabel,
|
|
5436
5758
|
"data-ssml-editor-toolbar-actions": "",
|
|
5437
|
-
children:
|
|
5759
|
+
children: [
|
|
5760
|
+
renderToolbarItems(),
|
|
5761
|
+
/* @__PURE__ */ jsx7("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
|
|
5762
|
+
/* @__PURE__ */ jsx7(
|
|
5763
|
+
"button",
|
|
5764
|
+
{
|
|
5765
|
+
type: "button",
|
|
5766
|
+
style: editMode === "visual" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
|
|
5767
|
+
"aria-pressed": editMode === "visual",
|
|
5768
|
+
onClick: () => setEditMode("visual"),
|
|
5769
|
+
children: "Visual"
|
|
5770
|
+
}
|
|
5771
|
+
),
|
|
5772
|
+
/* @__PURE__ */ jsx7(
|
|
5773
|
+
"button",
|
|
5774
|
+
{
|
|
5775
|
+
type: "button",
|
|
5776
|
+
style: editMode === "code" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
|
|
5777
|
+
"aria-pressed": editMode === "code",
|
|
5778
|
+
onClick: () => setEditMode("code"),
|
|
5779
|
+
children: "Code"
|
|
5780
|
+
}
|
|
5781
|
+
)
|
|
5782
|
+
]
|
|
5438
5783
|
}
|
|
5439
5784
|
)
|
|
5440
5785
|
}
|
|
5441
5786
|
),
|
|
5442
|
-
/* @__PURE__ */
|
|
5443
|
-
isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */
|
|
5444
|
-
/* @__PURE__ */
|
|
5445
|
-
/* @__PURE__ */
|
|
5446
|
-
helpInsertions.length > 0 && /* @__PURE__ */
|
|
5447
|
-
/* @__PURE__ */
|
|
5448
|
-
/* @__PURE__ */
|
|
5449
|
-
/* @__PURE__ */
|
|
5450
|
-
/* @__PURE__ */
|
|
5787
|
+
/* @__PURE__ */ jsxs3("div", { className: displayClassName, style: { ...editorStyles.display, ...displayStyle }, "data-ssml-editor-display": "", children: [
|
|
5788
|
+
isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */ jsxs3("section", { id: helpPanelId, style: editorStyles.helpPanel, "aria-label": copy.helpHeading, children: [
|
|
5789
|
+
/* @__PURE__ */ jsx7("h3", { style: editorStyles.helpHeading, children: copy.helpHeading }),
|
|
5790
|
+
/* @__PURE__ */ jsx7("p", { style: editorStyles.helpDescription, children: copy.helpDescription }),
|
|
5791
|
+
helpInsertions.length > 0 && /* @__PURE__ */ jsx7("ul", { style: editorStyles.helpList, children: helpInsertions.map((insertion) => /* @__PURE__ */ jsx7("li", { style: editorStyles.helpItem, children: /* @__PURE__ */ jsxs3("details", { className: "ssml-editor-help-settings-accordion", style: editorStyles.helpSettingsAccordion, children: [
|
|
5792
|
+
/* @__PURE__ */ jsxs3("summary", { className: "ssml-editor-help-settings-summary", style: editorStyles.helpSettingsSummary, children: [
|
|
5793
|
+
/* @__PURE__ */ jsx7("span", { style: editorStyles.helpIcon, "aria-hidden": "true", children: insertion.icon }),
|
|
5794
|
+
/* @__PURE__ */ jsxs3("span", { style: editorStyles.helpSettingsSummaryContent, children: [
|
|
5795
|
+
/* @__PURE__ */ jsx7("strong", { children: insertion.labels[language] }),
|
|
5451
5796
|
" ",
|
|
5452
|
-
insertion.tagName && /* @__PURE__ */
|
|
5453
|
-
/* @__PURE__ */
|
|
5797
|
+
insertion.tagName && /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
5798
|
+
/* @__PURE__ */ jsx7("code", { children: `<${insertion.tagName}${insertion.selfClosing ? "/>" : ">"}` }),
|
|
5454
5799
|
" \u2014",
|
|
5455
5800
|
" "
|
|
5456
5801
|
] }),
|
|
5457
5802
|
insertion.descriptions[language]
|
|
5458
5803
|
] })
|
|
5459
5804
|
] }),
|
|
5460
|
-
/* @__PURE__ */
|
|
5461
|
-
/* @__PURE__ */
|
|
5805
|
+
/* @__PURE__ */ jsxs3("p", { style: editorStyles.helpSettingsDescription, children: [
|
|
5806
|
+
/* @__PURE__ */ jsxs3("strong", { children: [
|
|
5462
5807
|
copy.parameters,
|
|
5463
5808
|
":"
|
|
5464
5809
|
] }),
|
|
5465
5810
|
" ",
|
|
5466
5811
|
insertion.parameterDescription[language]
|
|
5467
5812
|
] }),
|
|
5468
|
-
/* @__PURE__ */
|
|
5469
|
-
/* @__PURE__ */
|
|
5470
|
-
option.descriptions && /* @__PURE__ */
|
|
5813
|
+
/* @__PURE__ */ jsx7("ul", { style: editorStyles.helpSettingsList, children: insertion.options.map((option) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
5814
|
+
/* @__PURE__ */ jsx7("strong", { children: option.labels[language] }),
|
|
5815
|
+
option.descriptions && /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
5471
5816
|
" \u2014 ",
|
|
5472
5817
|
option.descriptions[language]
|
|
5473
5818
|
] })
|
|
5474
5819
|
] }, option.value)) })
|
|
5475
5820
|
] }) }, insertion.id)) })
|
|
5476
5821
|
] }),
|
|
5477
|
-
/* @__PURE__ */
|
|
5478
|
-
|
|
5822
|
+
editMode === "visual" ? /* @__PURE__ */ jsx7("div", { style: editorStyles.visual, children: /* @__PURE__ */ jsx7(
|
|
5823
|
+
VisualSsmlEditor,
|
|
5824
|
+
{
|
|
5825
|
+
document: draftDocument,
|
|
5826
|
+
readOnly: isReadOnly,
|
|
5827
|
+
onChange: commit,
|
|
5828
|
+
onPreviewSelection
|
|
5829
|
+
}
|
|
5830
|
+
) }) : /* @__PURE__ */ jsxs3("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight }, children: [
|
|
5831
|
+
/* @__PURE__ */ jsx7(
|
|
5479
5832
|
Editor,
|
|
5480
5833
|
{
|
|
5481
5834
|
height: editorHeight,
|
|
@@ -5500,7 +5853,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5500
5853
|
onChange: (value) => handleTextChange(value ?? "")
|
|
5501
5854
|
}
|
|
5502
5855
|
),
|
|
5503
|
-
selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */
|
|
5856
|
+
selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */ jsxs3(
|
|
5504
5857
|
"div",
|
|
5505
5858
|
{
|
|
5506
5859
|
role: "toolbar",
|
|
@@ -5514,12 +5867,12 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5514
5867
|
},
|
|
5515
5868
|
onMouseDown: (event) => event.preventDefault(),
|
|
5516
5869
|
children: [
|
|
5517
|
-
/* @__PURE__ */
|
|
5870
|
+
/* @__PURE__ */ jsxs3("span", { style: editorStyles.selectionCount, "aria-live": "polite", children: [
|
|
5518
5871
|
selectionOverlay.characterCount,
|
|
5519
5872
|
copy.selectionCountSuffix
|
|
5520
5873
|
] }),
|
|
5521
|
-
/* @__PURE__ */
|
|
5522
|
-
/* @__PURE__ */
|
|
5874
|
+
/* @__PURE__ */ jsx7("span", { style: editorStyles.selectionActionsDivider, "aria-hidden": "true" }),
|
|
5875
|
+
/* @__PURE__ */ jsxs3(
|
|
5523
5876
|
"button",
|
|
5524
5877
|
{
|
|
5525
5878
|
type: "button",
|
|
@@ -5528,7 +5881,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5528
5881
|
disabled: !canPreviewSelection,
|
|
5529
5882
|
onClick: previewSelection,
|
|
5530
5883
|
children: [
|
|
5531
|
-
/* @__PURE__ */
|
|
5884
|
+
/* @__PURE__ */ jsx7("span", { style: editorStyles.selectionActionIcon, "aria-hidden": "true", children: "\u25B6" }),
|
|
5532
5885
|
copy.previewSelection
|
|
5533
5886
|
]
|
|
5534
5887
|
}
|
|
@@ -5537,7 +5890,7 @@ var SsmlEditor = forwardRef(function SsmlEditor2({
|
|
|
5537
5890
|
}
|
|
5538
5891
|
)
|
|
5539
5892
|
] }),
|
|
5540
|
-
syntaxError && /* @__PURE__ */
|
|
5893
|
+
syntaxError && /* @__PURE__ */ jsxs3("p", { style: editorStyles.error, role: "alert", children: [
|
|
5541
5894
|
copy.syntaxError,
|
|
5542
5895
|
": ",
|
|
5543
5896
|
syntaxError.message
|
|
@@ -5553,6 +5906,7 @@ export {
|
|
|
5553
5906
|
SSML_HOVER_COPY,
|
|
5554
5907
|
SSML_INSERTIONS,
|
|
5555
5908
|
SsmlEditor,
|
|
5909
|
+
VisualSsmlEditor,
|
|
5556
5910
|
createSsmlEditorInsertionDefinition,
|
|
5557
5911
|
registerSsmlCodeLens,
|
|
5558
5912
|
updateTagAttribute
|