-
Notifications
You must be signed in to change notification settings - Fork 146
/
WatermarkPlugin.ts
113 lines (96 loc) · 3.11 KB
/
WatermarkPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { getObjectKeys } from 'roosterjs-content-model-dom';
import { isModelEmptyFast } from './isModelEmptyFast';
import type { WatermarkFormat } from './WatermarkFormat';
import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
const WATERMARK_CONTENT_KEY = '_WatermarkContent';
const styleMap: Record<keyof WatermarkFormat, string> = {
fontFamily: 'font-family',
fontSize: 'font-size',
textColor: 'color',
};
/**
* A watermark plugin to manage watermark string for roosterjs
*/
export class WatermarkPlugin implements EditorPlugin {
private editor: IEditor | null = null;
private format: WatermarkFormat;
private isShowing = false;
/**
* Create an instance of Watermark plugin
* @param watermark The watermark string
*/
constructor(protected watermark: string, format?: WatermarkFormat) {
this.format = format || {
fontSize: '14px',
textColor: '#AAAAAA',
};
}
/**
* Get a friendly name of this plugin
*/
getName() {
return 'Watermark';
}
/**
* Initialize this plugin. This should only be called from Editor
* @param editor Editor instance
*/
initialize(editor: IEditor) {
this.editor = editor;
}
/**
* Dispose this plugin
*/
dispose() {
this.editor = null;
}
/**
* Handle events triggered from editor
* @param event PluginEvent object
*/
onPluginEvent(event: PluginEvent) {
const editor = this.editor;
if (!editor) {
return;
}
if (
(event.eventType == 'input' && event.rawEvent.inputType == 'insertText') ||
event.eventType == 'compositionEnd'
) {
// When input text, editor must not be empty, so we can do hide watermark now without checking content model
this.showHide(editor, false /*isEmpty*/);
} else if (
event.eventType == 'editorReady' ||
event.eventType == 'contentChanged' ||
event.eventType == 'input' ||
event.eventType == 'beforeDispose'
) {
editor.formatContentModel(model => {
const isEmpty = isModelEmptyFast(model);
this.showHide(editor, isEmpty);
return false;
});
}
}
private showHide(editor: IEditor, isEmpty: boolean) {
if (this.isShowing && !isEmpty) {
this.hide(editor);
} else if (!this.isShowing && isEmpty) {
this.show(editor);
}
}
protected show(editor: IEditor) {
let rule = `position: absolute; pointer-events: none; content: "${this.watermark}";`;
getObjectKeys(styleMap).forEach(x => {
if (this.format[x]) {
rule += `${styleMap[x]}: ${this.format[x]}!important;`;
}
});
editor.setEditorStyle(WATERMARK_CONTENT_KEY, rule, 'before');
this.isShowing = true;
}
protected hide(editor: IEditor) {
editor.setEditorStyle(WATERMARK_CONTENT_KEY, null);
this.isShowing = false;
}
}