# 可扩展组件与使用指南

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

# 前置知识

为了更好地阅读本文,您可能需要先了解这些知识点:

  1. 关于 Fragment 配置: 请参考这篇文章
  2. 关于 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. 注意事项: 有些组件没有唯一的名称标识符,无法直接通过名称来指定目标组件,这时候可以使用组件选择语法

# 可扩展组件

# 头部区域

# 1. 标签组件

标签组件放在名称为 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 初始化之后的任意时机动态编辑组件。

# 2. 标签面板组件

标签面板组件是标签页选中后显示的面板,目前, 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 中有两个手型按钮组件,并且设置收缩后只保留一个组件显示。

# 3. 标签面板中的按钮组件(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) 可自定义内容:

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

在工具栏上, dropdown 组件通常是配合 ribbon-button 组件使用, 当然,你也可以单独使用, 这两种使用方式唯一的区别就在于显示效果上, 下面是一个 ribbon-buttondropdown 配合使用例子:

还有更多的业务组件, 可以参考 pre configured components 一章, 这一章有描述了多个业务组件的默认配置,我们可以参考这些配置项使用 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 组件被插入时触发,事件回调可以获取到 commentCardComponent, annot 两个参数
  2. UIExtension.UIEvents.destroyCommentListComment: CommentCardComponent 组件被销毁时触发,回调参数和 appendCommentListComment 事件相同
  3. UIExtension.UIEvents.appendCommentListReply: ReplyCardComponent 组件被插入时触发,事件回调可以获取到 replyCardComponent, replyAnnot 两个参数
  4. UIExtension.UIEvents.destroyCommentListReply: ReplyCardComponent 组件被销毁时触发,回调参数和 appendCommentListReply 事件相同

用法可以参考 API Reference 信息:

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

可以参考这篇文章:customize-thumbnail-list

# 3. 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 属性对话框不支持自定义,因此在实现自定义属性对话框时需要替换掉 <contextmenu-item-properties> 的实现, 可以参考下面的例子:

# 3. 其它右键菜单

其它右键菜单自定义方式和上述 页面右键菜单和 Annotation 方法都差不多,可以参考这些文档自行扩展。相关的菜单组件模板可以参考 预配置组件 一章中的内容。

# 弹出框

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

# controllers 复用

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

  1. UIExtension 内置 controller

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

    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: 将当前注释属性设置为默认属性,用户下次创建注释时将使用该默认值
  2. UIExtension Addon 中的 controller

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

    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.
      2. form-designer:CreateCheckBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      3. form-designer:CreateRadioButtonController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      4. form-designer:CreateComboBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      5. form-designer:CreateListBoxController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      6. form-designer:CreateTextController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      7. form-designer:CreateSignController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      8. form-designer:CreateImageController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      9. form-designer:CreateDateController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      10. form-designer:showCODialogController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      11. form-designer:AddTooltipController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
      12. form-designer:ResetFormController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
    3. page-editor addon:
      1. page-editor:EditObjectController: 切换当前 StateHandler 为 “页面对象编辑” 工具,页面对象包含 文本、图像、形状、渐变这几种。
      2. page-editor:AddImageAdvController: 切换当前 StateHandler 为 “从文件添加图像” 工具
      3. page-editor:AddShapesController: 切换当前 StateHandler 为“创建图形”工具
      4. page-editor:AddTextController: 切换当前 StateHandler 为 “添加文本” 工具
      5. page-editor:AddTextController: 切换当前 StateHandler 为 STATE_HANDLER_NAMES.STATE_HANDLER.
    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, 我们在使用它们的时候,要按照示例中提供的方法使用: