# 可扩展组件与使用指南

本节提供了可扩展组件的详细信息和使用指南,列举了可扩展组件的扩展方法,并帮助开发者更好地理解和使用组件的自定义功能。在以下文档中,我们将首先介绍可扩展组件的概念以及使用 Component API 和 Fragment 配置来扩展它们的方法。然后,我们将提供一个详细的可扩展组件列表,以便开发者可以清楚地了解哪些组件可以被修改。

# 前置知识

为了更好地理解本文档,您可能需要先了解以下知识点:

  1. 关于 Fragment 配置: 请参阅 UI Fragments 小节。
  2. 关于 Appearance 的使用:请参阅 Appearance 小节。
  3. 关于布局模板:请参阅 布局模板 小节。
  4. 关于组件选择器语法: 请参阅 组件选择器 小节。
  5. 关于 Component API: 请参阅 API Reference (opens new window) 小节。
  6. 关于 @controller 指令: 请参阅 @controller 小节。
  7. 关于 @tooltip 指令: 请参阅 @tooltip 小节。
  8. 关于 @on 指令: 请参阅 @on 小节。

接下来的内容将运用上述提到的知识。在阅读本节之前,请先了解这些知识,这里将不再重复介绍。

# 可扩展组件概述

  1. 什么是可扩展组件:通过 Fragment 配置或 Component API,可以在功能和外观上进行自定义和扩展的组件。

  2. 什么是不可扩展组件:与可扩展组件相反,这些组件不能被修改。这些组件在 SDK 内部进行了深度封装,因此无法对其进行细粒度的拆解和组合。但是其中一些组件可以作为一个整体进行替换 (例如,Annotation 属性对话框)。后续章节将提供更多具体细节。

  3. 注意事项: 有些组件没有唯一的名称标识符,因此无法直接通过名称来指定目标组件。在这种情况下,可以使用 组件选择器语法

# 可扩展组件

# 头部区域

# 标签组件

标签组件放在名称为 toolbar-tabs 的 div 容器中,而标签面板放在名称为 toolbar-tab-bodies 的 div 容器中。如果要新增或删除标签,需要同时修改这两个容器中组件。以下是一个示例 (点击 run 按钮查看效果):

  1. 在末尾增加标签

    在这个示例中,我们在标签栏末尾插入了一个名为 custom-tab 的新标签,并同时插入了一个名为 fv--custom-tab-body 的 div 组件。

  2. 删除指定标签

    在这个示例中,我们删除了 edit-tabfv--edit-tab-paddle 两个组件,然后 edit 标签将不会在界面中显示。

  3. 替换指定标签

    在这个示例中,edit-tab 标签被替换为一个自定义标签。

  4. 在指定位置插入标签

    以下示例在指定位置之后插入一个自定义标签。类似地,还有一个 FRAGMENT_ACTION.BEFORE 操作,表示组件将插入到指定目标组件之前。

  5. 使用 Component API

    以下示例使用了选择器语法和 Component.after 接口,向页面中插入更多的标签组件。

    与使用 Fragment 配置编辑组件相比(其只能在初始化时编辑),使用 Component API 允许您在 PDFUI 初始化后的任何时候动态编辑组件。

# 标签面板组件

标签面板组件是在选择一个标签页后显示的面板。目前, SDK 默认的布局模板使用的标签面板组件都是 paddle 组件。使用这个组件的目的是在浏览器视图宽度较小时,可以在左右两侧显示按钮,用于滚动面板内的组件。

paddle 组件可以被视为一个普通的 ContainerComponent。您可以使用 Fragment 配置通过 FRAGMENT_ACTION.APPEND 操作将子组件插入到其中,或者使用 Component API 插入子组件。下面将举例进行说明。

  1. 使用 Fragment 配置插入组件

    该示例使用 Fragment 配置向 paddle 组件默认插入了一个手型按钮。

  2. 使用 Component API 插入组件

    该示例使用 Component API 插入一个手形按钮。效果与前一个示例相同。

在默认的布局模板中,我们在 paddle 组件中使用了 group-list 组件对子组件进行分组。在实际应用中,更常见的是对 group-list 组件进行编辑。以下示例将使用 group-listgroup 进行说明:

在此示例中,我们插入了一个新的 custom-group,其中 group 包含两个手形按钮组件,并设置在收缩后只显示一个组件。

# 标签面板中的按钮组件(ribbon-button)

ribbon-button 是一个功能强大的组件,可以作为普通按钮或下拉组件使用。首先探讨一下将 ribbon-button 作为普通按钮的自定义方法。

作为普通按钮,ribbon-button 组件可以通过以下方式进行自定义:

  1. 文本内容: 按钮上显示的文本内容。
  2. 图标: 按钮图标,通过 icon-class 属性指定,需要额外的 CSS 样式。
  3. 工具提示: 当鼠标悬停在按钮上时,通过 @tooltip 指令和 tooltip-title 属性实现显示的浮动工具提示内容。
  4. Controller: 通常用于业务实现,在自定义按钮上复用 SDK 内部实现逻辑。

以下是一个使用 SDK 内置 controller 实现业务逻辑复用的自定义按钮的示例:

从这个示例可以看出,在复用 controller 时,可以使用 @controller="" 指令来指定需要复用的 Controller。除了 states:HandController 以外,还有许多其它的 controller 可以被复用。更多详情,请参阅 Controllers 小节。

除了可以使用自定义按钮复用逻辑外,还可以直接修改 SDK 的内置组件。主要的方法是通过配置 Fragment 实现。例如,以下示例充分展示了如何自定义 hand-tool (ribbon-button) 的内容:

# 工具栏标签面板中的下拉 (dropdown) 组件

在工具栏上,dropdown 组件通常与 ribbon-button 组件一起使用。但是,也可以单独使用它。这两种使用方法之间的唯一区别是显示效果。以下是一个 ribbon-buttondropdown 配合使用的示例:

有关更多业务组件,您可以参阅 预配置组件 小节。本节描述了多个业务组件的默认配置,我们可以参考这些配置项使用 Fragment 配置来进行调整。

# 左侧面板

在默认布局中,左侧面板是使用 sidebar 组件构建的,其子组件对应不同业务模块封装的 sidebar-panel 组件。

在本节中,我们将学习左侧面板的一些自定义方式和细节。

# 创建一个 sidebar-panel

以下是一个包含基本属性的 sidebar-panel 组件模板:

<sidebar-panel
    class="custom-sidebar-panel"
    icon-class="custom-sidebar-icon"
    title="Custom"
>
</sidebar-panel>

如果需要,您可以向其添加一些指令,比如 @tooltip 指令:

<sidebar-panel
    class="custom-sidebar-panel"
    icon-class="custom-sidebar-icon"
    title="Custom"
    @tooltip
    tooltip-placement="right" 
    tooltip-title="Custom Sidebar"
>
</sidebar-panel>

如果您需要监听 active 事件(当 sidebar-panel 被展开时),您可以使用 @on.active 指令进行监听。请参考以下示例:

class CustomSidebarPanel extends SeniorComponentFactory.createSuperClass({
    template: `
    <sidebar-panel
        class="custom-sidebar-panel"
        icon-class="custom-sidebar-icon"
        title="Custom"
        @tooltip
        tooltip-placement="right" 
        tooltip-title="Custom Sidebar"
        @on.active="$component.handleActiveEvent()"
    >
    </sidebar-panel>
    `
}) {
    static getName() {
        return 'custom-sidebar-panel'
    }
    handleActiveEvent(){
        console.log('hello world')
    }
}

以下是一个可运行的示例:

# 删除一个 sidebar-panel

如果您想要删除 SDK 中内置的 sidebar-panel 组件,我们建议使用 Fragment 配置而不是 Component API 进行删除,除非确实有必要。这是因为初始化 sidebar-panel 组件可能需要比较多的资源,通过 Fragment 配置进行删除可以避免不必要的初始化。

{
    target: '@layer-sidebar-panel'action: UIExtension.UIConsts.FRAGMENT_ACTION.REMOVE
}

# 自定义 SDK 内置的 sidebar-panel 组件

# 1. commentlist-sidebar-panel

在 commentlist 侧边栏面板中,可以自定义 CommentCardComponent 和 ReplyCardComponent。但与其他组件不同的是,它们是根据文档中当前的注释类型和数量动态生成的,无法通过 Fragment 配置修改其细节。不过,我们提供了事件,允许您在组件创建或删除时获取组件对象,然后使用 Component API 修改这些组件的细节。

以下是相关的事件说明:

  1. UIExtension.UIEvents.appendCommentListComment: CommentCardComponent 组件被插入时触发,事件回调可以获取到 commentCardComponentannot 两个参数。

  2. UIExtension.UIEvents.destroyCommentListComment: CommentCardComponent 组件被销毁时触发,回调参数和 appendCommentListComment 事件相同

  3. UIExtension.UIEvents.appendCommentListReply: ReplyCardComponent 组件被插入时触发,事件回调可以获取到 replyCardComponentreplyAnnot 两个参数。

  4. UIExtension.UIEvents.destroyCommentListReply: ReplyCardComponent 组件被销毁时触发,回调参数和 appendCommentListReply 事件相同。

您可以参考 API Reference 以获取使用信息:

  1. CommentCardComponent (opens new window)
  2. ReplyCardComponent (opens new window)
# 2. thumbnail-sidebar-panel

关于 thumbnail-sidebar-panel,请参阅: 自定义缩略图

# 3. bookmark-sidebar-panel

关于 bookmark-sidebar-panel,请参阅:自定义书签

# 其它

除了上面提到的三个之外,layer-sidebar-panelattachment-sidebar-panelfield-sidebar-panel 目前暂未提供自定义功能。

# 右键菜单

右键菜单是指基于 ContextMenuComponent (opens new window) 实现的组件。所有可自定义的右键菜单都是基于相同原理实现的:

  1. 每个具有特定功能的右键菜单都有一个固定的名称,替换右键菜单需要通过指定名称实现。替换后,名称不可更改,因为这可能导致右键菜单无法显示或覆盖其他右键菜单,影响其他功能的菜单显示。

  2. 通过 Fragment 配置和 Component API,可以添加、删除和替换右键菜单项。

  3. 开头,末尾或者连续的 contextmenu-separator 分割线会自动隐藏,一般不需要特别对其做显示隐藏控制。

接下来,将逐一介绍每个功能模块的右键菜单。

# 1. PDF 页面右键菜单

请参阅 自定义页面右键菜单 小节。

# 2. Annotation 右键菜单

请参阅 自定义 Annotation 右键菜单 小节。

需要注意的是,由于 Annotation 属性对话框不支持自定义,因此在实现自定义属性对话框时,需要替换 <contextmenu-item-properties> 的实现。您可以参考以下示例:

# 3. 其它右键菜单

自定义其它右键菜单与上述的页面右键菜单和 Annotation 右键菜单类似。您可以参考这些文档进行自我扩展。相关的菜单组件模板可以参考 预配置组件 小节。

# 模态框

如果是 SDK 内部的弹出窗口,包括 alert、prompt、confirm 以及 loading 加载遮罩层,我们可以通过 Viewer UI 定义这些由 SDK 内部触发显示的组件。具体用法,请参阅 Viewer UI 小节。

# Controllers 复用

下面是一个使用 @controller 指令语法的列表,列举了当前 SDK 可复用的 controller 实现。其中冒号之前是模块名,冒号之后是 controller 名:

# UIExtension 内置 controller

内置 controller 可以直接通过 UIExtension.modular.module('module name').getController('controller name') 来获取类。

  1. states:HandController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_HAND
  2. marquee:MarqueeToolController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_MARQUEE
  3. loupe:LoupeController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_LOUPE
  4. states:SnapshotToolController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_SNAPSHOT_TOOL
  5. file:DownloadFileController: 用于下载当前打开的文档。
  6. zoom:ZoomInAndOutController: 控制文档视图缩放,需要与 action 属性搭配使用。可选值有:action="zoomin"action="zoomout"
  7. pagemode:SinglePageModeController: 切换页面模式为单页模式。
  8. pagemode:ContinuousPageModeController: 切换页面模式为连续页模式。
  9. pagemode:FacingPageModeController: 切换页面模式为对开模式。
  10. pagemode:ContinuousFacingPageModeController: 切换页面模式为连续对开模式。
  11. states:CreateTextController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_TEXT
  12. states:CreateFileAttachmentController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_FILE_ATTACHMENT
  13. states:CreateHighlightController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_HIGHLIGHT
  14. states:CreateStrikeoutController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_STRIKE_OUT
  15. states:CreateUnderlineController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_UNDERLINE
  16. states:CreateSquigglyController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_SQUIGGLY
  17. states:CreateReplaceController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_REPLACE
  18. states:CreateCaretController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_CARET
  19. states:CreateTypewriterController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_TYPEWRITER
  20. states:CreateCalloutController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_FREETEXT_CALLOUT
  21. states:CreateTextboxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_FREETEXT_BOX
  22. states:CreateAreaHighlightController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_AREA_HIGHLIGHT。
  23. states:CreatePencilController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.PENCIL
  24. states:EraserController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_ERASER
  25. states:CreateLinkController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_LINK
  26. states:CreateImageController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_IMAGE
  27. zoom:DropdownZoomInAndOutController: 和 zoom:ZoomInAndOutController 功能相同, 但是只能在 dropdown 子组件中使用。
  28. zoom:ZoomActionController: 控制文档视图缩放,与 zoom:ZoomInAndOutController 不同之处在于它需要指定目标缩放比例(非数字): action='fitHeight', action='fitWidth', action='fitVisible'
  29. gotoview:GotoFirstPageController: 跳转到第一页。
  30. gotoview:GotoPrevPageController: 跳转到上一页。
  31. gotoview:GotoNextPageController: 跳转到下一页。
  32. gotoview:GotoLastPageController: 跳转到最后一页。
  33. states:CreateSquareController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_SQUARE
  34. states:CreateCircleController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_CIRCLE
  35. states:CreatePolygonController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_POLYGON
  36. states:CreatePolygonCloudController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_POLYGON_CLOUD
  37. states:CreateArrowController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_ARROW
  38. states:CreateLineController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_LINE
  39. states:CreatePolylineController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_POLYLINE
  40. distance:CreateDistanceController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_DISTANCE
  41. distance:CreatePerimeterController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_PERIMETER
  42. distance:CreateAreaController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_AREA
  43. distance:CreateCircleAreaController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.STATE_HANDLER_CREATE_CIRCLE_AREA
  44. comment-list:ExportCommentController: 将当前文档的注释导出为指定格式,格式由 format 属性指定:format="XFDF", 支持 XFDF, FDF, JSON 三种格式。
  45. text-sel:CopySelectedTextController: 复制选中文本。
  46. text-sel:CreateTextHighlightOnSelectedTextController: 在选中的文本范围内创建文本高亮注释。
  47. text-sel:CreateStrikeoutOnSelectedTextController: 在选中的文本范围内创建 Strikeout 注释。
  48. text-sel:CreateUnderlineOnSelectedTextController: 在选中的文本范围内创建 Underline 注释。
  49. text-sel:CreateBookmarkOnSelectedTextController: 将选中的文本添加到书签列表中。
  50. states:RibbonSelectTextImageController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_SELECT_TEXT_IMAGE
  51. states:RibbonSelectTextAnnotationController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_SELECT_ANNOTATION
  52. change-color:ChangeColorController: 用于切换文档背景色。
  53. comment-list:ImportCommentButtonController: 用于向文档中导入注释数据。
  54. states:SelectTextImageController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_SELECT_TEXT_IMAGE
  55. states:SelectAnnotationController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_SELECT_ANNOTATION
  56. zoom:ContextMenuZoomActionController: 控制文档视图缩放,并需要指定 action 属性。可选值有:fitWidth, fitHeight, fitVisible 以及数字。
  57. ui-rotation:RotateRightController: 控制文档视图向右旋转90度。
  58. ui-rotation:RotateLeftController: 控制文档视图向左旋转90度。
  59. annot-opr:ShowAnnotReplyController: 用于打开左侧栏 commentlist 面板,定位所选注释,并聚焦到回复输入框。
  60. annot-opr:DeleteAnnotController: 删除选中的注释。
  61. annot-opr:ShowAnnotPropertiesController: 显示注释属性对话框。
  62. annot-opr:SetPropsDefault: 将当前注释属性设置为默认属性,用户下次创建注释时将使用该默认值。

# UIExtension Addon 中的 controller

获取 Addons 中的 controller class 和获取 UIExtension 中内置 controller class 的方法相同,但是请确保这些 Addons 在获取之前已经加载完成。

  1. page-template addon:
    1. page-template:ShowPageTemplateDialogController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER
  2. form-designer addon:
    1. form-designer:CreatePushButtonController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_PUSH_BUTTON
    2. form-designer:CreateCheckBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_CHECK_BOX
    3. form-designer:CreateRadioButtonController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_RADIO_BUTTON
    4. form-designer:CreateComboBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_COMBO_BOX
    5. form-designer:CreateListBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_LIST_BOX
    6. form-designer:CreateTextController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_TEXT
    7. form-designer:CreateSignController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_SIGNATURE
    8. form-designer:CreateImageController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_IMAGE
    9. form-designer:CreateDateController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER_CREATE_FIELD_DATE
  3. page-editor addon:
    1. page-editor:EditObjectController: 切换当前 StateHandler 为 "页面对象编辑" 工具,页面对象包含文本、图像、形状和渐变。
    2. page-editor:AddImageAdvController: 切换当前 StateHandler 为 "从文件添加图像" 工具。
    3. page-editor:AddShapesController: 切换当前 StateHandler 为 "创建图形" 工具。
    4. page-editor:AddTextController: 切换当前 StateHandler 为 "添加文本" 工具。
  4. fullscreen addon:
    1. full-screen:FullscreenController: 切换全屏模式。
  5. print addon:
    1. print:ShowPrintDialogController: 显示打印对话框。
  6. file-property addon:
    1. fpmodule:FileInfoCallbackController: 显示文档属性对话框。
  7. h-continuous addon:
    1. h-continuous:HContinuousViewModeController: 切换页面模式为横向连续页模式。
  8. export-form addon:
    1. export-form-module:ExportToXMLController: 将当前文档的表单导出为 XML 格式文件。
    2. export-form-module:ExportToFDFController: 将当前文档的表单导出为 FDF 格式文件。
    3. export-form-module:ExportToXFDFController: 将当前文档的表单导出为 XFDF 格式文件。
    4. export-form-module:ExportToCSVController: 将当前文档的表单导出为 CSV 格式文件。
    5. export-form-module:ExportToTXTController: 将当前文档的表单导出为 TXT 格式文件。
  9. comparison addon:
    1. comparison:ShowCompareFileDialogButtonController: 显示文档对比对话框。
  10. redaction addon:
    1. redaction:RedactionTextAndImageController: 切换当前 StateHandler 为创建标记文本、图像的 Redaction 工具。
    2. redaction:RedactionController: 切换当前 StateHandler 为创建标记区域的 Redaction 工具。
    3. redaction:RedactionPageController: 切换当前 StateHandler 为创建标记页面的 Redaction 工具。

通过这些 controller,我们可以在重写组件的同时复用 SDK 内置的实现逻辑。以 states:HandController 为例,其允许将当前的 StateHandler 工具切换为手型工具,并且可以判断当前是否为手型工具来激活/取消激活组件:

当然, 并非所有的 controller 都像 states:HandController 那样简单。以下列出了几个比较特殊的 controller,在使用它们的时候,要按照示例中提供的方法使用: