Merge branch 'Hufe921:main' into main

pr675
lemon 2 years ago committed by GitHub
commit 4eab45fa3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -15,28 +15,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm i yarn -g
- run: yarn
- run: yarn run build
- run: mv dist canvas-editor
- name: Copy folder content recursively to remote
uses: garygrossgarten/github-action-scp@release
with:
local: canvas-editor
remote: ${{ secrets.PATH }}
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
rmRemote: true
- name: Executing remote ssh commands
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: sed -i 's/<\/body>/${{ secrets.SCRIPT }}<\/body>/g' ${{ secrets.PATH }}/index.html
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm i yarn -g
- run: yarn
- run: yarn run build
- run: mv dist canvas-editor
- name: Copy folder content recursively to remote
uses: appleboy/scp-action@v0.1.7
with:
source: canvas-editor
target: ${{ secrets.PATH }}
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
overwrite: true
- name: Executing remote ssh commands
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: sed -i 's/<\/body>/${{ secrets.SCRIPT }}<\/body>/g' ${{ secrets.PATH }}/canvas-editor/index.html

@ -4,6 +4,7 @@ on:
push:
branches: [main]
paths:
- '.github/workflows/docs.yml'
- 'docs/**'
jobs:
@ -11,21 +12,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm i yarn -g
- run: yarn
- run: yarn run docs:build
- run: mv ./docs/.vitepress/dist ./docs/.vitepress/canvas-editor-docs
- name: Copy folder content recursively to remote
uses: garygrossgarten/github-action-scp@release
with:
local: ./docs/.vitepress/canvas-editor-docs
remote: ${{ secrets.DOCS_PATH }}
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
rmRemote: true
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm i yarn -g
- run: yarn
- run: yarn run docs:build
- run: mv ./docs/.vitepress/dist ./docs/.vitepress/canvas-editor-docs
- name: Copy folder content recursively to remote
uses: appleboy/scp-action@v0.1.7
with:
source: docs/.vitepress/canvas-editor-docs
target: ${{ secrets.DOCS_PATH }}
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
overwrite: true
strip_components: 2

@ -1,3 +1,30 @@
## [0.9.85](https://github.com/Hufe921/canvas-editor/compare/v0.9.84...v0.9.85) (2024-07-07)
### Bug Fixes
* custom override method removes support for asynchronous #672 ([0e705d6](https://github.com/Hufe921/canvas-editor/commit/0e705d6a0bdb0922efd5c47edd8ca9eba9964199)), closes [#672](https://github.com/Hufe921/canvas-editor/issues/672)
* set control highlight and re render #678 ([24df9d3](https://github.com/Hufe921/canvas-editor/commit/24df9d3b006a8daf795ada677bfd0159e3ccc3f5)), closes [#678](https://github.com/Hufe921/canvas-editor/issues/678)
### Chores
* update build.yml ([a40441d](https://github.com/Hufe921/canvas-editor/commit/a40441dc3994a41ae29c341a542be6e0e7dada2e))
### Features
* add render mode #667 ([affd191](https://github.com/Hufe921/canvas-editor/commit/affd1911552a73a2b63a13f2c423121637830b99)), closes [#667](https://github.com/Hufe921/canvas-editor/issues/667)
* add title deletable property #670 ([b3d8413](https://github.com/Hufe921/canvas-editor/commit/b3d8413b35050eac626af1c57beaaf1b8d692a0e)), closes [#670](https://github.com/Hufe921/canvas-editor/issues/670)
* insert element boundary optimization #669 ([de44bd6](https://github.com/Hufe921/canvas-editor/commit/de44bd68ab01e5ffa8d6a8dc5d566b0cdb8d08e6)), closes [#669](https://github.com/Hufe921/canvas-editor/issues/669)
### Tests
* update text test case ([c24da73](https://github.com/Hufe921/canvas-editor/commit/c24da737b15200775a7d4a5edf4e2224f6ec5429))
## [0.9.84](https://github.com/Hufe921/canvas-editor/compare/v0.9.83...v0.9.84) (2024-06-30)

@ -33,7 +33,7 @@ describe('菜单-文本处理', () => {
.then(() => {
const data = editor.command.getValue().data.main
expect(data[0].font).to.eq('宋体')
expect(data[0].font).to.eq('华文宋体')
})
})
})

@ -932,6 +932,16 @@ Usage:
instance.command.executeLocationControl(controlId: string)
```
## executeInsertControl
Feature: Insert control
Usage:
```javascript
instance.command.executeInsertControl(payload: IElement)
```
## executeUpdateOptions
Feature: Update options

@ -43,6 +43,7 @@ interface IEditorOption {
marginIndicatorColor?: string // The margin indicator color. default: #BABABA
margins?: IMargin // Page margins. default: [100, 120, 100, 120]
pageMode?: PageMode // Paper mode: Linkage, Pagination. default: Pagination
renderMode?: RenderMode // Render mode: speed(multi words combination rendering), compatibility(word by word rendering:avoid environmental differences such as browse,fonts...). default: speed
defaultHyperlinkColor?: string // Default hyperlink color. default: #0000FF
table?: ITableOption // table configuration {tdPadding?:IPadding; defaultTrMinHeight?:number; defaultColMinWidth?:number}
header?: IHeader // Header information.{top?:number; maxHeightRadio?:MaxHeightRatio;}

@ -154,7 +154,10 @@ interface IElement {
};
// title
level?: TitleLevel;
title?: ITitle;
title?: {
conceptId?: string;
deletable?: boolean;
};
// list
listType?: ListType;
listStyle?: ListStyle;

@ -932,6 +932,16 @@ instance.command.executeSetControlHighlight(payload: ISetControlHighlightOption)
instance.command.executeLocationControl(controlId: string)
```
## executeInsertControl
功能:插入控件
用法:
```javascript
instance.command.executeInsertControl(payload: IElement)
```
## executeUpdateOptions
功能:修改配置

@ -43,6 +43,7 @@ interface IEditorOption {
marginIndicatorColor?: string // 页边距指示器颜色。默认:#BABABA
margins?: IMargin // 页面边距。默认:[100, 120, 100, 120]
pageMode?: PageMode // 纸张模式:连页、分页。默认:分页
renderMode?: RenderMode // 渲染模式:极速(多个字组合渲染)、兼容(逐字渲染:避免浏览器字体等环境差异)。默认:极速
defaultHyperlinkColor?: string // 默认超链接颜色。默认:#0000FF
table?: ITableOption // 表格配置。{tdPadding?:IPadding; defaultTrMinHeight?:number; defaultColMinWidth?:number}
header?: IHeader // 页眉信息。{top?:number; maxHeightRadio?:MaxHeightRatio;}

@ -154,7 +154,10 @@ interface IElement {
};
// 标题
level?: TitleLevel;
title?: ITitle;
title?: {
conceptId?: string;
deletable?: boolean;
};
// 列表
listType?: ListType;
listStyle?: ListStyle;

@ -32,11 +32,10 @@
<div class="options">
<ul>
<li data-family="Microsoft YaHei" style="font-family:'Microsoft YaHei';">微软雅黑</li>
<li data-family="宋体" style="font-family:'宋体';">宋体</li>
<li data-family="黑体" style="font-family:'黑体';">黑体</li>
<li data-family="仿宋" style="font-family:'仿宋';">仿宋</li>
<li data-family="楷体" style="font-family:'楷体';">楷体</li>
<li data-family="等线" style="font-family:'等线';">等线</li>
<li data-family="华文宋体" style="font-family:'华文宋体';">华文宋体</li>
<li data-family="华文黑体" style="font-family:'华文黑体';">华文黑体</li>
<li data-family="华文仿宋" style="font-family:'华文仿宋';">华文仿宋</li>
<li data-family="华文楷体" style="font-family:'华文楷体';">华文楷体</li>
<li data-family="华文琥珀" style="font-family:'华文琥珀';">华文琥珀</li>
<li data-family="华文楷体" style="font-family:'华文楷体';">华文楷体</li>
<li data-family="华文隶书" style="font-family:'华文隶书';">华文隶书</li>

@ -2,7 +2,7 @@
"name": "@hufe921/canvas-editor",
"author": "Hufe",
"license": "MIT",
"version": "0.9.84",
"version": "0.9.85",
"description": "rich text editor by canvas/svg",
"publishConfig": {
"registry": "https://registry.npmjs.org/",

@ -92,6 +92,7 @@ export class Command {
public executeSetControlProperties: CommandAdapt['setControlProperties']
public executeSetControlHighlight: CommandAdapt['setControlHighlight']
public executeLocationControl: CommandAdapt['locationControl']
public executeInsertControl: CommandAdapt['insertControl']
public executeUpdateOptions: CommandAdapt['updateOptions']
public executeInsertTitle: CommandAdapt['insertTitle']
public getCatalog: CommandAdapt['getCatalog']
@ -242,5 +243,6 @@ export class Command {
this.getControlValue = adapt.getControlValue.bind(adapt)
this.getControlList = adapt.getControlList.bind(adapt)
this.executeLocationControl = adapt.locationControl.bind(adapt)
this.executeInsertControl = adapt.insertControl.bind(adapt)
}
}

@ -2263,7 +2263,9 @@ export class CommandAdapt {
// 格式化上下文信息
const { startIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
formatElementContext(elementList, cloneElementList, startIndex)
formatElementContext(elementList, cloneElementList, startIndex, {
isBreakWhenWrap: true
})
this.draw.insertElementList(cloneElementList)
}
@ -2484,6 +2486,9 @@ export class CommandAdapt {
public setControlHighlight(payload: ISetControlHighlightOption) {
this.draw.getControl().setHighlightList(payload)
this.draw.render({
isSubmitHistory: false
})
}
public updateOptions(payload: IUpdateOption) {
@ -2577,6 +2582,25 @@ export class CommandAdapt {
}
}
public insertControl(payload: IElement) {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
const cloneElement = deepClone(payload)
// 格式化上下文信息
const { startIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const copyElement = getAnchorElement(elementList, startIndex)
if (!copyElement) return
const cloneAttr = [
...TABLE_CONTEXT_ATTR,
...EDITOR_ROW_ATTR,
...LIST_CONTEXT_ATTR
]
cloneProperty<IElement>(cloneAttr, copyElement, cloneElement)
// 插入控件
this.draw.insertElementList([cloneElement])
}
public getContainer(): HTMLDivElement {
return this.draw.getContainer()
}

@ -129,8 +129,11 @@ export class Cursor {
const agentCursorDom = this.cursorAgent.getAgentCursorDom()
if (isFocus) {
setTimeout(() => {
agentCursorDom.focus()
agentCursorDom.setSelectionRange(0, 0)
// 光标不聚焦时重新定位
if (document.activeElement !== agentCursorDom) {
agentCursorDom.focus()
agentCursorDom.setSelectionRange(0, 0)
}
})
}
// fillText位置 + 文字基线到底部距离 - 模拟光标偏移量

@ -685,7 +685,11 @@ export class Draw {
if (!this.control.getActiveControl()) {
let deleteIndex = endIndex - 1
while (deleteIndex >= start) {
if (elementList[deleteIndex]?.control?.deletable !== false) {
const deleteElement = elementList[deleteIndex]
if (
deleteElement?.control?.deletable !== false &&
deleteElement?.title?.deletable !== false
) {
elementList.splice(deleteIndex, 1)
}
deleteIndex--

@ -23,7 +23,7 @@ import { IEditorData, IEditorOption } from '../../../interface/Editor'
import { IElement, IElementPosition } from '../../../interface/Element'
import { EventBusMap } from '../../../interface/EventBus'
import { IRange } from '../../../interface/Range'
import { deepClone, nextTick, splitText } from '../../../utils'
import { deepClone, nextTick, omitObject, splitText } from '../../../utils'
import {
formatElementContext,
formatElementList,
@ -42,7 +42,11 @@ import { SelectControl } from './select/SelectControl'
import { TextControl } from './text/TextControl'
import { DateControl } from './date/DateControl'
import { MoveDirection } from '../../../dataset/enum/Observer'
import { CONTROL_STYLE_ATTR } from '../../../dataset/constant/Element'
import {
CONTROL_STYLE_ATTR,
LIST_CONTEXT_ATTR,
TITLE_CONTEXT_ATTR
} from '../../../dataset/constant/Element'
interface IMoveCursorResult {
newIndex: number
@ -876,7 +880,12 @@ export class Control {
}
}
if (element.controlId) {
controlElementList.push(element)
// 移除控件所在标题及列表上下文信息
const controlElement = omitObject(element, [
...TITLE_CONTEXT_ATTR,
...LIST_CONTEXT_ATTR
])
controlElementList.push(controlElement)
}
}
}

@ -133,7 +133,7 @@ export class TextControl implements IControlInstance {
.spliceElementList(elementList, startIndex + 1, endIndex - startIndex)
const value = this.getValue(context)
if (!value.length) {
this.control.addPlaceholder(startIndex)
this.control.addPlaceholder(startIndex, context)
}
return startIndex
}

@ -1,4 +1,4 @@
import { ElementType, IEditorOption, IElement } from '../../..'
import { ElementType, IEditorOption, IElement, RenderMode } from '../../..'
import {
PUNCTUATION_LIST,
METRICS_BASIS_TEXT
@ -124,6 +124,15 @@ export class TextParticle {
y: number
) {
this.ctx = ctx
// 兼容模式立即绘制
if (this.options.renderMode === RenderMode.COMPATIBILITY) {
this._setCurXY(x, y)
this.text = element.value
this.curStyle = element.style
this.curColor = element.color
this.complete()
return
}
// 主动完成的重设起始点
if (!this.text) {
this._setCurXY(x, y)

@ -38,6 +38,10 @@ export function enter(evt: KeyboardEvent, host: CanvasEvent) {
if (evt.shiftKey && startElement.listId) {
enterText.listWrap = true
}
// 格式化上下文
formatElementContext(elementList, [enterText], startIndex, {
isBreakWhenWrap: true
})
// 标题结尾处回车无需格式化及样式复制
if (
!(
@ -45,8 +49,6 @@ export function enter(evt: KeyboardEvent, host: CanvasEvent) {
endElement.titleId !== elementList[endIndex + 1]?.titleId
)
) {
// 格式化上下文
formatElementContext(elementList, [enterText], startIndex)
// 复制样式属性
const copyElement = getAnchorElement(elementList, endIndex)
if (copyElement) {

@ -42,3 +42,8 @@ export enum WordBreak {
BREAK_ALL = 'break-all',
BREAK_WORD = 'break-word'
}
export enum RenderMode {
SPEED = 'speed',
COMPATIBILITY = 'compatibility'
}

@ -21,7 +21,8 @@ import {
EditorMode,
PageMode,
PaperDirection,
WordBreak
WordBreak,
RenderMode
} from './dataset/enum/Editor'
import { EDITOR_COMPONENT } from './dataset/constant/Editor'
import { IWatermark } from './interface/Watermark'
@ -150,6 +151,7 @@ export {
ControlType,
EditorComponent,
PageMode,
RenderMode,
ImageDisplay,
Command,
KeyMap,

@ -3,6 +3,7 @@ import {
EditorMode,
PageMode,
PaperDirection,
RenderMode,
WordBreak
} from '../dataset/enum/Editor'
import { IBackgroundOption } from './Background'
@ -60,6 +61,7 @@ export interface IEditorOption {
marginIndicatorColor?: string
margins?: IMargin
pageMode?: PageMode
renderMode?: RenderMode
defaultHyperlinkColor?: string
paperDirection?: PaperDirection
inactiveAlpha?: number

@ -12,7 +12,11 @@ export interface ITitleSizeOption {
export type ITitleOption = ITitleSizeOption & {}
export interface ITitle {
export interface ITitleRule {
deletable?: boolean
}
export type ITitle = ITitleRule & {
conceptId?: string
}

@ -826,7 +826,7 @@ export function formatElementContext(
if (
isBreakWhenWrap &&
!copyElement.listId &&
/^\n/.test(targetElement.value)
START_LINE_BREAK_REG.test(targetElement.value)
) {
isBreakWarped = true
}

@ -39,6 +39,7 @@ import {
EditorMode,
PageMode,
PaperDirection,
RenderMode,
WordBreak
} from '../dataset/enum/Editor'
@ -144,6 +145,7 @@ export function mergeOption(
marginIndicatorColor: '#BABABA',
margins: [100, 120, 100, 120],
pageMode: PageMode.PAGING,
renderMode: RenderMode.SPEED,
defaultHyperlinkColor: '#0000FF',
paperDirection: PaperDirection.VERTICAL,
inactiveAlpha: 0.6,

Loading…
Cancel
Save