Undo and redo ​
Introduction ​
Foxit PDF SDK for Web provides an undo-redo add-on that adds undo and redo for PDF documents. Users can press Ctrl+Z and Ctrl+Y to undo and redo:
- Add annotation
- Delete annotation
- Modify annotation
The add-on also exposes programming APIs so you can implement undo and redo in custom applications.
Load the add-on ​
See Add-ons overview for loading instructions. After the add-on loads, undo/redo is active automatically. Users can press Ctrl+Z and Ctrl+Y (on Mac: Cmd+Z and Cmd+Y) to undo and redo the last operation.
Programming API ​
In addition to keyboard shortcuts, the undo-redo add-on provides APIs for custom workflows. Obtain the add-on instance before calling its methods:
javascript
async function obtainAddonInstanceExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
/ Here you can begin to use the methods of undoRedoAddon object.
} else {
console.error("UndoRedo Addon instance not found.");
}
}For full API details, see UndoRedoAddon in the API Reference.
After you obtain the UndoRedoAddon instance, you can call its methods.
Undo ​
undoRedoAddon.undo() undoes the user's last operation:
javascript
async function undoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}Redo ​
undoRedoAddon.redo() re-applies the last undone operation:
javascript
async function redoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.redo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}Undo all ​
undoRedoAddon.undoAll() undoes every recorded operation and restores the document to its initial state:
javascript
async function undoAllExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}After undoing all operations, you can still redo step by step.
Record operations ​
UndoRedoAddon provides an invoke method that accepts a callback. The callback receives a wrapped PDFDoc object. Unlike the unwrapped PDFDoc, the wrapped instance records operations that can be undone and redone.
The example below records creating and modifying an annotation; those steps can then be undone and redone with undo / redo:
javascript
function wait() {
// Pause briefly after each step so you can observe the effect.
return new Promise((resolve) => setTimeout(resolve, 2000));
}
async function invokeExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
await undoRedoAddon.invoke(async (pdfDoc) => {
const pdfPage = await pdfDoc.getPageByIndex(0);
const [square, popup] = await pdfPage.addAnnot({
type: "square",
rect: {
left: 0,
right: 100,
bottom: 500,
top: 550,
},
color: 0xff0000, / Initial border color: red
});
await wait();
// After creation, set the border color to purple
await square.setBorderColor(0xff00ff);
});
await wait();
// After undo, the color returns to red
await undoRedoAddon.undo();
await wait();
// After redo, the color becomes purple again
await undoRedoAddon.redo();
await wait();
// Undo all — the square annotation is removed
await undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}APIs that support undo/redo ​
The following SDK APIs support undo and redo when used inside UIXAddon.invoke.
Object accessor APIs ​
These methods return wrapped objects when called inside an invoke callback. Methods on those wrapped objects record undoable operations:
PDFDoc.getPageByIndex(index): Get a page by index.PDFDoc.getPageById(id): Get a page by unique ID.PDFDoc.getAnnots(): Get all annotations in the document.
PDFPage.getAnnots(): Get all annotations on the page.PDFPage.getAnnotsByObjectNumArray(objectNums): Get annotations by object number array.PDFPage.getAnnotsByIdArray(annotIds): Get annotations by ID array.PDFPage.getMarkupAnnots(): Get markup annotations on the page.PDFPage.getAnnotTree(): Get the annotation tree on the page.
Example:
javascript
async function getAnnotsExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
await undoRedoAddon.invoke(async (pdfDoc) => {
const pdfPage = await pdfDoc.getPageByIndex(0);
const [square] = await pdfPage.getAnnotsByObjectNumArray([12002]);
square.setBorderColor(0xFF0000);
});
await undoRedoAddon.undo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}Operation APIs ​
Calls to these methods are recorded automatically and can be undone and redone. They must be invoked on objects returned by the accessor APIs above.
- PDFDoc
PDFDoc.addAnnot
- PDFPage
PDFPage.addAnnotPDFPage.removeAnnotByIdPDFPage.removeAnnotByObjectNumber
- Annot (base class for all annotation types):
Annot.setContentAnnot.setRectAnnot.setBorderColorAnnot.setBorderInfoAnnot.setFlags
- Markup (base class for markup annotations, including FreeText (callout, textbox, typewriter), ink, line, note, polygon, polyline, redact, sound, square, stamp, and TextMarkup (highlight, squiggly, strikeout, underline)):
Markup.setOpacityMarkup.setSubjectMarkup.setTitleMarkup.addReplyMarkup.addReviewStateMarkup.addMarkedStateMarkup.setFillColor
- Specific annotation types:
- Circle
Circle.setMeasureRatioCircle.setMeasureUnitCircle.setMeasureConversionFactorCircle.enableCaptionCircle.setCaptionColor
- Line
Line.setMeasureRatioLine.setMeasureUnitLine.enableCaptionLine.setCaptionColorLine.setEndPointLine.setStartPointLine.setEndingStyleLine.setStyleFillColorLine.setLeaderLineExtendLine.setLeaderLineOffsetLine.setLeaderLineLengthLine.setCaptionOffset
- Polygon
Polygon.enableCaptionPolygon.setCaptionColorPolygon.updateVertexesPolygon.setVertexes
- Polyline
Polyline.setMeasureRatioPolyline.enableCaptionPolyline.setCaptionColorPolyline.setEndingStylePolyline.setStyleFillColorPolyline.updateVertexesPolyline.setVertexes
- Square
Square.setMeasureRatioSquare.setMeasureUnitSquare.setMeasureConversionFactor
- FreeText (typewriter, textbox, callout)
FreeText.setAlignmentFreeText.setInnerRectFreeText.setCalloutLinePointsFreeText.setCalloutLineEndingStyleFreeText.setDefaultAppearanceFreeText.setRotation
- Screen
Screen.setRotation
- Stamp
Stamp.setRotation
- Redact
Redact.setDefaultAppearanceRedact.setOverlayTextRedact.removeOvelayTextRedact.setOverlayTextAlignmentRedact.setRepeatRedact.setAutoFontSizeRedact.setRedactApplyFillColor
- Ink
Ink.setInkList
- Link
Link.setHighlightingModeLink.setAction
- FileAttachment
FileAttachment.setIconName
- Note
Note.setIconName
- Circle