Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: extract i18n to class module #176

Merged
merged 1 commit into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions packages/docs/fluent-editor/demos/i18n-custom.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ onMounted(() => {
],
'counter': true,
'better-table': true,
'i18n': {
lang: 'zh-CN',
langText: {
'copy-cells': '复制单元格',
'copy-table': '复制表格',
'cut-cells': '剪切单元格',
'empty-cells': '清空单元格',
},
},
},
lang: 'zh-CN',
langText: {
'copy-cells': '复制单元格',
'copy-table': '复制表格',
'cut-cells': '剪切单元格',
'empty-cells': '清空单元格',
},

})
})
})
Expand Down
6 changes: 4 additions & 2 deletions packages/docs/fluent-editor/demos/i18n.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ onMounted(() => {
],
'counter': true,
'better-table': true,
'i18n': {
lang: lang.value,
},
},
lang: lang.value,
})
})
})
function switchLanguage() {
lang.value = lang.value === 'zh-CN' ? 'en-US' : 'zh-CN'
editor.changeLanguage({ lang: lang.value })
editor.getModule('i18n').changeLanguage({ lang: lang.value })
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ export interface IEditorConfig extends QuillOptions {
autoProtocol?: boolean | string
editorPaste?: any
uploadOption?: {
imageUpload?: ({ file: File, callback, editor }) => void
imageUpload?: ({ file, callback, editor }) => void
imageAccept?: Array<string>[] | string
fileAccept?: Array<string>[] | string
fileUpload: ({ file: File, callback, editor }) => void
fileUpload: ({ file, callback, editor }) => void
isVideoPlay?: boolean
maxSize?: number
success?: (file: File) => void
fail?: (file: File) => void
multiple?: boolean
}
screenshot?: Partial<ScreenShotOptions>
lang?: string
langText?: Record<string, string>
i18n?: {
lang?: string
langText?: Record<string, string>
}
zzxming marked this conversation as resolved.
Show resolved Hide resolved
}
8 changes: 4 additions & 4 deletions packages/fluent-editor/src/counter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class Counter {
this.options = this.resolveOptions(options)
this.container = quill.addContainer('ql-counter')
quill.on(Quill.events.TEXT_CHANGE, this.renderCount)
this.quill.on(CHANGE_LANGUAGE_EVENT, () => {
this.quill.emitter.on(CHANGE_LANGUAGE_EVENT, () => {
this.options = this.resolveOptions(options)
this.renderCount()
})
Expand All @@ -22,7 +22,7 @@ export default class Counter {
return Object.assign({
format: 'text',
unit: 'char',
template: this.quill.options.langText['counter-template'],
template: this.quill.langText['counter-template'],
count: 500,
}, options)
}
Expand All @@ -33,7 +33,7 @@ export default class Counter {
const { format, count: totalCount, unit, template: counterTemplate, errorTemplate } = this.options
const count = this.getContentLength(format)
const restCount = totalCount - count
const countUnit = unit === 'char' ? this.quill.options.langText.char : this.quill.options.langText.word
const countUnit = unit === 'char' ? this.quill.langText.char : this.quill.langText.word
let template: any = counterTemplate
if (typeof template === 'function') {
template = template(count, restCount)
Expand All @@ -43,7 +43,7 @@ export default class Counter {
.replace('{{restCount}}', String(restCount))
.replace(/{{countUnit}}/g, countUnit)

let limitTemplate: any = errorTemplate || this.quill.options.langText['counter-limit-tips']
let limitTemplate: any = errorTemplate || this.quill.langText['counter-limit-tips']
if (typeof limitTemplate === 'function') {
limitTemplate = limitTemplate(count, restCount)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/fluent-editor/src/custom-clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class CustomClipboard extends Clipboard {
let loadingTipsContainer
if (deltaLength > BIG_DELTA_LIMIT) {
loadingTipsContainer = this.quill.addContainer('ql-loading-tips')
loadingTipsContainer.innerHTML = this.quill.options.langText.pasting
loadingTipsContainer.innerHTML = this.quill.langText.pasting
zzxming marked this conversation as resolved.
Show resolved Hide resolved
}

const linePos = { index: range.index, length: range.length, fix: 0 }
Expand Down Expand Up @@ -471,7 +471,7 @@ class CustomClipboard extends Clipboard {
else {
// 剪切板中无图片,用失败占位图替换
const errorImagePlaceholderJpg
= this.quill.options.langText['img-error'] === 'Image Copy Error'
= this.quill.langText['img-error'] === 'Image Copy Error'
? ERROR_IMAGE_PLACEHOLDER_EN
: ERROR_IMAGE_PLACEHOLDER_CN
file = await imageUrlToFile(errorImagePlaceholderJpg, true)
Expand Down
35 changes: 7 additions & 28 deletions packages/fluent-editor/src/fluent-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { IEditorConfig } from './config/types'
import Quill from 'quill'
import HeaderList from 'quill-header-list'
import { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'
import { CHANGE_LANGUAGE_EVENT, defaultLanguage, getListValue, ICONS_CONFIG, inputFile, LANG_CONF } from './config'
import { getListValue, ICONS_CONFIG, inputFile } from './config'
import Counter from './counter' // 字符统计
import CustomClipboard from './custom-clipboard' // 粘贴板
import CustomImage from './custom-image/BlotFormatter' // 图片
Expand All @@ -14,6 +14,7 @@ import Emoji from './emoji' // 表情
import FileModule from './file' // 文件
import { FormatPainter } from './format-painter'
import { fullscreenHandler } from './fullscreen/handler'
import { I18N } from './i18n'
import Link from './link' // 超链接
import MathliveModule from './mathlive' // latex公式
import MathliveBlot from './mathlive/formats'
Expand All @@ -24,42 +25,18 @@ import Strike from './strike' // 删除线
import CustomSyntax from './syntax' // 代码块高亮
import BetterTable from './table/better-table' // 表格
import Toolbar, { ToolbarTip } from './toolbar' // 工具栏
import { isUndefined } from './utils/is'
import Video from './video' // 视频
// import GlobalLink from './global-link' // 全局链接
// import QuickMenu from './quick-menu' // 快捷菜单
export interface I18NOptions {
lang: string
langText: Record<string, string>
}
function resolveLanguageOption(options: Partial<I18NOptions>): I18NOptions {
if (isUndefined(options.lang)) {
options.lang = defaultLanguage
}
if (!(options.lang in LANG_CONF)) {
console.warn(`The language ${options.lang} is not supported. Use the default language: ${defaultLanguage}`)
options.lang = defaultLanguage
}
return {
lang: options.lang,
langText: Object.assign({}, LANG_CONF[options.lang], options.langText || {}),
}
}

export class FluentEditor extends Quill {
isFullscreen: boolean = false
options: IEditorConfig & ExpandedQuillOptions
lang: string
langText: Record<string, string>
Copy link
Member

@kagol kagol Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zzxming 这两个变量为什么从 quill.options 移到了 quill 呢?直接放到 quill 中和放到 quill.options 中,一般如何选择呢?
另外是不是从 i18n 模块也能获取这两个变量,比如:this.quill.getModule('i18n').options.lang,这样是不是就重复了?

之前可能是没有抽取 i18n 模块,所以需要有一个地方承载 lang / langText,现在有 i18n 模块了,我觉得挂在 quill 的这两个变量是没有必要的。

不过这个不太要紧,我先合入,可以后续持续优化。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你说的有道理,这个是我在删依赖包的时候顺手改的,没注意太多。

但是我觉得在 this.quill 上挂 lang 这个变量还是有用的,i18n 是处理编辑器内文字的,有这个也可以更方便的获取当前编辑器的语,可以挂 getter,这样要修改还是要通过 changeLanguage 改,但是获取可以直接 quill.lang 获取。langText我可以抽离一个函数去获取对应文本,这样也不用每次获取文本都要写一长串了

constructor(container: HTMLElement | string, options: IEditorConfig = {}) {
options = Object.assign(options, resolveLanguageOption(options || {}))
super(container, options)
}

changeLanguage(options: Partial<I18NOptions>) {
const langOps = resolveLanguageOption(options)
if (langOps.lang === this.options.lang) return
this.options.lang = langOps.lang
this.options.langText = langOps.langText
this.emitter.emit(CHANGE_LANGUAGE_EVENT, this.options.lang, this.options.langText)
}
}

const registerModules = function () {
Expand All @@ -71,6 +48,7 @@ const registerModules = function () {
const SnowTheme = Quill.imports['themes/snow'] as typeof Module
SnowTheme.DEFAULTS = {
modules: {
'i18n': true,
'keyboard': {
bindings: {
...BetterTable.keyboardBindings,
Expand Down Expand Up @@ -183,6 +161,7 @@ const registerModules = function () {

FluentEditor.register(
{
'modules/i18n': I18N,
'modules/toolbar': Toolbar,
'modules/mention': Mention,
'modules/clipboard': CustomClipboard,
Expand Down
49 changes: 49 additions & 0 deletions packages/fluent-editor/src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { FluentEditor } from '../fluent-editor'
import { CHANGE_LANGUAGE_EVENT, defaultLanguage, LANG_CONF } from '../config'
import { isUndefined } from '../utils/is'

export interface I18NOptions {
lang: string
langText: Record<string, string>
}

export class I18N {
isFullscreen: boolean = false
options: I18NOptions = {
lang: 'en-US',
langText: LANG_CONF['en-US'],
}

constructor(public quill: FluentEditor, options: Partial<I18NOptions>) {
this.options = Object.assign({}, options, this.resolveLanguageOption(options || {}))
this.changeLanguage(this.options)
}

resolveLanguageOption(options: Partial<I18NOptions>): I18NOptions {
if (isUndefined(options.lang)) {
options.lang = defaultLanguage
}
if (!(options.lang in LANG_CONF)) {
console.warn(`The language ${options.lang} is not supported. Use the default language: ${defaultLanguage}`)
options.lang = defaultLanguage
}
return {
lang: options.lang,
langText: Object.assign({}, LANG_CONF[options.lang], options.langText || {}),
}
}

setLangTextToInstance() {
this.quill.langText = this.options.langText
this.quill.lang = this.options.lang
}

changeLanguage(options: Partial<I18NOptions>) {
const langOps = this.resolveLanguageOption(options)
if (langOps.lang === this.quill.lang) return
this.options.lang = langOps.lang
this.options.langText = langOps.langText
this.setLangTextToInstance()
this.quill.emitter.emit(CHANGE_LANGUAGE_EVENT, this.options.lang, this.options.langText)
}
}
4 changes: 2 additions & 2 deletions packages/fluent-editor/src/link/modules/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export default class Tooltip extends BaseTooltip {
LinkBlot.autoProtocol = this.options.autoProtocol
this.debouncedHideToolTip = debounce(this.hideToolTip, 300)
this.debouncedShowToolTip = debounce(this.showToolTip, 300)
this.quill.on(CHANGE_LANGUAGE_EVENT, () => {
this.quill.emitter.on(CHANGE_LANGUAGE_EVENT, () => {
this.setTemplate()
})
}

setTemplate() {
this.root.innerHTML = [
`<input type="text" data-formula="e=mc^2" data-link="${this.quill.options.langText?.linkplaceholder}" data-video="Embed URL" style="width: 225px;">`,
`<input type="text" data-formula="e=mc^2" data-link="${this.quill.langText?.linkplaceholder}" data-video="Embed URL" style="width: 225px;">`,
'<span class="ql-split"></span>',
'<a class="ql-preview"><i class="icon-share"></i></a>',
'<a class="ql-remove"><i class="icon-delete"></i></a>',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default class TableOperationMenu {
this.selectedTds = this.tableSelection.selectedTds
this.destroyHandler = this.destroy.bind(this)
this.columnToolCells = this.tableColumnTool.colToolCells()
this.DEFAULT_COLOR_SUBTITLE = this.quill.options.langText['sub-title-bg-color']
this.DEFAULT_COLOR_SUBTITLE = this.quill.langText['sub-title-bg-color']
this.colorSubTitle
= options.color && options.color.text
? options.color.text
Expand All @@ -66,13 +66,13 @@ export default class TableOperationMenu {
document.addEventListener('click', this.destroyHandler, false)
this.quill.on(CHANGE_LANGUAGE_EVENT, () => {
this.destroy()
this.DEFAULT_COLOR_SUBTITLE = this.quill.options.langText['sub-title-bg-color']
this.DEFAULT_COLOR_SUBTITLE = this.quill.langText['sub-title-bg-color']
this.setDefaultMenu()
})
}

setDefaultMenu() {
const langText = this.quill.options.langText
const langText = this.quill.langText
this.DEFAULT_MENU = {
copyCells: {
text: langText['copy-cells'],
Expand Down
5 changes: 3 additions & 2 deletions packages/fluent-editor/src/toolbar/toolbar-tip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class ToolbarTip extends QuillToolbarTip {
}
super(quill, options)

this.quill.on(CHANGE_LANGUAGE_EVENT, () => {
this.quill.emitter.on(CHANGE_LANGUAGE_EVENT, () => {
this.destroyAllTips()
this.options = this.resolveOptions(options)
this.createToolbarTip()
Expand All @@ -20,7 +20,8 @@ export class ToolbarTip extends QuillToolbarTip {

resolveOptions(options: Partial<QuillToolbarTipOptions>): QuillToolbarTipOptions {
const result = super.resolveOptions(options)
const langText = this.quill.options.langText
if (!this.quill.lang) return result
const langText = this.quill.langText
const btnTips = [
'bold',
'italic',
Expand Down
Loading