@itwin/core-markup 4.0.0-dev.8 → 4.0.0-dev.80
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 +41 -1
- package/lib/cjs/Markup.d.ts +323 -310
- package/lib/cjs/Markup.d.ts.map +1 -1
- package/lib/cjs/Markup.js +451 -420
- package/lib/cjs/Markup.js.map +1 -1
- package/lib/cjs/MarkupTool.d.ts +38 -38
- package/lib/cjs/MarkupTool.js +88 -88
- package/lib/cjs/MarkupTool.js.map +1 -1
- package/lib/cjs/RedlineTool.d.ts +145 -145
- package/lib/cjs/RedlineTool.d.ts.map +1 -1
- package/lib/cjs/RedlineTool.js +498 -512
- package/lib/cjs/RedlineTool.js.map +1 -1
- package/lib/cjs/SelectTool.d.ts +126 -126
- package/lib/cjs/SelectTool.js +741 -741
- package/lib/cjs/SelectTool.js.map +1 -1
- package/lib/cjs/SvgJsExt.d.ts +85 -85
- package/lib/cjs/SvgJsExt.js +185 -185
- package/lib/cjs/TextEdit.d.ts +43 -43
- package/lib/cjs/TextEdit.js +196 -196
- package/lib/cjs/TextEdit.js.map +1 -1
- package/lib/cjs/Undo.d.ts +46 -46
- package/lib/cjs/Undo.js +168 -168
- package/lib/cjs/core-markup.d.ts +18 -18
- package/lib/cjs/core-markup.js +38 -34
- package/lib/cjs/core-markup.js.map +1 -1
- package/lib/esm/Markup.d.ts +323 -310
- package/lib/esm/Markup.d.ts.map +1 -1
- package/lib/esm/Markup.js +447 -415
- package/lib/esm/Markup.js.map +1 -1
- package/lib/esm/MarkupTool.d.ts +38 -38
- package/lib/esm/MarkupTool.js +85 -84
- package/lib/esm/MarkupTool.js.map +1 -1
- package/lib/esm/RedlineTool.d.ts +145 -145
- package/lib/esm/RedlineTool.d.ts.map +1 -1
- package/lib/esm/RedlineTool.js +494 -498
- package/lib/esm/RedlineTool.js.map +1 -1
- package/lib/esm/SelectTool.d.ts +126 -126
- package/lib/esm/SelectTool.js +735 -734
- package/lib/esm/SelectTool.js.map +1 -1
- package/lib/esm/SvgJsExt.d.ts +85 -85
- package/lib/esm/SvgJsExt.js +180 -180
- package/lib/esm/TextEdit.d.ts +43 -43
- package/lib/esm/TextEdit.js +193 -191
- package/lib/esm/TextEdit.js.map +1 -1
- package/lib/esm/Undo.d.ts +46 -46
- package/lib/esm/Undo.js +164 -164
- package/lib/esm/core-markup.d.ts +18 -18
- package/lib/esm/core-markup.js +22 -22
- package/package.json +19 -19
package/lib/esm/TextEdit.js
CHANGED
|
@@ -1,192 +1,194 @@
|
|
|
1
|
-
/*---------------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
-
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
/** @packageDocumentation
|
|
6
|
-
* @module MarkupTools
|
|
7
|
-
*/
|
|
8
|
-
import { CoreTools, EventHandled, IModelApp, InputSource, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod, } from "@itwin/core-frontend";
|
|
9
|
-
import { G, Text as MarkupText } from "@svgdotjs/svg.js";
|
|
10
|
-
import { MarkupApp } from "./Markup";
|
|
11
|
-
import { MarkupTool } from "./MarkupTool";
|
|
12
|
-
import { RedlineTool } from "./RedlineTool";
|
|
13
|
-
// cspell:ignore rbox
|
|
14
|
-
/** Tool to place new text notes on a Markup.
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
constructor() {
|
|
19
|
-
super(...arguments);
|
|
20
|
-
this._nRequiredPoints = 1;
|
|
21
|
-
this._minPoints = 0;
|
|
22
|
-
}
|
|
23
|
-
async onPostInstall() {
|
|
24
|
-
this._value = MarkupApp.props.text.startValue; // so applications can put a default string (e.g. user's initials) in the note. Can be empty
|
|
25
|
-
return super.onPostInstall();
|
|
26
|
-
}
|
|
27
|
-
showPrompt() { this.provideToolAssistance(`${MarkupTool.toolKey}Text.Place.Prompts.FirstPoint`, true); }
|
|
28
|
-
async createMarkup(svg, ev, isDynamics) {
|
|
29
|
-
if (isDynamics && InputSource.Touch === ev.inputSource)
|
|
30
|
-
return;
|
|
31
|
-
const start = MarkupApp.convertVpToVb(ev.viewPoint); // starting point in viewbox coordinates
|
|
32
|
-
const text = new MarkupText().plain(this._value); // create a plain text element
|
|
33
|
-
svg.put(text); // add it to the supplied container
|
|
34
|
-
this.setCurrentTextStyle(text); // apply active text style
|
|
35
|
-
text.translate(start.x, start.y); // and position it relative to the cursor
|
|
36
|
-
if (isDynamics) {
|
|
37
|
-
svg.add(text.getOutline().attr(MarkupApp.props.text.edit.textBox).addClass(MarkupApp.textOutlineClass)); // in dynamics, draw the box around the text
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
await new EditTextTool(text, true).run(); // text is now positioned, open text editor
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
async onResetButtonUp(_ev) {
|
|
44
|
-
await this.exitTool();
|
|
45
|
-
return EventHandled.Yes;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
PlaceTextTool.toolId = "Markup.Text.Place";
|
|
49
|
-
PlaceTextTool.iconSpec = "icon-text-medium";
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
sections
|
|
71
|
-
sections.push(ToolAssistance.createSection(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
style
|
|
92
|
-
style.
|
|
93
|
-
style.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
text.
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
outline.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
editor
|
|
104
|
-
editor.
|
|
105
|
-
editor.
|
|
106
|
-
editor.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
style
|
|
119
|
-
style.
|
|
120
|
-
style.
|
|
121
|
-
style.
|
|
122
|
-
style.
|
|
123
|
-
style.
|
|
124
|
-
style.
|
|
125
|
-
style.
|
|
126
|
-
style.
|
|
127
|
-
style.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
undo
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
newText.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
editSize.
|
|
167
|
-
|
|
168
|
-
this.editDiv
|
|
169
|
-
this.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
EditTextTool.
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/** @packageDocumentation
|
|
6
|
+
* @module MarkupTools
|
|
7
|
+
*/
|
|
8
|
+
import { CoreTools, EventHandled, IModelApp, InputSource, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod, } from "@itwin/core-frontend";
|
|
9
|
+
import { G, Text as MarkupText } from "@svgdotjs/svg.js";
|
|
10
|
+
import { MarkupApp } from "./Markup";
|
|
11
|
+
import { MarkupTool } from "./MarkupTool";
|
|
12
|
+
import { RedlineTool } from "./RedlineTool";
|
|
13
|
+
// cspell:ignore rbox
|
|
14
|
+
/** Tool to place new text notes on a Markup.
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
class PlaceTextTool extends RedlineTool {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this._nRequiredPoints = 1;
|
|
21
|
+
this._minPoints = 0;
|
|
22
|
+
}
|
|
23
|
+
async onPostInstall() {
|
|
24
|
+
this._value = MarkupApp.props.text.startValue; // so applications can put a default string (e.g. user's initials) in the note. Can be empty
|
|
25
|
+
return super.onPostInstall();
|
|
26
|
+
}
|
|
27
|
+
showPrompt() { this.provideToolAssistance(`${MarkupTool.toolKey}Text.Place.Prompts.FirstPoint`, true); }
|
|
28
|
+
async createMarkup(svg, ev, isDynamics) {
|
|
29
|
+
if (isDynamics && InputSource.Touch === ev.inputSource)
|
|
30
|
+
return;
|
|
31
|
+
const start = MarkupApp.convertVpToVb(ev.viewPoint); // starting point in viewbox coordinates
|
|
32
|
+
const text = new MarkupText().plain(this._value); // create a plain text element
|
|
33
|
+
svg.put(text); // add it to the supplied container
|
|
34
|
+
this.setCurrentTextStyle(text); // apply active text style
|
|
35
|
+
text.translate(start.x, start.y); // and position it relative to the cursor
|
|
36
|
+
if (isDynamics) {
|
|
37
|
+
svg.add(text.getOutline().attr(MarkupApp.props.text.edit.textBox).addClass(MarkupApp.textOutlineClass)); // in dynamics, draw the box around the text
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
await new EditTextTool(text, true).run(); // text is now positioned, open text editor
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async onResetButtonUp(_ev) {
|
|
44
|
+
await this.exitTool();
|
|
45
|
+
return EventHandled.Yes;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
PlaceTextTool.toolId = "Markup.Text.Place";
|
|
49
|
+
PlaceTextTool.iconSpec = "icon-text-medium";
|
|
50
|
+
export { PlaceTextTool };
|
|
51
|
+
/** Tool for editing text. Started automatically by the place text tool and by clicking on text from the SelectTool
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
class EditTextTool extends MarkupTool {
|
|
55
|
+
constructor(text, _fromPlaceTool = false) {
|
|
56
|
+
super();
|
|
57
|
+
this.text = text;
|
|
58
|
+
this._fromPlaceTool = _fromPlaceTool;
|
|
59
|
+
}
|
|
60
|
+
showPrompt() {
|
|
61
|
+
const mainInstruction = ToolAssistance.createInstruction(this.iconSpec, IModelApp.localization.getLocalizedString(`${MarkupTool.toolKey}Text.Edit.Prompts.FirstPoint`));
|
|
62
|
+
const mouseInstructions = [];
|
|
63
|
+
const touchInstructions = [];
|
|
64
|
+
const acceptMsg = CoreTools.translate("ElementSet.Inputs.Accept");
|
|
65
|
+
const rejectMsg = CoreTools.translate("ElementSet.Inputs.Exit");
|
|
66
|
+
touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, acceptMsg, false, ToolAssistanceInputMethod.Touch));
|
|
67
|
+
mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.LeftClick, acceptMsg, false, ToolAssistanceInputMethod.Mouse));
|
|
68
|
+
touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.TwoTouchTap, rejectMsg, false, ToolAssistanceInputMethod.Touch));
|
|
69
|
+
mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.RightClick, rejectMsg, false, ToolAssistanceInputMethod.Mouse));
|
|
70
|
+
const sections = [];
|
|
71
|
+
sections.push(ToolAssistance.createSection(mouseInstructions, ToolAssistance.inputsLabel));
|
|
72
|
+
sections.push(ToolAssistance.createSection(touchInstructions, ToolAssistance.inputsLabel));
|
|
73
|
+
const instructions = ToolAssistance.createInstructions(mainInstruction, sections);
|
|
74
|
+
IModelApp.notifications.setToolAssistance(instructions);
|
|
75
|
+
}
|
|
76
|
+
/** Open the text editor */
|
|
77
|
+
startEditor() {
|
|
78
|
+
let text = this.text;
|
|
79
|
+
if (text === undefined)
|
|
80
|
+
return;
|
|
81
|
+
if (text instanceof G) {
|
|
82
|
+
this.boxed = text;
|
|
83
|
+
text = text.children()[1];
|
|
84
|
+
if (!(text instanceof MarkupText))
|
|
85
|
+
return;
|
|
86
|
+
this.text = text;
|
|
87
|
+
}
|
|
88
|
+
const markupDiv = this.markup.markupDiv;
|
|
89
|
+
const editDiv = this.editDiv = document.createElement("div"); // create a new DIV to hold the text editor
|
|
90
|
+
const editProps = MarkupApp.props.text.edit;
|
|
91
|
+
let style = editDiv.style;
|
|
92
|
+
style.backgroundColor = editProps.background;
|
|
93
|
+
style.top = style.left = "0";
|
|
94
|
+
style.right = style.bottom = "100%";
|
|
95
|
+
markupDiv.appendChild(editDiv); // add textEditor div to markup div
|
|
96
|
+
const divRect = markupDiv.getBoundingClientRect();
|
|
97
|
+
const outline = text.getOutline(); // use the outline rather than the text in case it's blank.
|
|
98
|
+
text.after(outline); // we have to add it to the DOM or the rbox call doesn't work.
|
|
99
|
+
const rbox = outline.rbox();
|
|
100
|
+
const bbox = outline.bbox();
|
|
101
|
+
outline.remove(); // take it out again.
|
|
102
|
+
const editor = this.editor = document.createElement("textarea");
|
|
103
|
+
editDiv.appendChild(editor);
|
|
104
|
+
editor.className = MarkupApp.textEditorClass;
|
|
105
|
+
editor.contentEditable = "true";
|
|
106
|
+
editor.spellcheck = true;
|
|
107
|
+
editor.wrap = "off";
|
|
108
|
+
// so we don't send these events to the ToolAdmin and process them by tools. We want default handling
|
|
109
|
+
const mouseListener = (ev) => (ev.stopPropagation(), true);
|
|
110
|
+
editor.onselectstart = editor.oncontextmenu = editor.onmousedown = editor.onmouseup = mouseListener; // enable default handling for these events
|
|
111
|
+
// Tab, Escape, ctrl-enter, or shift-enter all end the editor
|
|
112
|
+
editor.onkeydown = async (ev) => {
|
|
113
|
+
if (ev.key === "Tab" || ev.key === "Escape" || (ev.key === "Enter" && (ev.shiftKey || ev.ctrlKey)))
|
|
114
|
+
this.exitTool(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
|
115
|
+
ev.stopPropagation();
|
|
116
|
+
};
|
|
117
|
+
const textElStyle = window.getComputedStyle(text.node);
|
|
118
|
+
style = editor.style;
|
|
119
|
+
style.pointerEvents = "auto";
|
|
120
|
+
style.position = "absolute";
|
|
121
|
+
style.top = `${(rbox.cy - (bbox.h / 2)) - divRect.top}px`; // put the editor over the middle of the text element
|
|
122
|
+
style.left = `${(rbox.cx - (bbox.w / 2)) - divRect.left}px`;
|
|
123
|
+
style.height = editProps.size.height;
|
|
124
|
+
style.width = editProps.size.width;
|
|
125
|
+
style.resize = "both";
|
|
126
|
+
style.fontFamily = textElStyle.fontFamily; // set the font family and anchor to the same as the text element
|
|
127
|
+
style.textAnchor = textElStyle.textAnchor;
|
|
128
|
+
style.fontSize = editProps.fontSize; // from app.props
|
|
129
|
+
const parentZ = parseInt(window.getComputedStyle(markupDiv).zIndex || "0", 10);
|
|
130
|
+
style.zIndex = (parentZ + 200).toString();
|
|
131
|
+
editor.innerHTML = text.getMarkup(); // start with existing text
|
|
132
|
+
this.editor.focus(); // give the editor focus
|
|
133
|
+
// if we're started from the place text tool, select the entire current value, otherwise place the cursor at the end.
|
|
134
|
+
this.editor.setSelectionRange(this._fromPlaceTool ? 0 : editor.value.length, editor.value.length);
|
|
135
|
+
}
|
|
136
|
+
/** Called when EditText exits, saves the edited value into the text element */
|
|
137
|
+
async onCleanup() {
|
|
138
|
+
if (!this.editDiv)
|
|
139
|
+
return;
|
|
140
|
+
const text = this.text;
|
|
141
|
+
const original = this.boxed ? this.boxed : text;
|
|
142
|
+
const undo = this.markup.undo;
|
|
143
|
+
undo.performOperation(this.keyin, () => {
|
|
144
|
+
const newVal = this.editor.value;
|
|
145
|
+
if (newVal.trim() === "") { // if the result of the editing is blank, just delete the text element
|
|
146
|
+
if (!this._fromPlaceTool)
|
|
147
|
+
undo.onDelete(original);
|
|
148
|
+
original.remove(); // must do this *after* we call undo.onDelete
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
let newText = text.clone();
|
|
152
|
+
const fontSize = text.getFontSize();
|
|
153
|
+
newText.createMarkup(newVal, fontSize);
|
|
154
|
+
if (this.boxed) {
|
|
155
|
+
newText = this.createBoxedText(original.parent(), newText);
|
|
156
|
+
newText.matrix(original.matrix());
|
|
157
|
+
}
|
|
158
|
+
original.replace(newText);
|
|
159
|
+
if (this._fromPlaceTool)
|
|
160
|
+
undo.onAdded(newText);
|
|
161
|
+
else
|
|
162
|
+
undo.onModified(newText, original);
|
|
163
|
+
});
|
|
164
|
+
const editSize = MarkupApp.props.text.edit.size;
|
|
165
|
+
const style = this.editor.style;
|
|
166
|
+
editSize.height = style.height;
|
|
167
|
+
editSize.width = style.width;
|
|
168
|
+
this.editDiv.remove();
|
|
169
|
+
this.editDiv = undefined;
|
|
170
|
+
this.editor = undefined;
|
|
171
|
+
}
|
|
172
|
+
async onInstall() {
|
|
173
|
+
if (!await super.onInstall())
|
|
174
|
+
return false;
|
|
175
|
+
this.startEditor();
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
async onResetButtonUp(_ev) {
|
|
179
|
+
await this.exitTool();
|
|
180
|
+
return EventHandled.Yes;
|
|
181
|
+
}
|
|
182
|
+
async onDataButtonUp(_ev) {
|
|
183
|
+
await this.exitTool();
|
|
184
|
+
return EventHandled.Yes;
|
|
185
|
+
}
|
|
186
|
+
async onMouseStartDrag(_ev) {
|
|
187
|
+
await this.exitTool();
|
|
188
|
+
return EventHandled.Yes;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
EditTextTool.toolId = "Markup.Text.Edit";
|
|
192
|
+
EditTextTool.iconSpec = "icon-text-medium";
|
|
193
|
+
export { EditTextTool };
|
|
192
194
|
//# sourceMappingURL=TextEdit.js.map
|
package/lib/esm/TextEdit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextEdit.js","sourceRoot":"","sources":["../../src/TextEdit.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module MarkupTools\r\n */\r\n\r\nimport {\r\n BeButtonEvent, CoreTools, EventHandled, IModelApp, InputSource, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod,\r\n ToolAssistanceInstruction, ToolAssistanceSection,\r\n} from \"@itwin/core-frontend\";\r\nimport { G, Text as MarkupText } from \"@svgdotjs/svg.js\";\r\nimport { MarkupApp } from \"./Markup\";\r\nimport { MarkupTool } from \"./MarkupTool\";\r\nimport { RedlineTool } from \"./RedlineTool\";\r\n\r\n// cspell:ignore rbox\r\n\r\n/** Tool to place new text notes on a Markup.\r\n * @public\r\n */\r\nexport class PlaceTextTool extends RedlineTool {\r\n public static override toolId = \"Markup.Text.Place\";\r\n public static override iconSpec = \"icon-text-medium\";\r\n protected override _nRequiredPoints = 1;\r\n protected override _minPoints = 0;\r\n protected _value!: string;\r\n\r\n public override async onPostInstall() {\r\n this._value = MarkupApp.props.text.startValue; // so applications can put a default string (e.g. user's initials) in the note. Can be empty\r\n return super.onPostInstall();\r\n }\r\n\r\n protected override showPrompt(): void { this.provideToolAssistance(`${MarkupTool.toolKey}Text.Place.Prompts.FirstPoint`, true); }\r\n\r\n protected override async createMarkup(svg: G, ev: BeButtonEvent, isDynamics: boolean): Promise<void> {\r\n if (isDynamics && InputSource.Touch === ev.inputSource)\r\n return;\r\n const start = MarkupApp.convertVpToVb(ev.viewPoint); // starting point in viewbox coordinates\r\n const text = new MarkupText().plain(this._value); // create a plain text element\r\n svg.put(text); // add it to the supplied container\r\n this.setCurrentTextStyle(text); // apply active text style\r\n text.translate(start.x, start.y); // and position it relative to the cursor\r\n if (isDynamics) {\r\n svg.add(text.getOutline().attr(MarkupApp.props.text.edit.textBox).addClass(MarkupApp.textOutlineClass)); // in dynamics, draw the box around the text\r\n } else {\r\n await new EditTextTool(text, true).run(); // text is now positioned, open text editor\r\n }\r\n }\r\n public override async onResetButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n}\r\n\r\n/** Tool for editing text. Started automatically by the place text tool and by clicking on text from the SelectTool\r\n * @public\r\n */\r\nexport class EditTextTool extends MarkupTool {\r\n public static override toolId = \"Markup.Text.Edit\";\r\n public static override iconSpec = \"icon-text-medium\";\r\n public editor?: HTMLTextAreaElement;\r\n public editDiv?: HTMLDivElement;\r\n public boxed?: G;\r\n constructor(public text?: MarkupText | G, private _fromPlaceTool = false) { super(); }\r\n\r\n protected override showPrompt(): void {\r\n const mainInstruction = ToolAssistance.createInstruction(this.iconSpec, IModelApp.localization.getLocalizedString(`${MarkupTool.toolKey}Text.Edit.Prompts.FirstPoint`));\r\n const mouseInstructions: ToolAssistanceInstruction[] = [];\r\n const touchInstructions: ToolAssistanceInstruction[] = [];\r\n\r\n const acceptMsg = CoreTools.translate(\"ElementSet.Inputs.Accept\");\r\n const rejectMsg = CoreTools.translate(\"ElementSet.Inputs.Exit\");\r\n touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, acceptMsg, false, ToolAssistanceInputMethod.Touch));\r\n mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.LeftClick, acceptMsg, false, ToolAssistanceInputMethod.Mouse));\r\n touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.TwoTouchTap, rejectMsg, false, ToolAssistanceInputMethod.Touch));\r\n mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.RightClick, rejectMsg, false, ToolAssistanceInputMethod.Mouse));\r\n\r\n const sections: ToolAssistanceSection[] = [];\r\n sections.push(ToolAssistance.createSection(mouseInstructions, ToolAssistance.inputsLabel));\r\n sections.push(ToolAssistance.createSection(touchInstructions, ToolAssistance.inputsLabel));\r\n\r\n const instructions = ToolAssistance.createInstructions(mainInstruction, sections);\r\n IModelApp.notifications.setToolAssistance(instructions);\r\n }\r\n\r\n /** Open the text editor */\r\n public startEditor() {\r\n let text = this.text;\r\n if (text === undefined)\r\n return;\r\n\r\n if (text instanceof G) {\r\n this.boxed = text;\r\n text = text.children()[1] as MarkupText;\r\n if (!(text instanceof MarkupText))\r\n return;\r\n this.text = text;\r\n }\r\n const markupDiv = this.markup.markupDiv;\r\n const editDiv = this.editDiv = document.createElement(\"div\"); // create a new DIV to hold the text editor\r\n const editProps = MarkupApp.props.text.edit;\r\n let style = editDiv.style;\r\n style.backgroundColor = editProps.background;\r\n style.top = style.left = \"0\";\r\n style.right = style.bottom = \"100%\";\r\n\r\n markupDiv.appendChild(editDiv); // add textEditor div to markup div\r\n\r\n const divRect = markupDiv.getBoundingClientRect();\r\n const outline = text.getOutline(); // use the outline rather than the text in case it's blank.\r\n text.after(outline); // we have to add it to the DOM or the rbox call doesn't work.\r\n const rbox = outline.rbox();\r\n const bbox = outline.bbox();\r\n outline.remove(); // take it out again.\r\n const editor = this.editor = document.createElement(\"textarea\");\r\n editDiv.appendChild(editor);\r\n editor.className = MarkupApp.textEditorClass;\r\n editor.contentEditable = \"true\";\r\n editor.spellcheck = true;\r\n editor.wrap = \"off\";\r\n // so we don't send these events to the ToolAdmin and process them by tools. We want default handling\r\n const mouseListener = (ev: Event) => (ev.stopPropagation(), true);\r\n (editor as any).onselectstart = editor.oncontextmenu = editor.onmousedown = editor.onmouseup = mouseListener; // enable default handling for these events\r\n\r\n // Tab, Escape, ctrl-enter, or shift-enter all end the editor\r\n editor.onkeydown = async (ev: KeyboardEvent) => {\r\n if (ev.key === \"Tab\" || ev.key === \"Escape\" || (ev.key === \"Enter\" && (ev.shiftKey || ev.ctrlKey)))\r\n this.exitTool(); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n ev.stopPropagation();\r\n\r\n };\r\n const textElStyle = window.getComputedStyle(text.node);\r\n\r\n style = editor.style;\r\n style.pointerEvents = \"auto\";\r\n style.position = \"absolute\";\r\n style.top = `${(rbox.cy - (bbox.h / 2)) - divRect.top}px`; // put the editor over the middle of the text element\r\n style.left = `${(rbox.cx - (bbox.w / 2)) - divRect.left}px`;\r\n style.height = editProps.size.height;\r\n style.width = editProps.size.width;\r\n style.resize = \"both\";\r\n style.fontFamily = textElStyle.fontFamily; // set the font family and anchor to the same as the text element\r\n style.textAnchor = textElStyle.textAnchor;\r\n style.fontSize = editProps.fontSize; // from app.props\r\n\r\n const parentZ = parseInt(window.getComputedStyle(markupDiv).zIndex || \"0\", 10);\r\n style.zIndex = (parentZ + 200).toString();\r\n\r\n editor.innerHTML = text.getMarkup(); // start with existing text\r\n this.editor.focus(); // give the editor focus\r\n\r\n // if we're started from the place text tool, select the entire current value, otherwise place the cursor at the end.\r\n this.editor.setSelectionRange(this._fromPlaceTool ? 0 : editor.value.length, editor.value.length);\r\n }\r\n\r\n /** Called when EditText exits, saves the edited value into the text element */\r\n public override async onCleanup() {\r\n if (!this.editDiv)\r\n return;\r\n\r\n const text = this.text! as MarkupText;\r\n const original = this.boxed ? this.boxed : text;\r\n const undo = this.markup.undo;\r\n undo.performOperation(this.keyin, () => {\r\n const newVal = this.editor!.value;\r\n if (newVal.trim() === \"\") { // if the result of the editing is blank, just delete the text element\r\n if (!this._fromPlaceTool)\r\n undo.onDelete(original);\r\n original.remove(); // must do this *after* we call undo.onDelete\r\n return;\r\n }\r\n\r\n let newText: G | MarkupText = text.clone();\r\n const fontSize = text.getFontSize();\r\n newText.createMarkup(newVal, fontSize);\r\n if (this.boxed) {\r\n newText = this.createBoxedText((original as G).parent() as G, newText);\r\n newText.matrix(original.matrix());\r\n }\r\n original.replace(newText);\r\n if (this._fromPlaceTool)\r\n undo.onAdded(newText);\r\n else\r\n undo.onModified(newText, original);\r\n });\r\n\r\n const editSize = MarkupApp.props.text.edit.size;\r\n const style = this.editor!.style;\r\n editSize.height = style.height;\r\n editSize.width = style.width;\r\n this.editDiv.remove();\r\n this.editDiv = undefined;\r\n this.editor = undefined;\r\n }\r\n\r\n public override async onInstall() {\r\n if (!await super.onInstall())\r\n return false;\r\n this.startEditor();\r\n return true;\r\n }\r\n\r\n public override async onResetButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n\r\n public override async onDataButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n\r\n public override async onMouseStartDrag(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"TextEdit.js","sourceRoot":"","sources":["../../src/TextEdit.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module MarkupTools\r\n */\r\n\r\nimport {\r\n BeButtonEvent, CoreTools, EventHandled, IModelApp, InputSource, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod,\r\n ToolAssistanceInstruction, ToolAssistanceSection,\r\n} from \"@itwin/core-frontend\";\r\nimport { G, Text as MarkupText } from \"@svgdotjs/svg.js\";\r\nimport { MarkupApp } from \"./Markup\";\r\nimport { MarkupTool } from \"./MarkupTool\";\r\nimport { RedlineTool } from \"./RedlineTool\";\r\n\r\n// cspell:ignore rbox\r\n\r\n/** Tool to place new text notes on a Markup.\r\n * @public\r\n */\r\nexport class PlaceTextTool extends RedlineTool {\r\n public static override toolId = \"Markup.Text.Place\";\r\n public static override iconSpec = \"icon-text-medium\";\r\n protected override _nRequiredPoints = 1;\r\n protected override _minPoints = 0;\r\n protected _value!: string;\r\n\r\n public override async onPostInstall() {\r\n this._value = MarkupApp.props.text.startValue; // so applications can put a default string (e.g. user's initials) in the note. Can be empty\r\n return super.onPostInstall();\r\n }\r\n\r\n protected override showPrompt(): void { this.provideToolAssistance(`${MarkupTool.toolKey}Text.Place.Prompts.FirstPoint`, true); }\r\n\r\n protected override async createMarkup(svg: G, ev: BeButtonEvent, isDynamics: boolean): Promise<void> {\r\n if (isDynamics && InputSource.Touch === ev.inputSource)\r\n return;\r\n const start = MarkupApp.convertVpToVb(ev.viewPoint); // starting point in viewbox coordinates\r\n const text = new MarkupText().plain(this._value); // create a plain text element\r\n svg.put(text); // add it to the supplied container\r\n this.setCurrentTextStyle(text); // apply active text style\r\n text.translate(start.x, start.y); // and position it relative to the cursor\r\n if (isDynamics) {\r\n svg.add(text.getOutline().attr(MarkupApp.props.text.edit.textBox).addClass(MarkupApp.textOutlineClass)); // in dynamics, draw the box around the text\r\n } else {\r\n await new EditTextTool(text, true).run(); // text is now positioned, open text editor\r\n }\r\n }\r\n public override async onResetButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n}\r\n\r\n/** Tool for editing text. Started automatically by the place text tool and by clicking on text from the SelectTool\r\n * @public\r\n */\r\nexport class EditTextTool extends MarkupTool {\r\n public static override toolId = \"Markup.Text.Edit\";\r\n public static override iconSpec = \"icon-text-medium\";\r\n public editor?: HTMLTextAreaElement;\r\n public editDiv?: HTMLDivElement;\r\n public boxed?: G;\r\n constructor(public text?: MarkupText | G, private _fromPlaceTool = false) { super(); }\r\n\r\n protected override showPrompt(): void {\r\n const mainInstruction = ToolAssistance.createInstruction(this.iconSpec, IModelApp.localization.getLocalizedString(`${MarkupTool.toolKey}Text.Edit.Prompts.FirstPoint`));\r\n const mouseInstructions: ToolAssistanceInstruction[] = [];\r\n const touchInstructions: ToolAssistanceInstruction[] = [];\r\n\r\n const acceptMsg = CoreTools.translate(\"ElementSet.Inputs.Accept\");\r\n const rejectMsg = CoreTools.translate(\"ElementSet.Inputs.Exit\");\r\n touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, acceptMsg, false, ToolAssistanceInputMethod.Touch));\r\n mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.LeftClick, acceptMsg, false, ToolAssistanceInputMethod.Mouse));\r\n touchInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.TwoTouchTap, rejectMsg, false, ToolAssistanceInputMethod.Touch));\r\n mouseInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.RightClick, rejectMsg, false, ToolAssistanceInputMethod.Mouse));\r\n\r\n const sections: ToolAssistanceSection[] = [];\r\n sections.push(ToolAssistance.createSection(mouseInstructions, ToolAssistance.inputsLabel));\r\n sections.push(ToolAssistance.createSection(touchInstructions, ToolAssistance.inputsLabel));\r\n\r\n const instructions = ToolAssistance.createInstructions(mainInstruction, sections);\r\n IModelApp.notifications.setToolAssistance(instructions);\r\n }\r\n\r\n /** Open the text editor */\r\n public startEditor() {\r\n let text = this.text;\r\n if (text === undefined)\r\n return;\r\n\r\n if (text instanceof G) {\r\n this.boxed = text;\r\n text = text.children()[1] as MarkupText;\r\n if (!(text instanceof MarkupText))\r\n return;\r\n this.text = text;\r\n }\r\n const markupDiv = this.markup.markupDiv;\r\n const editDiv = this.editDiv = document.createElement(\"div\"); // create a new DIV to hold the text editor\r\n const editProps = MarkupApp.props.text.edit;\r\n let style = editDiv.style;\r\n style.backgroundColor = editProps.background;\r\n style.top = style.left = \"0\";\r\n style.right = style.bottom = \"100%\";\r\n\r\n markupDiv.appendChild(editDiv); // add textEditor div to markup div\r\n\r\n const divRect = markupDiv.getBoundingClientRect();\r\n const outline = text.getOutline(); // use the outline rather than the text in case it's blank.\r\n text.after(outline); // we have to add it to the DOM or the rbox call doesn't work.\r\n const rbox = outline.rbox();\r\n const bbox = outline.bbox();\r\n outline.remove(); // take it out again.\r\n const editor = this.editor = document.createElement(\"textarea\");\r\n editDiv.appendChild(editor);\r\n editor.className = MarkupApp.textEditorClass;\r\n editor.contentEditable = \"true\";\r\n editor.spellcheck = true;\r\n editor.wrap = \"off\";\r\n // so we don't send these events to the ToolAdmin and process them by tools. We want default handling\r\n const mouseListener = (ev: Event) => (ev.stopPropagation(), true);\r\n (editor as any).onselectstart = editor.oncontextmenu = editor.onmousedown = editor.onmouseup = mouseListener; // enable default handling for these events\r\n\r\n // Tab, Escape, ctrl-enter, or shift-enter all end the editor\r\n editor.onkeydown = async (ev: KeyboardEvent) => {\r\n if (ev.key === \"Tab\" || ev.key === \"Escape\" || (ev.key === \"Enter\" && (ev.shiftKey || ev.ctrlKey)))\r\n this.exitTool(); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n ev.stopPropagation();\r\n\r\n };\r\n const textElStyle = window.getComputedStyle(text.node);\r\n\r\n style = editor.style;\r\n style.pointerEvents = \"auto\";\r\n style.position = \"absolute\";\r\n style.top = `${(rbox.cy - (bbox.h / 2)) - divRect.top}px`; // put the editor over the middle of the text element\r\n style.left = `${(rbox.cx - (bbox.w / 2)) - divRect.left}px`;\r\n style.height = editProps.size.height;\r\n style.width = editProps.size.width;\r\n style.resize = \"both\";\r\n style.fontFamily = textElStyle.fontFamily; // set the font family and anchor to the same as the text element\r\n style.textAnchor = textElStyle.textAnchor;\r\n style.fontSize = editProps.fontSize; // from app.props\r\n\r\n const parentZ = parseInt(window.getComputedStyle(markupDiv).zIndex || \"0\", 10);\r\n style.zIndex = (parentZ + 200).toString();\r\n\r\n editor.innerHTML = text.getMarkup(); // start with existing text\r\n this.editor.focus(); // give the editor focus\r\n\r\n // if we're started from the place text tool, select the entire current value, otherwise place the cursor at the end.\r\n this.editor.setSelectionRange(this._fromPlaceTool ? 0 : editor.value.length, editor.value.length);\r\n }\r\n\r\n /** Called when EditText exits, saves the edited value into the text element */\r\n public override async onCleanup() {\r\n if (!this.editDiv)\r\n return;\r\n\r\n const text = this.text! as MarkupText;\r\n const original = this.boxed ? this.boxed : text;\r\n const undo = this.markup.undo;\r\n undo.performOperation(this.keyin, () => {\r\n const newVal = this.editor!.value;\r\n if (newVal.trim() === \"\") { // if the result of the editing is blank, just delete the text element\r\n if (!this._fromPlaceTool)\r\n undo.onDelete(original);\r\n original.remove(); // must do this *after* we call undo.onDelete\r\n return;\r\n }\r\n\r\n let newText: G | MarkupText = text.clone();\r\n const fontSize = text.getFontSize();\r\n newText.createMarkup(newVal, fontSize);\r\n if (this.boxed) {\r\n newText = this.createBoxedText((original as G).parent() as G, newText);\r\n newText.matrix(original.matrix());\r\n }\r\n original.replace(newText);\r\n if (this._fromPlaceTool)\r\n undo.onAdded(newText);\r\n else\r\n undo.onModified(newText, original);\r\n });\r\n\r\n const editSize = MarkupApp.props.text.edit.size;\r\n const style = this.editor!.style;\r\n editSize.height = style.height;\r\n editSize.width = style.width;\r\n this.editDiv.remove();\r\n this.editDiv = undefined;\r\n this.editor = undefined;\r\n }\r\n\r\n public override async onInstall() {\r\n if (!await super.onInstall())\r\n return false;\r\n this.startEditor();\r\n return true;\r\n }\r\n\r\n public override async onResetButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n\r\n public override async onDataButtonUp(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n\r\n public override async onMouseStartDrag(_ev: BeButtonEvent): Promise<EventHandled> {\r\n await this.exitTool();\r\n return EventHandled.Yes;\r\n }\r\n}\r\n"]}
|
package/lib/esm/Undo.d.ts
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
/** @packageDocumentation
|
|
2
|
-
* @module MarkupTools
|
|
3
|
-
*/
|
|
4
|
-
import { Element as MarkupElement } from "@svgdotjs/svg.js";
|
|
5
|
-
/** Stores the sequence of operations performed on a Markup. Facilitates undo/redo of the operations.
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export declare class UndoManager {
|
|
9
|
-
private _currentCmd;
|
|
10
|
-
private _grouped;
|
|
11
|
-
private _stack;
|
|
12
|
-
private _currentPos;
|
|
13
|
-
private _cmdName;
|
|
14
|
-
private addAction;
|
|
15
|
-
/** @internal */
|
|
16
|
-
get size(): number;
|
|
17
|
-
private startCommand;
|
|
18
|
-
private startGroup;
|
|
19
|
-
private endGroup;
|
|
20
|
-
/** Perform a series of changes to markup elements that should all be reversed as a single operation.
|
|
21
|
-
* @param fn the function that performs the changes to the elements. It must call the onXXX methods of this class to store
|
|
22
|
-
* the operations in the undo buffer.
|
|
23
|
-
* @note all of the onXXX methods of this class should *only* be called from within the callback function of this method.
|
|
24
|
-
*/
|
|
25
|
-
performOperation(cmdName: string, fn: VoidFunction): void;
|
|
26
|
-
/** call this from within a [[performOperation]] function *after* an element has been added to a markup */
|
|
27
|
-
onAdded(elem: MarkupElement): void;
|
|
28
|
-
/** call this from within a [[performOperation]] function *before* an element is about to be deleted from a markup */
|
|
29
|
-
onDelete(elem: MarkupElement): void;
|
|
30
|
-
/** call this from within a [[performOperation]] function *after* an element has been moved in display order in a markup */
|
|
31
|
-
onRepositioned(elem: MarkupElement, oldIndex: number, oldParent: MarkupElement): void;
|
|
32
|
-
/** call this from within a [[performOperation]] function *after* an element has been modified in a markup */
|
|
33
|
-
onModified(newElem: MarkupElement, oldElem: MarkupElement): void;
|
|
34
|
-
/** determine whether there are any un-reversed operations */
|
|
35
|
-
get undoPossible(): boolean;
|
|
36
|
-
/** determine whether there are any reversed operations */
|
|
37
|
-
get redoPossible(): boolean;
|
|
38
|
-
/** the name of the operation that can be undone (or undefined) */
|
|
39
|
-
get undoString(): string | undefined;
|
|
40
|
-
/** the name of the operation that can be redone (or undefined) */
|
|
41
|
-
get redoString(): string | undefined;
|
|
42
|
-
/** reverse the most recent operation, if any */
|
|
43
|
-
doUndo(): void;
|
|
44
|
-
/** reinstate the most recently reversed operation, if any */
|
|
45
|
-
doRedo(): void;
|
|
46
|
-
}
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module MarkupTools
|
|
3
|
+
*/
|
|
4
|
+
import { Element as MarkupElement } from "@svgdotjs/svg.js";
|
|
5
|
+
/** Stores the sequence of operations performed on a Markup. Facilitates undo/redo of the operations.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare class UndoManager {
|
|
9
|
+
private _currentCmd;
|
|
10
|
+
private _grouped;
|
|
11
|
+
private _stack;
|
|
12
|
+
private _currentPos;
|
|
13
|
+
private _cmdName;
|
|
14
|
+
private addAction;
|
|
15
|
+
/** @internal */
|
|
16
|
+
get size(): number;
|
|
17
|
+
private startCommand;
|
|
18
|
+
private startGroup;
|
|
19
|
+
private endGroup;
|
|
20
|
+
/** Perform a series of changes to markup elements that should all be reversed as a single operation.
|
|
21
|
+
* @param fn the function that performs the changes to the elements. It must call the onXXX methods of this class to store
|
|
22
|
+
* the operations in the undo buffer.
|
|
23
|
+
* @note all of the onXXX methods of this class should *only* be called from within the callback function of this method.
|
|
24
|
+
*/
|
|
25
|
+
performOperation(cmdName: string, fn: VoidFunction): void;
|
|
26
|
+
/** call this from within a [[performOperation]] function *after* an element has been added to a markup */
|
|
27
|
+
onAdded(elem: MarkupElement): void;
|
|
28
|
+
/** call this from within a [[performOperation]] function *before* an element is about to be deleted from a markup */
|
|
29
|
+
onDelete(elem: MarkupElement): void;
|
|
30
|
+
/** call this from within a [[performOperation]] function *after* an element has been moved in display order in a markup */
|
|
31
|
+
onRepositioned(elem: MarkupElement, oldIndex: number, oldParent: MarkupElement): void;
|
|
32
|
+
/** call this from within a [[performOperation]] function *after* an element has been modified in a markup */
|
|
33
|
+
onModified(newElem: MarkupElement, oldElem: MarkupElement): void;
|
|
34
|
+
/** determine whether there are any un-reversed operations */
|
|
35
|
+
get undoPossible(): boolean;
|
|
36
|
+
/** determine whether there are any reversed operations */
|
|
37
|
+
get redoPossible(): boolean;
|
|
38
|
+
/** the name of the operation that can be undone (or undefined) */
|
|
39
|
+
get undoString(): string | undefined;
|
|
40
|
+
/** the name of the operation that can be redone (or undefined) */
|
|
41
|
+
get redoString(): string | undefined;
|
|
42
|
+
/** reverse the most recent operation, if any */
|
|
43
|
+
doUndo(): void;
|
|
44
|
+
/** reinstate the most recently reversed operation, if any */
|
|
45
|
+
doRedo(): void;
|
|
46
|
+
}
|
|
47
47
|
//# sourceMappingURL=Undo.d.ts.map
|