# Undo/Redo
# Introduction
Foxit PDF SDK for Web provides an addon called "undo-redo", which adds undo and redo functionality to PDF documents. Users can use the combination keys Ctrl+Z
and Ctrl+Y
to undo and redo the following actions:
- Add comments
- Delete comments
- Modify comments
- And more
Additionally, the addon also provides APIs to allow developers to implement undo and redo functionality in their custom applications.
# Load the addon
Please refer to the methods in the Addons Introduction section. Once the addon is loaded, the undo-redo functionality will be automatically activated. Users can use Ctrl+Z
and Ctrl+Y
(or Cmd+Z
and Cmd+Y
on Mac) to undo and redo the previous actions.
# APIs
In addition to providing shortcut keys, the undo-redo addon also offers a series of APIs to help developers implement custom features. Before calling the API, we first need to obtain the object instance of the undo-redo addon:
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 a detailed description of APIs in UndoRedoAddon class, please refer to the API Reference (opens new window).
After getting the UndoRedoAddon instance, let's start using it.
# Undo an operation
The undoRedoAddon.undo()
method is used for undoing an operation, allowing the reversal of the user's last action. Please refer to the example:
async function undoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# Redo an operation
The undoRedoAddon.redo()
method is used for redoing an operation, allowing the reapplication of the most recent user action that was undone. Please refer to the example:
async function redoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.redo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# Undo all operations
The UndoRedoAddon.undoAll()
method is used for undoing all operations, allowing the reversal of all user actions and restoring the document to its original state. Please refer to the example:
async function undoAllExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
Although all operations have been undone, they can still be redone step by step.
# Record operations
The UndoRedoAddon also provides an invoke
method, through which a callback function can be passed. This function accepts a PDFDoc (opens new window) object, which is a wrapped object. The difference between this wrapped PDFDoc and an unwrapped one is that it can record operations, and these recorded operations can be undone and redone.
Here is a simple example, where we record the operations of creating and modifying annotations within the callback function. After these operations have been recorded, we can also undo and redo them using the undo/redo
APIs:
function wait() {
// The purpose of this function is to pause for a certain amount of time after each step is executed, making it easier to observe the results.
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, // Initialize the border color to red.
});
await wait();
// Set the border color to purple after creation is completed.
await square.setBorderColor(0xff00ff);
});
await wait();
// After undoing, the color reverts back to red.
await undoRedoAddon.undo();
await wait();
// After redoing, the color changes to purple.
await undoRedoAddon.redo();
await wait();
// Undo all, the square annotation will be deleted.
await undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# List of APIs supporting Undo/Redo
The following lists the APIs that Foxit PDF SDK for Web currently supports for undo and redo operations.
# Supported object retrieval APIs
Here is a series of APIs that, when called within the UIXAddon.invoke
callback function, return a wrapped object. Developers can use the methods on this wrapped object to record operations:
- PDFDoc (opens new window)
PDFDoc.getPageByIndex(index)
: Get a page in the document by its index.PDFDoc.getPageById(id)
: Get a page using its unique identifier.PDFDoc.getAnnots()
: Get all annotations in the document.
- PDFPage (opens new window)
PDFPage.getAnnots()
: Get all annotations on a page.PDFPage.getAnnotsByObjectNumArray(objectNums)
: Get annotations on a page using an array of object numbers.PDFPage.getAnnotsByIdArray(annotIds)
: Get annotations on a page using an array of annotation identifiers.PDFPage.getMarkupAnnots()
: Get markup annotations on a page.PDFPage.getAnnotTree()
: Get the tree structure of annotations on a page.
Example:
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.");
}
}
# Supported operation APIs
After these APIs are called, their operations will be automatically recorded, and the recorded operations can be undone and redone. It is important to note that these APIs must be called on the objects returned by the object retrieval APIs listed in the previous paragraph.
- PDFDoc (opens new window)
PDFDoc.addAnnot
- PDFPage (opens new window)
PDFPage.addAnnot
PDFPage.removeAnnotById
PDFPage.removeAnnotByObjectNumber
- Annot (opens new window) (All annotation classes' superclass):
Annot.setContent
Annot.setRect
Annot.setBorderColor
Annot.setBorderInfo
Annot.setFlags
- Markup (opens new window) (All Markup annotation classes' superclass, including FreeText(callout, textbox, typewriter), ink, line, note, polygon, polyline, redact, sound, square, stamp and TextMarkup(highlight, squiggly, strikeout, underline)):
Markup.setOpacity
Markup.setSubject
Markup.setTitle
Markup.addReply
Markup.addReviewState
Markup.addMarkedState
Markup.setFillColor
- Specific annotation types:
- Circle (opens new window)
Circle.setMeasureRatio
Circle.setMeasureUnit
Circle.setMeasureConversionFactor
Circle.enableCaption
Circle.setCaptionColor
- Line (opens new window)
Line.setMeasureRatio
Line.setMeasureUnit
Line.enableCaption
Line.setCaptionColor
Line.setEndPoint
Line.setStartPoint
Line.setEndingStyle
Line.setStyleFillColor
Line.setLeaderLineExtend
Line.setLeaderLineOffset
Line.setLeaderLineLength
Line.setCaptionOffset
- Polygon (opens new window)
Polygon.enableCaption
Polygon.setCaptionColor
Polygon.updateVertexes
Polygon.setVertexes
- Polyline (opens new window)
Polyline.setMeasureRatio
Polyline.enableCaption
Polyline.setCaptionColor
Polyline.setEndingStyle
Polyline.setStyleFillColor
Polyline.updateVertexes
Polyline.setVertexes
- Square (opens new window)
Square.setMeasureRatio
Square.setMeasureUnit
Square.setMeasureConversionFactor
- FreeText (opens new window)(typewriter, textbox, callout)
FreeText.setAlignment
FreeText.setInnerRect
FreeText.setCalloutLinePoints
FreeText.setCalloutLineEndingStyle
FreeText.setDefaultAppearance
FreeText.setRotation
- Screen (opens new window)
Screen.setRotation
- Stamp (opens new window)
Stamp.setRotation
- Redact (opens new window)
Redact.setDefaultAppearance
Redact.setOverlayText
Redact.removeOvelayText
Redact.setOverlayTextAlignment
Redact.setRepeat
Redact.setAutoFontSize
Redact.setRedactApplyFillColor
- Ink (opens new window)
Ink.setInkList
- Link (opens new window)
Link.setHighlightingMode
Link.setAction
- FileAttachment (opens new window)
FileAttachment.setIconName
- Note (opens new window)
Note.setIconName
- Circle (opens new window)