# 自定义 Annotation 右键菜单
本章节将介绍以下内容:
- 自定义Foxit PDF SDK for Web支持的 Annotation 的右键菜单
- 自定义Foxit PDF SDK for Web不支持的 Annotation 的右键菜单
- 隐藏右键菜单或者菜单项
- 显示自定义的右键菜单
# 自定义Foxit PDF SDK for Web支持的 Annotation 的右键菜单
Foxit PDF SDK for Web支持大部分的标准 Annotation 类型。每种类型的 Annotation 都有自己的右键菜单。以下列出了Foxit PDF SDK for Web支持的 Annotation 以及其对应的XML元素名称。
{
"line": "fv--line-contextmenu",
"linearrow": "fv--linearrow-contextmenu",
"linedimension": "fv--linedimension-contextmenu",
"polylinedimension": "fv--polylinedimension-contextmenu",
"polygondimension": "fv--polygondimension-contextmenu",
"circle": "fv--circle-contextmenu",
"square": "fv--square-contextmenu",
"polyline": "fv--polyline-contextmenu",
"polygon": "fv--polygon-contextmenu",
"polygoncloud": "fv--polygoncloud-contextmenu",
"fileattachment": "fv--fileattachment-contextmenu",
"freetexttypewriter": "fv--freetexttypewriter-contextmenu",
"typewriter": "fv--typewriter-contextmenu",
"freetextcallout": "fv--freetextcallout-contextmenu",
"callout": "fv--callout-contextmenu",
"freetexttextbox": "fv--freetexttextbox-contextmenu",
"textbox": "fv--textbox-contextmenu",
"freetext": "fv--freetext-contextmenu",
"ink": "fv--ink-contextmenu",
"stamp": "fv--stamp-contextmenu",
"text": "fv--text-contextmenu",
"areahighlight": "fv--areahighlight-contextmenu",
"highlight": "fv--highlight-contextmenu",
"caret": "fv--caret-contextmenu",
"replace": "fv--replace-contextmenu",
"squiggly": "fv--squiggly-contextmenu",
"strikeout": "fv--strikeout-contextmenu",
"redact": "fv--redact-contextmenu",
"underline": "fv--underline-contextmenu",
"media": "fv--media-contextmenu",
"image": "fv--image-contextmenu",
"link": "fv--link-contextmenu",
"sound": "fv--sound-contextmenu"
}
Annotation 元素名称可以通过UIExtension.XViewerUI中的 super.getAnnotsContextMenuName(owner)
函数获取。您可以参阅 自定义 viewerUI 小节中的代码示例。
如果要修改 annotation 右键菜单项,可以通过 Fragment 配置结合上述右键菜单名称进行修改,详情请参考下面的示例。
# 替换菜单项
new UIExtension.PDFUI({
appearance: UIExtension.appearances.AdaptiveAppearance.extend({
getDefaultFragments: function() {
return [{
target: 'fv--highlight-contextmenu',
action: UIExtension.UIConsts.FRAGMENT_ACTION.REPLACE,
template: `
<contextmenu name="fv--highlight-contextmenu">
<contextmenu-item-reply></contextmenu-item-reply>
<contextmenu-item-delete-annot></contextmenu-item-delete-annot>
<contextmenu-item-properties></contextmenu-item-properties>
<contextmenu-item name="x-user-custom-contextmenu-item">Custom </contextmenu-item>
</contextmenu>`,
config:[{
target: 'x-user-custom-contextmenu-item',
callback: function() {
alert('custom contextmenu item clicked!');
}
}]
}];
}
})
})
# 插入菜单项
new UIExtension.PDFUI({
appearance: UIExtension.appearances.AdaptiveAppearance.extend({
getDefaultFragments: function() {
return [{
target: 'fv--textbox-contextmenu',
action: UIExtension.UIConsts.FRAGMENT_ACTION.APPEND,
template: `
<contextmenu-item name="x-user-custom-contextmenu-item">Custom</contextmenu-item>
`,
config: [{
target: 'x-user-custom-contextmenu-item',
callback: function() {
alert('custom contextmenu item clicked!');
}
}]
}];
}
})
});
# 删除菜单项
new UIExtension.PDFUI({
appearance: UIExtension.appearances.AdaptiveAppearance.extend({
getDefaultFragments: function() {
return [{
target: 'fv--media-contextmenu>fv--contextmenu-item-media-download',
action: UIExtension.UIConsts.FRAGMENT_ACTION.REMOVE
}]
}
})
})
# 自定义 Foxit PDF SDK for Web 不支持的 Annotation 的右键菜单
不支持的 Annotation 是指不在上述支持列表中但已在PDF references中定义的 Annotation 。自定义Foxit PDF SDK for Web不支持的 Annotation 的右键菜单,您需要重写XViewUI中的getAnnotsContextMenuName方法,以创建一个新的上下文菜单并将其添加到template中。
如何快速检测当前 Annotation 是否是Foxit PDF SDK for Web所支持的 Annotation ,您可以检查其对应的元素名称,默认情况下支持的 Annotation 都被标记为 "fv--default-annot-contextmenu"。
以下示例假设当前PDF文件包含一个 'trapnet' Annotation ,该 Annotation 是Foxit PDF SDK for Web不支持的。以下代码展示了如何自定义其右键菜单。
new UIExtension.PDFUI({
viewerOptions: {
viewerUI: new class extends UIExtension.XViewerUI {
createContextMenu(owner, anchor, config) {
if(owner instanceof PDFViewCtrl.AnnotComponent) {
if(owner.annot.getType() === 'trapnet') {
return 'custom-trapnet-contextmenu-name';
}
}
return super.createContextMenu(owner, anchor, config);
}
} ()
},
appearance: UIExtension.appearances.AdaptiveAppearance.extend({
getDefaultFragments: function() {
return [{
target: 'template-container',
action: UIExtension.UIConsts.FRAGMENT_ACTION.APPEND,
template: `
<contextmenu name="custom-trapnet-contextmenu-name">
<contextmenu-item-reply></contextmenu-item-reply>
<contextmenu-item-delete-annot></contextmenu-item-delete-annot>
<contextmenu-item-properties></contextmenu-item-properties>
<contextmenu-item name="x-user-custom-contextmenu-item">Custom </contextmenu-item>
</contextmenu>
`,
config:[{
target: 'x-user-custom-contextmenu-item',
callback: function() {
alert('custom contextmenu item clicked!');
}
}]
}]
}
})
})
# 隐藏右键菜单或者菜单项
您可以使用以下方法中的一种来隐藏右键菜单或者菜单项。
# 1. 在fragments中配置一个类方法来强制隐藏
new UIExtension.PDFUI({
appearance: UIExtension.appearances.AdaptiveAppearance.extend({
getDefaultFragments: function() {
// the other options ...
return [{
target: 'fv--underline-contextmenu',
config: {
cls: 'fv__ui-force-hide'
}
}]
}
})
})
上述代码的作用是使 underline Annotation 的右键菜单被强制隐藏,这样右键点击 underline Annotation 就不再会有任何响应。
# 2. 自定义 viewerUI
new UIExtension.PDFUI({
viewerOptions: {
viewerUI: new class extends UIExtension.XViewerUI {
createContextMenu(owner, anchor, config) {
if(owner instanceof PDFViewCtrl.AnnotComponent) {
const contextMenuName = super.getAnnotsContextMenuName(owner)
if(contextMenuName === 'fv--underline-contextmenu'){
return;
}
}
return super.createContextMenu(owner, anchor, config);
}
} ()
}
});
此方法将在点击右键时隐藏内置菜单,而显示浏览器的默认菜单。
# 3. 重写AnnotComponent中的showContextMenu方法
const pdfui = new UIExtension.PDFUI({
// ....
});
pdfui.initializePromise.then(function () {
var annotMap = {};
pdfui.registerMatchRule(function(annot, AnnotComponentClass) {
let type = annot.getType();
var intent = annot.getIntent && annot.getIntent() || "default";
// You can add more annotation types
if(type === 'underline') {
return AnnotComponentClass;
}
if (annotMap[type] && annotMap[type][intent]) {
return annotMap[type][intent];
}
annotMap[type] = annotMap[type] || {};
return annotMap[type][intent] = (class extends AnnotComponentClass {
showContextMenu() {
// Do nothing
}
});
});
});
此方法将在点击右键时隐藏内置菜单,而显示浏览器的默认菜单。
# 显示自定义右键菜单组件
您需要重写viewerUI来显示自定义的右键菜单。
new UIExtension.PDFUI({
viewerOptions: {
viewerUI: new (class extends UIExtension.XViewerUI {
createContextMenu(owner, anchor, config) {
if (owner instanceof PDFViewCtrl.AnnotComponent) {
const contextMenuName = super.getAnnotsContextMenuName(owner);
if (contextMenuName === "fv--underline-contextmenu") {
return new (class extends PDFViewCtrl.IContextMenu {
constructor() {
super();
this.initContextmenu();
}
destroy() {
$(anchor).contextMenu("destroy");
}
showAt(x, y) {
$(anchor).contextMenu();
}
disable() {
super.disable();
$(anchor).contextMenu("destroy");
}
enable() {
super.enable();
this.initContextmenu();
}
initContextmenu() {
// The code example below requires referencing Jquery libraries including contextMenu.min.css, contextMenu.min.js and min.js.
$(anchor).contextMenu({
selector: config.selector,
items: [
{
name: 'show "Hello World"',
callback: function() {
alert("hello world");
}
},
{
name: 'show "Bye!"',
callback: function() {
alert("Bye!");
}
}
]
});
}
})();
}
}
return super.createContextMenu(owner, anchor, config);
}
})()
}
});
# Annotation 右键菜单匹配规则
在我们的默认布局模板中,可以看到这些 Annotation 相关的右键菜单组件:
<default-annot-contextmenu @lazy></default-annot-contextmenu>
<markup-contextmenu @lazy></markup-contextmenu>
<markup-contextmenu @lazy name="fv--line-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--linearrow-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--linedimension-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--polylinedimention-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--polygondimension-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--circle-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--square-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--polyline-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--polygon-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--polygoncloud-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--ink-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--stamp-contextmenu"></markup-contextmenu>
<markup-contextmenu @lazy name="fv--text-contextmenu"></markup-contextmenu>
<caret-contextmenu name="fv--areahighlight-contextmenu" @lazy></caret-contextmenu>
<caret-contextmenu name="fv--replace-contextmenu" @lazy></caret-contextmenu>
<measurement-contextmenu @lazy></measurement-contextmenu>
<caret-contextmenu name="fv--caret-contextmenu"></caret-contextmenu>
<textmarkup-contextmenu @lazy name="fv--highlight-contextmenu"></textmarkup-contextmenu>
<textmarkup-contextmenu @lazy name="fv--strikeout-contextmenu"></textmarkup-contextmenu>
<textmarkup-contextmenu @lazy name="fv--underline-contextmenu"></textmarkup-contextmenu>
<textmarkup-contextmenu @lazy name="fv--squiggly-contextmenu"></textmarkup-contextmenu>
<freetext-contextmenu @lazy name="fv--typewriter-contextmenu"></freetext-contextmenu>
<freetext-contextmenu @lazy name="fv--callout-contextmenu"></freetext-contextmenu>
<freetext-contextmenu @lazy name="fv--textbox-contextmenu"></freetext-contextmenu>
<action-annot-contextmenu @lazy name="fv--image-contextmenu"></action-annot-contextmenu>
<action-annot-contextmenu @lazy name="fv--link-contextmenu"></action-annot-contextmenu>
<comment-card-contextmenu @lazy ></comment-card-contextmenu>
<fileattachment-contextmenu @lazy></fileattachment-contextmenu>
<media-contextmenu @lazy ></media-contextmenu>
<sound-contextmenu @lazy ></sound-contextmenu>
<redact-contextmenu @lazy ></redact-contextmenu>
可以观察到,在开头的 <default-annot-contextmenu>
和 <markup-contextmenu>
中,如果某个注释类型无法在当前布局模板中精确匹配到右键菜单,将会根据以下规则匹配默认右键菜单:
- 如果该注释属于 Markup Annotation,则会匹配到
<markup-contextmenu>
; - 如果布局模板中也没有
<markup-context>
,或者该注释不属于标记注释,那么将会匹配到<default-annot-contextmenu>
。
最终用户将看到的右键菜单将以最后匹配到的为准。如果布局模板中没有定义任何右键菜单,则触发 Annotation 右键点击时,则会显示 PDFViewCtrl 层定义的菜单,如果不想在 Annotation 上显示任何菜单, 则请参考 自定义 ViewerUI 一节。