Skip to content

Commit dd7337f

Browse files
feat(custom-image): 增加 allowInvalid 用于支持特定场景(比如:Electron)需要返回原始 url (#354)
* feat(custom-image): 增加 allowInvalid 用于支持特定场景(比如:Electron)需要返回原始 url * docs: add image options doc * chore: release v4.0.0-alpha.5 * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 24427ba commit dd7337f

5 files changed

Lines changed: 98 additions & 2 deletions

File tree

packages/docs/fluent-editor/docs/demo/file-upload.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,81 @@
3232

3333
> 上传文件被 `mimetypes``maxSize` 筛选而上传失败的文件不会出现在 `handler` 回调参数中。
3434
> 若文件是被`mimetypes``maxSize` 筛选而上传失败,fail 回调中的 `range` 则为上传初始位置,而不是上传失败的位置。
35+
36+
## 图片(image)模块的 Options
37+
38+
```typescript
39+
const DefaultOptions = {
40+
// 默认情况下,`file://` 格式的本地文件路径在浏览器环境无法读取,因此会被转换成 `//:0`,但是在一些特殊的场景下(比如:Electron),需要获取到图片的原始路径,进行后续的上传处理
41+
// 注意:该选项一旦设置为 true,本地磁盘路径会暴露出去,这可能会带来安全风险,请确保你了解相关的安全隐患
42+
allowInvalidUrl: false,
43+
44+
specs: [
45+
ImageSpec,
46+
],
47+
overlay: {
48+
className: 'blot-formatter__overlay',
49+
style: {
50+
position: 'absolute',
51+
boxSizing: 'border-box',
52+
border: '1px dashed #444',
53+
},
54+
},
55+
toolbar: {
56+
mainClassName: 'blot-formatter__toolbar',
57+
mainStyle: {
58+
position: 'absolute',
59+
top: '-12px',
60+
right: '0',
61+
left: '0',
62+
height: '0',
63+
minWidth: '120px',
64+
font: '12px/1.0 Arial, Helvetica, sans-serif',
65+
textAlign: 'center',
66+
color: '#333',
67+
boxSizing: 'border-box',
68+
cursor: 'default',
69+
zIndex: '1',
70+
},
71+
buttonClassName: 'blot-formatter__toolbar-button',
72+
addButtonSelectStyle: true,
73+
buttonStyle: {
74+
display: 'inline-flex',
75+
alignItems: 'center',
76+
justifyContent: 'center',
77+
width: '24px',
78+
height: '24px',
79+
background: 'white',
80+
border: '1px solid #999',
81+
verticalAlign: 'middle',
82+
cursor: 'pointer',
83+
},
84+
svgStyle: {
85+
display: 'inline-block',
86+
width: '16px',
87+
height: '16px',
88+
background: 'white',
89+
verticalAlign: 'middle',
90+
},
91+
buttons: {
92+
'align-left': true,
93+
'align-center': true,
94+
'align-right': true,
95+
'copy': true,
96+
'download': true,
97+
},
98+
},
99+
resize: {
100+
handleClassName: 'blot-formatter__resize-handle',
101+
handleStyle: {
102+
position: 'absolute',
103+
height: '12px',
104+
width: '12px',
105+
backgroundColor: 'white',
106+
border: '1px solid #777',
107+
boxSizing: 'border-box',
108+
opacity: '0.80',
109+
},
110+
},
111+
}
112+
```

packages/fluent-editor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@opentiny/fluent-editor",
33
"type": "module",
4-
"version": "4.0.0-alpha.2",
4+
"version": "4.0.0-alpha.5",
55
"description": "A rich text editor based on Quill 2.0, which extends rich modules and formats on the basis of Quill. It's powerful and out-of-the-box.",
66
"author": "OpenTiny Team",
77
"license": "MIT",

packages/fluent-editor/src/modules/custom-image/blot-formatter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export class BlotFormatter {
2727

2828
constructor(public quill: FluentEditor, options: Partial<BlotFormatterOptions> = {}) {
2929
this.options = deepmerge({}, DefaultOptions, options, { arrayMerge: dontMerge })
30+
if (options.allowInvalidUrl !== undefined) {
31+
this.options.allowInvalidUrl = options.allowInvalidUrl
32+
}
33+
CustomImage.setOptions(this.options.allowInvalidUrl)
3034
this.currentSpec = null
3135
this.actions = []
3236
this.overlay = document.createElement('div')

packages/fluent-editor/src/modules/custom-image/image.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ export class CustomImage extends Embed {
1818
static blotName = 'image'
1919
static tagName = 'IMG'
2020
static ID_SEED = 0
21+
static allowInvalidUrl: boolean = false
2122
declare domNode: HTMLElement
23+
24+
static setOptions(allowInvalidUrl: boolean) {
25+
this.allowInvalidUrl = allowInvalidUrl
26+
}
27+
2228
static create(value: ImageValue) {
2329
const node = super.create(value) as HTMLElement
2430
const url = typeof value === 'string' ? value : value.src
@@ -69,7 +75,10 @@ export class CustomImage extends Embed {
6975
}
7076

7177
static sanitize(url: string) {
72-
return sanitize(url, ['http', 'https', 'blob', 'data']) ? url : '//:0'
78+
if (sanitize(url, ['http', 'https', 'blob', 'data']) || this.allowInvalidUrl) {
79+
return url
80+
}
81+
return '//:0'
7382
}
7483

7584
static value(domNode: HTMLElement) {

packages/fluent-editor/src/modules/custom-image/options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export interface BlotFormatterOptions {
5454
overlay: OverlayOptions
5555
resize: ResizeOptions
5656
toolbar: ToolbarOptions
57+
allowInvalidUrl: boolean
5758
}
5859

5960
export const LEFT_ALIGN = 'align-left'
@@ -62,6 +63,10 @@ export const RIGHT_ALIGN = 'align-right'
6263
export const COPY = 'copy'
6364
export const DOWNLOAD = 'download'
6465
const DefaultOptions: BlotFormatterOptions = {
66+
// 默认情况下,`file://` 格式的本地文件路径在浏览器环境无法读取,因此会被转换成 `//:0`,但是在一些特殊的场景下(比如:Electron),需要获取到图片的原始路径,进行后续的上传处理
67+
// 注意:该选项一旦设置为 true,本地磁盘路径会暴露出去,这可能会带来安全风险,请确保你了解相关的安全隐患
68+
allowInvalidUrl: false,
69+
6570
specs: [
6671
ImageSpec,
6772
],

0 commit comments

Comments
 (0)