feat: add executeLocationControl api #592
This commit is contained in:
@@ -912,6 +912,16 @@ Usage:
|
||||
instance.command.executeSetControlHighlight(payload: ISetControlHighlightOption)
|
||||
```
|
||||
|
||||
## executeLocationControl
|
||||
|
||||
Feature: Positioning and activating control
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
instance.command.executeLocationControl(controlId: string)
|
||||
```
|
||||
|
||||
## executeUpdateOptions
|
||||
|
||||
Feature: Update options
|
||||
|
||||
@@ -912,6 +912,16 @@ instance.command.executeSetControlProperties(payload: ISetControlProperties)
|
||||
instance.command.executeSetControlHighlight(payload: ISetControlHighlightOption)
|
||||
```
|
||||
|
||||
## executeLocationControl
|
||||
|
||||
功能:定位并激活控件
|
||||
|
||||
用法:
|
||||
|
||||
```javascript
|
||||
instance.command.executeLocationControl(controlId: string)
|
||||
```
|
||||
|
||||
## executeUpdateOptions
|
||||
|
||||
功能:修改配置
|
||||
|
||||
@@ -90,6 +90,7 @@ export class Command {
|
||||
public executeSetControlExtension: CommandAdapt['setControlExtension']
|
||||
public executeSetControlProperties: CommandAdapt['setControlProperties']
|
||||
public executeSetControlHighlight: CommandAdapt['setControlHighlight']
|
||||
public executeLocationControl: CommandAdapt['locationControl']
|
||||
public executeUpdateOptions: CommandAdapt['updateOptions']
|
||||
public executeInsertTitle: CommandAdapt['insertTitle']
|
||||
public getCatalog: CommandAdapt['getCatalog']
|
||||
@@ -236,5 +237,6 @@ export class Command {
|
||||
this.executeSetControlHighlight = adapt.setControlHighlight.bind(adapt)
|
||||
this.getControlValue = adapt.getControlValue.bind(adapt)
|
||||
this.getControlList = adapt.getControlList.bind(adapt)
|
||||
this.executeLocationControl = adapt.locationControl.bind(adapt)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
import { IElement, IElementStyle } from '../../interface/Element'
|
||||
import { IPasteOption } from '../../interface/Event'
|
||||
import { IMargin } from '../../interface/Margin'
|
||||
import { ILocationPosition } from '../../interface/Position'
|
||||
import { IRange, RangeContext, RangeRect } from '../../interface/Range'
|
||||
import { IColgroup } from '../../interface/table/Colgroup'
|
||||
import { ITd } from '../../interface/table/Td'
|
||||
@@ -2446,6 +2447,85 @@ export class CommandAdapt {
|
||||
return this.draw.getControl().getList()
|
||||
}
|
||||
|
||||
public locationControl(controlId: string) {
|
||||
function location(
|
||||
elementList: IElement[],
|
||||
zone: EditorZone
|
||||
): ILocationPosition | null {
|
||||
let i = 0
|
||||
while (i < elementList.length) {
|
||||
const element = elementList[i]
|
||||
i++
|
||||
if (element.type === ElementType.TABLE) {
|
||||
const trList = element.trList!
|
||||
for (let r = 0; r < trList.length; r++) {
|
||||
const tr = trList[r]
|
||||
for (let d = 0; d < tr.tdList.length; d++) {
|
||||
const td = tr.tdList[d]
|
||||
const locationContext = location(td.value, zone)
|
||||
if (locationContext) {
|
||||
return {
|
||||
...locationContext,
|
||||
positionContext: {
|
||||
isTable: true,
|
||||
index: i - 1,
|
||||
trIndex: r,
|
||||
tdIndex: d,
|
||||
tdId: element.tdId,
|
||||
trId: element.trId,
|
||||
tableId: element.tableId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (element?.controlId !== controlId) continue
|
||||
const curIndex = i - 1
|
||||
return {
|
||||
zone,
|
||||
range: {
|
||||
startIndex: curIndex,
|
||||
endIndex: curIndex
|
||||
},
|
||||
positionContext: {
|
||||
isTable: false
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
const data = [
|
||||
{
|
||||
zone: EditorZone.HEADER,
|
||||
elementList: this.draw.getHeaderElementList()
|
||||
},
|
||||
{
|
||||
zone: EditorZone.MAIN,
|
||||
elementList: this.draw.getOriginalMainElementList()
|
||||
},
|
||||
{
|
||||
zone: EditorZone.FOOTER,
|
||||
elementList: this.draw.getFooterElementList()
|
||||
}
|
||||
]
|
||||
for (const context of data) {
|
||||
const locationContext = location(context.elementList, context.zone)
|
||||
if (locationContext) {
|
||||
// 设置区域、上下文、光标信息
|
||||
this.setZone(locationContext.zone)
|
||||
this.position.setPositionContext(locationContext.positionContext)
|
||||
this.range.replaceRange(locationContext.range)
|
||||
this.draw.render({
|
||||
curIndex: locationContext.range.startIndex,
|
||||
isCompute: false,
|
||||
isSubmitHistory: false
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getContainer(): HTMLDivElement {
|
||||
return this.draw.getContainer()
|
||||
}
|
||||
|
||||
@@ -849,7 +849,9 @@ export class Control {
|
||||
for (const elementList of data) {
|
||||
getControlElementList(elementList)
|
||||
}
|
||||
return zipElementList(controlElementList)
|
||||
return zipElementList(controlElementList, {
|
||||
extraPickAttrs: ['controlId']
|
||||
})
|
||||
}
|
||||
|
||||
public recordBorderInfo(x: number, y: number, width: number, height: number) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IElement, ImageDisplay } from '..'
|
||||
import { IElement, ImageDisplay, IRange } from '..'
|
||||
import { EditorZone } from '../dataset/enum/Editor'
|
||||
import { IElementPosition } from './Element'
|
||||
import { IRow } from './Row'
|
||||
@@ -93,3 +93,9 @@ export interface IFloatPosition {
|
||||
tdValueIndex?: number
|
||||
zone?: EditorZone
|
||||
}
|
||||
|
||||
export interface ILocationPosition {
|
||||
zone: EditorZone
|
||||
range: IRange
|
||||
positionContext: IPositionContext
|
||||
}
|
||||
|
||||
+35
-14
@@ -487,12 +487,22 @@ export function isSameElementExceptValue(
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function pickElementAttr(payload: IElement): IElement {
|
||||
interface IPickElementOption {
|
||||
extraPickAttrs?: Array<keyof IElement>
|
||||
}
|
||||
export function pickElementAttr(
|
||||
payload: IElement,
|
||||
option: IPickElementOption = {}
|
||||
): IElement {
|
||||
const { extraPickAttrs } = option
|
||||
const zipAttrs = EDITOR_ELEMENT_ZIP_ATTR
|
||||
if (extraPickAttrs) {
|
||||
zipAttrs.push(...extraPickAttrs)
|
||||
}
|
||||
const element: IElement = {
|
||||
value: payload.value === ZERO ? `\n` : payload.value
|
||||
}
|
||||
EDITOR_ELEMENT_ZIP_ATTR.forEach(attr => {
|
||||
zipAttrs.forEach(attr => {
|
||||
const value = payload[attr] as never
|
||||
if (value !== undefined) {
|
||||
element[attr] = value
|
||||
@@ -501,7 +511,14 @@ export function pickElementAttr(payload: IElement): IElement {
|
||||
return element
|
||||
}
|
||||
|
||||
export function zipElementList(payload: IElement[]): IElement[] {
|
||||
interface IZipElementListOption {
|
||||
extraPickAttrs?: Array<keyof IElement>
|
||||
}
|
||||
export function zipElementList(
|
||||
payload: IElement[],
|
||||
options: IZipElementListOption = {}
|
||||
): IElement[] {
|
||||
const { extraPickAttrs } = options
|
||||
const elementList = deepClone(payload)
|
||||
const zipElementListData: IElement[] = []
|
||||
let e = 0
|
||||
@@ -541,7 +558,7 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
valueList.push(titleE)
|
||||
e++
|
||||
}
|
||||
titleElement.valueList = zipElementList(valueList)
|
||||
titleElement.valueList = zipElementList(valueList, options)
|
||||
element = titleElement
|
||||
}
|
||||
} else if (element.listId && element.listType) {
|
||||
@@ -569,7 +586,7 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
valueList.push(listE)
|
||||
e++
|
||||
}
|
||||
listElement.valueList = zipElementList(valueList)
|
||||
listElement.valueList = zipElementList(valueList, options)
|
||||
element = listElement
|
||||
}
|
||||
} else if (element.type === ElementType.TABLE) {
|
||||
@@ -599,7 +616,7 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
const zipTd: ITd = {
|
||||
colspan: td.colspan,
|
||||
rowspan: td.rowspan,
|
||||
value: zipElementList(td.value)
|
||||
value: zipElementList(td.value, options)
|
||||
}
|
||||
// 压缩单元格属性
|
||||
TABLE_TD_ZIP_ATTR.forEach(attr => {
|
||||
@@ -633,7 +650,7 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
valueList.push(hyperlinkE)
|
||||
e++
|
||||
}
|
||||
hyperlinkElement.valueList = zipElementList(valueList)
|
||||
hyperlinkElement.valueList = zipElementList(valueList, options)
|
||||
element = hyperlinkElement
|
||||
}
|
||||
} else if (element.type === ElementType.DATE) {
|
||||
@@ -656,7 +673,7 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
valueList.push(dateE)
|
||||
e++
|
||||
}
|
||||
dateElement.valueList = zipElementList(valueList)
|
||||
dateElement.valueList = zipElementList(valueList, options)
|
||||
element = dateElement
|
||||
}
|
||||
} else if (element.controlId) {
|
||||
@@ -675,7 +692,8 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
...pickObject(element, EDITOR_ROW_ATTR),
|
||||
type: ElementType.CONTROL,
|
||||
value: '',
|
||||
control
|
||||
control,
|
||||
controlId
|
||||
}
|
||||
const valueList: IElement[] = []
|
||||
while (e < elementList.length) {
|
||||
@@ -691,12 +709,12 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
}
|
||||
e++
|
||||
}
|
||||
controlElement.control!.value = zipElementList(valueList)
|
||||
element = controlElement
|
||||
controlElement.control!.value = zipElementList(valueList, options)
|
||||
element = pickElementAttr(controlElement, { extraPickAttrs })
|
||||
}
|
||||
}
|
||||
// 组合元素
|
||||
const pickElement = pickElementAttr(element)
|
||||
const pickElement = pickElementAttr(element, { extraPickAttrs })
|
||||
if (
|
||||
!element.type ||
|
||||
element.type === ElementType.TEXT ||
|
||||
@@ -708,7 +726,10 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
||||
e++
|
||||
if (
|
||||
nextElement &&
|
||||
isSameElementExceptValue(pickElement, pickElementAttr(nextElement))
|
||||
isSameElementExceptValue(
|
||||
pickElement,
|
||||
pickElementAttr(nextElement, { extraPickAttrs })
|
||||
)
|
||||
) {
|
||||
const nextValue =
|
||||
nextElement.value === ZERO ? '\n' : nextElement.value
|
||||
|
||||
Reference in New Issue
Block a user