diff --git a/src/editor/assets/css/contextmenu/contextmenu.css b/src/editor/assets/css/contextmenu/contextmenu.css
index 8ad16bc..dc6a7af 100644
--- a/src/editor/assets/css/contextmenu/contextmenu.css
+++ b/src/editor/assets/css/contextmenu/contextmenu.css
@@ -145,4 +145,16 @@
.ce-contextmenu-vertical-align-bottom {
background-image: url(../../../assets/images/vertical-align-bottom.svg);
+}
+
+.ce-contextmenu-border-all {
+ background-image: url(../../../assets/images/table-border-all.svg);
+}
+
+.ce-contextmenu-border-empty {
+ background-image: url(../../../assets/images/table-border-empty.svg);
+}
+
+.ce-contextmenu-border-external {
+ background-image: url(../../../assets/images/table-border-external.svg);
}
\ No newline at end of file
diff --git a/src/editor/assets/images/table-border-all.svg b/src/editor/assets/images/table-border-all.svg
new file mode 100644
index 0000000..338ae14
--- /dev/null
+++ b/src/editor/assets/images/table-border-all.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/editor/assets/images/table-border-empty.svg b/src/editor/assets/images/table-border-empty.svg
new file mode 100644
index 0000000..4a6baa6
--- /dev/null
+++ b/src/editor/assets/images/table-border-empty.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/editor/assets/images/table-border-external.svg b/src/editor/assets/images/table-border-external.svg
new file mode 100644
index 0000000..2ad564f
--- /dev/null
+++ b/src/editor/assets/images/table-border-external.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts
index c5a3085..7803eb2 100644
--- a/src/editor/core/command/Command.ts
+++ b/src/editor/core/command/Command.ts
@@ -1,4 +1,4 @@
-import { IElement, ImageDisplay, INavigateInfo, VerticalAlign } from '../..'
+import { IElement, ImageDisplay, INavigateInfo, TableBorder, VerticalAlign } from '../..'
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
import { RowFlex } from '../../dataset/enum/Row'
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
@@ -49,6 +49,7 @@ export class Command {
private static mergeTableCell: CommandAdapt['mergeTableCell']
private static cancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
private static tableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
+ private static tableBorderType: CommandAdapt['tableBorderType']
private static image: CommandAdapt['image']
private static hyperlink: CommandAdapt['hyperlink']
private static deleteHyperlink: CommandAdapt['deleteHyperlink']
@@ -124,6 +125,7 @@ export class Command {
Command.mergeTableCell = adapt.mergeTableCell.bind(adapt)
Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
Command.tableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
+ Command.tableBorderType = adapt.tableBorderType.bind(adapt)
Command.image = adapt.image.bind(adapt)
Command.hyperlink = adapt.hyperlink.bind(adapt)
Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt)
@@ -323,6 +325,10 @@ export class Command {
return Command.tableTdVerticalAlign(payload)
}
+ public executeTableBorderType(payload: TableBorder) {
+ return Command.tableBorderType(payload)
+ }
+
public executeHyperlink(payload: IElement) {
return Command.hyperlink(payload)
}
diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts
index e17161c..7e9d33d 100644
--- a/src/editor/core/command/CommandAdapt.ts
+++ b/src/editor/core/command/CommandAdapt.ts
@@ -6,6 +6,7 @@ import { EditorContext, EditorMode, PageMode, PaperDirection } from '../../datas
import { ElementType } from '../../dataset/enum/Element'
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
import { RowFlex } from '../../dataset/enum/Row'
+import { TableBorder } from '../../dataset/enum/table/Table'
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
import { IEditorOption, IEditorResult } from '../../interface/Editor'
@@ -1032,9 +1033,9 @@ export class CommandAdapt {
const element = originalElementList[index!]
const curTd = element?.trList?.[trIndex!]?.tdList?.[tdIndex!]
if (
- !curTd
- || curTd.verticalAlign === payload
- || (!curTd.verticalAlign && payload === VerticalAlign.TOP)
+ !curTd ||
+ curTd.verticalAlign === payload ||
+ (!curTd.verticalAlign && payload === VerticalAlign.TOP)
) {
return
}
@@ -1046,6 +1047,27 @@ export class CommandAdapt {
})
}
+ public tableBorderType(payload: TableBorder) {
+ const isReadonly = this.draw.isReadonly()
+ if (isReadonly) return
+ const positionContext = this.position.getPositionContext()
+ if (!positionContext.isTable) return
+ const { index } = positionContext
+ const originalElementList = this.draw.getOriginalElementList()
+ const element = originalElementList[index!]
+ if (
+ (!element.borderType && payload === TableBorder.ALL) ||
+ element.borderType === payload
+ ) {
+ return
+ }
+ element.borderType = payload
+ const { endIndex } = this.range.getRange()
+ this.draw.render({
+ curIndex: endIndex
+ })
+ }
+
public hyperlink(payload: IElement) {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
diff --git a/src/editor/core/contextmenu/menus/tableMenus.ts b/src/editor/core/contextmenu/menus/tableMenus.ts
index 0aa15f8..73a7934 100644
--- a/src/editor/core/contextmenu/menus/tableMenus.ts
+++ b/src/editor/core/contextmenu/menus/tableMenus.ts
@@ -1,4 +1,5 @@
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
+import { TableBorder } from '../../../dataset/enum/table/Table'
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
import { Command } from '../../command/Command'
@@ -6,6 +7,39 @@ export const tableMenus: IRegisterContextMenu[] = [
{
isDivider: true
},
+ {
+ i18nPath: 'contextmenu.table.border',
+ icon: 'border-all',
+ when: (payload) => {
+ return !payload.isReadonly && payload.isInTable
+ },
+ childMenus: [
+ {
+ i18nPath: 'contextmenu.table.borderAll',
+ icon: 'border-all',
+ when: () => true,
+ callback: (command: Command) => {
+ command.executeTableBorderType(TableBorder.ALL)
+ }
+ },
+ {
+ i18nPath: 'contextmenu.table.borderEmpty',
+ icon: 'border-empty',
+ when: () => true,
+ callback: (command: Command) => {
+ command.executeTableBorderType(TableBorder.EMPTY)
+ }
+ },
+ {
+ i18nPath: 'contextmenu.table.borderExternal',
+ icon: 'border-external',
+ when: () => true,
+ callback: (command: Command) => {
+ command.executeTableBorderType(TableBorder.EXTERNAL)
+ }
+ }
+ ]
+ },
{
i18nPath: 'contextmenu.table.verticalAlign',
icon: 'vertical-align',
diff --git a/src/editor/core/draw/particle/table/TableParticle.ts b/src/editor/core/draw/particle/table/TableParticle.ts
index 9444b75..180ab45 100644
--- a/src/editor/core/draw/particle/table/TableParticle.ts
+++ b/src/editor/core/draw/particle/table/TableParticle.ts
@@ -1,8 +1,17 @@
-import { ElementType, IElement } from '../../../..'
+import { ElementType, IElement, TableBorder } from '../../../..'
import { IEditorOption } from '../../../../interface/Editor'
import { RangeManager } from '../../../range/RangeManager'
import { Draw } from '../../Draw'
+interface IDrawTableBorderOption {
+ ctx: CanvasRenderingContext2D;
+ startX: number;
+ startY: number;
+ width: number;
+ height: number;
+ isDrawFullBorder?: boolean;
+}
+
export class TableParticle {
private range: RangeManager
@@ -13,14 +22,19 @@ export class TableParticle {
this.options = draw.getOptions()
}
- private _drawBorder(ctx: CanvasRenderingContext2D, startX: number, startY: number, width: number, height: number) {
+ private _drawBorder(payload: IDrawTableBorderOption) {
+ const { ctx, startX, startY, width, height, isDrawFullBorder } = payload
ctx.beginPath()
const x = Math.round(startX)
const y = Math.round(startY)
ctx.translate(0.5, 0.5)
- ctx.moveTo(x, y + height)
- ctx.lineTo(x, y)
- ctx.lineTo(x + width, y)
+ if (isDrawFullBorder) {
+ ctx.rect(x, y, width, height)
+ } else {
+ ctx.moveTo(x, y + height)
+ ctx.lineTo(x, y)
+ ctx.lineTo(x + width, y)
+ }
ctx.stroke()
ctx.translate(-0.5, -0.5)
}
@@ -159,31 +173,41 @@ export class TableParticle {
}
public render(ctx: CanvasRenderingContext2D, element: IElement, startX: number, startY: number) {
- const { colgroup, trList } = element
- if (!colgroup || !trList) return
+ const { colgroup, trList, borderType } = element
+ if (!colgroup || !trList || borderType === TableBorder.EMPTY) return
const { scale } = this.options
const tableWidth = element.width! * scale
const tableHeight = element.height! * scale
+ const isExternalBorderType = borderType === TableBorder.EXTERNAL
ctx.save()
// 渲染边框
- this._drawBorder(ctx, startX, startY, tableWidth, tableHeight)
- // 渲染表格
- for (let t = 0; t < trList.length; t++) {
- const tr = trList[t]
- for (let d = 0; d < tr.tdList.length; d++) {
- const td = tr.tdList[d]
- const width = td.width! * scale
- const height = td.height! * scale
- const x = Math.round(td.x! * scale + startX + width)
- const y = Math.round(td.y! * scale + startY)
- ctx.translate(0.5, 0.5)
- // 绘制线条
- ctx.beginPath()
- ctx.moveTo(x, y)
- ctx.lineTo(x, y + height)
- ctx.lineTo(x - width, y + height)
- ctx.stroke()
- ctx.translate(-0.5, -0.5)
+ this._drawBorder({
+ ctx,
+ startX,
+ startY,
+ width: tableWidth,
+ height: tableHeight,
+ isDrawFullBorder: isExternalBorderType
+ })
+ if (!isExternalBorderType) {
+ // 渲染表格
+ for (let t = 0; t < trList.length; t++) {
+ const tr = trList[t]
+ for (let d = 0; d < tr.tdList.length; d++) {
+ const td = tr.tdList[d]
+ const width = td.width! * scale
+ const height = td.height! * scale
+ const x = Math.round(td.x! * scale + startX + width)
+ const y = Math.round(td.y! * scale + startY)
+ ctx.translate(0.5, 0.5)
+ // 绘制线条
+ ctx.beginPath()
+ ctx.moveTo(x, y)
+ ctx.lineTo(x, y + height)
+ ctx.lineTo(x - width, y + height)
+ ctx.stroke()
+ ctx.translate(-0.5, -0.5)
+ }
}
}
ctx.restore()
diff --git a/src/editor/core/i18n/lang/en.json b/src/editor/core/i18n/lang/en.json
index e3c4f90..7c03137 100644
--- a/src/editor/core/i18n/lang/en.json
+++ b/src/editor/core/i18n/lang/en.json
@@ -39,7 +39,11 @@
"verticalAlign": "Vertical align",
"verticalAlignTop": "Top",
"verticalAlignMiddle": "Middle",
- "verticalAlignBottom": "Bottom"
+ "verticalAlignBottom": "Bottom",
+ "border": "Table border",
+ "borderAll": "All",
+ "borderEmpty": "Empty",
+ "borderExternal": "External"
}
},
"datePicker": {
diff --git a/src/editor/core/i18n/lang/zh-CN.json b/src/editor/core/i18n/lang/zh-CN.json
index c81bc3d..7c69215 100644
--- a/src/editor/core/i18n/lang/zh-CN.json
+++ b/src/editor/core/i18n/lang/zh-CN.json
@@ -39,7 +39,11 @@
"verticalAlign": "垂直对齐",
"verticalAlignTop": "顶端对齐",
"verticalAlignMiddle": "垂直居中",
- "verticalAlignBottom": "底端对齐"
+ "verticalAlignBottom": "底端对齐",
+ "border": "表格边框",
+ "borderAll": "所有框线",
+ "borderEmpty": "无框线",
+ "borderExternal": "外侧框线"
}
},
"datePicker": {
diff --git a/src/editor/dataset/constant/Element.ts b/src/editor/dataset/constant/Element.ts
index da40daf..f3d4946 100644
--- a/src/editor/dataset/constant/Element.ts
+++ b/src/editor/dataset/constant/Element.ts
@@ -43,6 +43,7 @@ export const EDITOR_ELEMENT_ZIP_ATTR: Array = [
'rowMargin',
'dashArray',
'trList',
+ 'borderType',
'width',
'height',
'url',
diff --git a/src/editor/dataset/enum/table/Table.ts b/src/editor/dataset/enum/table/Table.ts
new file mode 100644
index 0000000..a1dc22d
--- /dev/null
+++ b/src/editor/dataset/enum/table/Table.ts
@@ -0,0 +1,5 @@
+export enum TableBorder {
+ ALL = 'all',
+ EMPTY = 'empty',
+ EXTERNAL = 'external'
+}
\ No newline at end of file
diff --git a/src/editor/index.ts b/src/editor/index.ts
index f7d7041..529c9c9 100644
--- a/src/editor/index.ts
+++ b/src/editor/index.ts
@@ -34,6 +34,7 @@ import { defaultCursorOption } from './dataset/constant/Cursor'
import { IPageNumber } from './interface/PageNumber'
import { defaultPageNumberOption } from './dataset/constant/PageNumber'
import { VerticalAlign } from './dataset/enum/VerticalAlign'
+import { TableBorder } from './dataset/enum/table/Table'
export default class Editor {
@@ -175,7 +176,8 @@ export {
Command,
KeyMap,
BlockType,
- PaperDirection
+ PaperDirection,
+ TableBorder
}
// 对外类型
diff --git a/src/editor/interface/Element.ts b/src/editor/interface/Element.ts
index bdd3ead..5dba458 100644
--- a/src/editor/interface/Element.ts
+++ b/src/editor/interface/Element.ts
@@ -1,6 +1,7 @@
import { ControlComponent, ImageDisplay } from '../dataset/enum/Control'
import { ElementType } from '../dataset/enum/Element'
import { RowFlex } from '../dataset/enum/Row'
+import { TableBorder } from '../dataset/enum/table/Table'
import { IBlock } from './Block'
import { ICheckbox } from './Checkbox'
import { IControl } from './Control'
@@ -32,6 +33,7 @@ export interface IElementStyle {
export interface ITableAttr {
colgroup?: IColgroup[];
trList?: ITr[];
+ borderType?: TableBorder;
}
export interface ITableElement {
@@ -40,14 +42,14 @@ export interface ITableElement {
tableId?: string;
}
+export type ITable = ITableAttr & ITableElement
+
export interface IHyperlinkElement {
valueList?: IElement[];
url?: string;
hyperlinkId?: string;
}
-export type ITable = ITableAttr & ITableElement
-
export interface ISuperscriptSubscript {
actualSize?: number;
}
diff --git a/src/main.ts b/src/main.ts
index c6e0bf7..6eed966 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1182,4 +1182,4 @@ window.onload = function () {
}
])
-}
+}
\ No newline at end of file