feat: apply style to entire table #232
This commit is contained in:
@@ -419,6 +419,16 @@ Usage:
|
||||
instance.command.executeTableTdBackgroundColor(payload: string)
|
||||
```
|
||||
|
||||
## executeTableSelectAll
|
||||
|
||||
Feature: Select the entire table
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
instance.command.executeTableSelectAll()
|
||||
```
|
||||
|
||||
## executeImage
|
||||
|
||||
Feature: Insert a picture
|
||||
|
||||
@@ -419,6 +419,16 @@ instance.command.executeTableBorderType(payload: TableBorder)
|
||||
instance.command.executeTableTdBackgroundColor(payload: string)
|
||||
```
|
||||
|
||||
## executeTableSelectAll
|
||||
|
||||
功能:选中整个表格
|
||||
|
||||
用法:
|
||||
|
||||
```javascript
|
||||
instance.command.executeTableSelectAll()
|
||||
```
|
||||
|
||||
## executeImage
|
||||
|
||||
功能:插入图片
|
||||
|
||||
@@ -43,6 +43,7 @@ export class Command {
|
||||
public executeTableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
||||
public executeTableBorderType: CommandAdapt['tableBorderType']
|
||||
public executeTableTdBackgroundColor: CommandAdapt['tableTdBackgroundColor']
|
||||
public executeTableSelectAll: CommandAdapt['tableSelectAll']
|
||||
public executeImage: CommandAdapt['image']
|
||||
public executeHyperlink: CommandAdapt['hyperlink']
|
||||
public executeDeleteHyperlink: CommandAdapt['deleteHyperlink']
|
||||
@@ -133,6 +134,7 @@ export class Command {
|
||||
this.executeTableBorderType = adapt.tableBorderType.bind(adapt)
|
||||
this.executeTableTdBackgroundColor =
|
||||
adapt.tableTdBackgroundColor.bind(adapt)
|
||||
this.executeTableSelectAll = adapt.tableSelectAll.bind(adapt)
|
||||
this.executeImage = adapt.image.bind(adapt)
|
||||
this.executeHyperlink = adapt.hyperlink.bind(adapt)
|
||||
this.executeDeleteHyperlink = adapt.deleteHyperlink.bind(adapt)
|
||||
|
||||
@@ -195,7 +195,7 @@ export class CommandAdapt {
|
||||
public format() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.font = ''
|
||||
@@ -211,7 +211,7 @@ export class CommandAdapt {
|
||||
public font(payload: string) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.font = payload
|
||||
@@ -224,7 +224,7 @@ export class CommandAdapt {
|
||||
if (payload < minSize || payload > maxSize) return
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getTextLikeSelection()
|
||||
const selection = this.range.getTextLikeSelectionElementList()
|
||||
if (!selection || !selection.length) return
|
||||
let isExistUpdate = false
|
||||
selection.forEach(el => {
|
||||
@@ -245,7 +245,7 @@ export class CommandAdapt {
|
||||
public sizeAdd() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getTextLikeSelection()
|
||||
const selection = this.range.getTextLikeSelectionElementList()
|
||||
if (!selection || !selection.length) return
|
||||
const { defaultSize, maxSize } = this.options
|
||||
let isExistUpdate = false
|
||||
@@ -269,7 +269,7 @@ export class CommandAdapt {
|
||||
public sizeMinus() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getTextLikeSelection()
|
||||
const selection = this.range.getTextLikeSelectionElementList()
|
||||
if (!selection || !selection.length) return
|
||||
const { defaultSize, minSize } = this.options
|
||||
let isExistUpdate = false
|
||||
@@ -293,7 +293,7 @@ export class CommandAdapt {
|
||||
public bold() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const noBoldIndex = selection.findIndex(s => !s.bold)
|
||||
selection.forEach(el => {
|
||||
@@ -305,7 +305,7 @@ export class CommandAdapt {
|
||||
public italic() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const noItalicIndex = selection.findIndex(s => !s.italic)
|
||||
selection.forEach(el => {
|
||||
@@ -317,7 +317,7 @@ export class CommandAdapt {
|
||||
public underline() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const noUnderlineIndex = selection.findIndex(s => !s.underline)
|
||||
selection.forEach(el => {
|
||||
@@ -329,7 +329,7 @@ export class CommandAdapt {
|
||||
public strikeout() {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
|
||||
selection.forEach(el => {
|
||||
@@ -343,7 +343,7 @@ export class CommandAdapt {
|
||||
if (isReadonly) return
|
||||
const activeControl = this.control.getActiveControl()
|
||||
if (activeControl) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const superscriptIndex = selection.findIndex(
|
||||
s => s.type === ElementType.SUPERSCRIPT
|
||||
@@ -374,7 +374,7 @@ export class CommandAdapt {
|
||||
if (isReadonly) return
|
||||
const activeControl = this.control.getActiveControl()
|
||||
if (activeControl) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
const subscriptIndex = selection.findIndex(
|
||||
s => s.type === ElementType.SUBSCRIPT
|
||||
@@ -403,7 +403,7 @@ export class CommandAdapt {
|
||||
public color(payload: string) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.color = payload
|
||||
@@ -417,7 +417,7 @@ export class CommandAdapt {
|
||||
public highlight(payload: string) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const selection = this.range.getSelection()
|
||||
const selection = this.range.getSelectionElementList()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.highlight = payload
|
||||
@@ -505,20 +505,11 @@ export class CommandAdapt {
|
||||
if (isReadonly) return
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
if (!~startIndex && !~endIndex) return
|
||||
// 选区行信息
|
||||
const rangeRow = this.range.getRangeRow()
|
||||
if (!rangeRow) return
|
||||
const positionList = this.position.getPositionList()
|
||||
const elementList = this.draw.getElementList()
|
||||
// 当前选区所在行
|
||||
for (let p = 0; p < positionList.length; p++) {
|
||||
const position = positionList[p]
|
||||
const rowSet = rangeRow.get(position.pageNo)
|
||||
if (!rowSet) continue
|
||||
if (rowSet.has(position.rowNo)) {
|
||||
elementList[p].rowFlex = payload
|
||||
}
|
||||
}
|
||||
const rowElementList = this.range.getRangeRowElementList()
|
||||
if (!rowElementList) return
|
||||
rowElementList.forEach(element => {
|
||||
element.rowFlex = payload
|
||||
})
|
||||
// 光标定位
|
||||
const isSetCursor = startIndex === endIndex
|
||||
const curIndex = isSetCursor ? endIndex : startIndex
|
||||
@@ -530,20 +521,11 @@ export class CommandAdapt {
|
||||
if (isReadonly) return
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
if (!~startIndex && !~endIndex) return
|
||||
// 选区行信息
|
||||
const rangeRow = this.range.getRangeRow()
|
||||
if (!rangeRow) return
|
||||
const positionList = this.position.getPositionList()
|
||||
const elementList = this.draw.getElementList()
|
||||
// 当前选区所在行
|
||||
for (let p = 0; p < positionList.length; p++) {
|
||||
const position = positionList[p]
|
||||
const rowSet = rangeRow.get(position.pageNo)
|
||||
if (!rowSet) continue
|
||||
if (rowSet.has(position.rowNo)) {
|
||||
elementList[p].rowMargin = payload
|
||||
}
|
||||
}
|
||||
const rowElementList = this.range.getRangeRowElementList()
|
||||
if (!rowElementList) return
|
||||
rowElementList.forEach(element => {
|
||||
element.rowMargin = payload
|
||||
})
|
||||
// 光标定位
|
||||
const isSetCursor = startIndex === endIndex
|
||||
const curIndex = isSetCursor ? endIndex : startIndex
|
||||
@@ -1187,21 +1169,23 @@ export class CommandAdapt {
|
||||
public tableTdVerticalAlign(payload: VerticalAlign) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
const positionContext = this.position.getPositionContext()
|
||||
if (!positionContext.isTable) return
|
||||
const { index, trIndex, tdIndex } = positionContext
|
||||
const originalElementList = this.draw.getOriginalElementList()
|
||||
const element = originalElementList[index!]
|
||||
const curTd = element?.trList?.[trIndex!]?.tdList?.[tdIndex!]
|
||||
if (
|
||||
!curTd ||
|
||||
curTd.verticalAlign === payload ||
|
||||
(!curTd.verticalAlign && payload === VerticalAlign.TOP)
|
||||
) {
|
||||
return
|
||||
const rowCol = this.draw.getTableParticle().getRangeRowCol()
|
||||
if (!rowCol) return
|
||||
for (let r = 0; r < rowCol.length; r++) {
|
||||
const row = rowCol[r]
|
||||
for (let c = 0; c < row.length; c++) {
|
||||
const td = row[c]
|
||||
if (
|
||||
!td ||
|
||||
td.verticalAlign === payload ||
|
||||
(!td.verticalAlign && payload === VerticalAlign.TOP)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
// 重设垂直对齐方式
|
||||
td.verticalAlign = payload
|
||||
}
|
||||
}
|
||||
// 重设垂直对齐方式
|
||||
curTd.verticalAlign = payload
|
||||
const { endIndex } = this.range.getRange()
|
||||
this.draw.render({
|
||||
curIndex: endIndex
|
||||
@@ -1248,6 +1232,31 @@ export class CommandAdapt {
|
||||
})
|
||||
}
|
||||
|
||||
public tableSelectAll() {
|
||||
const positionContext = this.position.getPositionContext()
|
||||
const { index, tableId, isTable } = positionContext
|
||||
if (!isTable || !tableId) return
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
const originalElementList = this.draw.getOriginalElementList()
|
||||
const trList = originalElementList[index!].trList!
|
||||
// 最后单元格位置
|
||||
const endTrIndex = trList.length - 1
|
||||
const endTdIndex = trList[endTrIndex].tdList.length - 1
|
||||
this.range.replaceRange({
|
||||
startIndex,
|
||||
endIndex,
|
||||
tableId,
|
||||
startTdIndex: 0,
|
||||
endTdIndex,
|
||||
startTrIndex: 0,
|
||||
endTrIndex
|
||||
})
|
||||
this.draw.render({
|
||||
isCompute: false,
|
||||
isSubmitHistory: false
|
||||
})
|
||||
}
|
||||
|
||||
public hyperlink(payload: IElement) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
|
||||
@@ -56,6 +56,23 @@ export class RangeManager {
|
||||
return elementList.slice(startIndex + 1, endIndex + 1)
|
||||
}
|
||||
|
||||
public getSelectionElementList(): IElement[] | null {
|
||||
if (this.range.isCrossRowCol) {
|
||||
const rowCol = this.draw.getTableParticle().getRangeRowCol()
|
||||
if (!rowCol) return null
|
||||
const elementList: IElement[] = []
|
||||
for (let r = 0; r < rowCol.length; r++) {
|
||||
const row = rowCol[r]
|
||||
for (let c = 0; c < row.length; c++) {
|
||||
const col = row[c]
|
||||
elementList.push(...col.value)
|
||||
}
|
||||
}
|
||||
return elementList
|
||||
}
|
||||
return this.getSelection()
|
||||
}
|
||||
|
||||
public getTextLikeSelection(): IElement[] | null {
|
||||
const selection = this.getSelection()
|
||||
if (!selection) return null
|
||||
@@ -64,6 +81,14 @@ export class RangeManager {
|
||||
)
|
||||
}
|
||||
|
||||
public getTextLikeSelectionElementList(): IElement[] | null {
|
||||
const selection = this.getSelectionElementList()
|
||||
if (!selection) return null
|
||||
return selection.filter(
|
||||
s => !s.type || TEXTLIKE_ELEMENT_TYPE.includes(s.type)
|
||||
)
|
||||
}
|
||||
|
||||
// 获取光标所选位置行信息
|
||||
public getRangeRow(): RangeRowMap | null {
|
||||
const { startIndex, endIndex } = this.range
|
||||
@@ -84,6 +109,31 @@ export class RangeManager {
|
||||
return rangeRow
|
||||
}
|
||||
|
||||
// 获取光标所选位置元素列表
|
||||
public getRangeRowElementList(): IElement[] | null {
|
||||
const { startIndex, endIndex, isCrossRowCol } = this.range
|
||||
if (!~startIndex && !~endIndex) return null
|
||||
if (isCrossRowCol) {
|
||||
return this.getSelectionElementList()
|
||||
}
|
||||
// 选区行信息
|
||||
const rangeRow = this.getRangeRow()
|
||||
if (!rangeRow) return null
|
||||
const positionList = this.position.getPositionList()
|
||||
const elementList = this.draw.getElementList()
|
||||
// 当前选区所在行
|
||||
const rowElementList: IElement[] = []
|
||||
for (let p = 0; p < positionList.length; p++) {
|
||||
const position = positionList[p]
|
||||
const rowSet = rangeRow.get(position.pageNo)
|
||||
if (!rowSet) continue
|
||||
if (rowSet.has(position.rowNo)) {
|
||||
rowElementList.push(elementList[p])
|
||||
}
|
||||
}
|
||||
return rowElementList
|
||||
}
|
||||
|
||||
// 获取选取段落信息
|
||||
public getRangeParagraph(): RangeRowArray | null {
|
||||
const { startIndex, endIndex } = this.range
|
||||
|
||||
Reference in New Issue
Block a user