@sd-angular/core 19.0.0-beta.2 → 19.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/sd-angular-core-components-document-builder.mjs +92 -32
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-auth.mjs +137 -0
- package/fesm2022/sd-angular-core-modules-auth.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules.mjs +1 -0
- package/fesm2022/sd-angular-core-modules.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +4 -7
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +11 -2
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/modules/auth/configurations/auth.configuration.d.ts +19 -0
- package/modules/auth/configurations/index.d.ts +1 -0
- package/modules/auth/guards/auth.guard.d.ts +11 -0
- package/modules/auth/guards/index.d.ts +2 -0
- package/modules/auth/guards/portal.guard.d.ts +11 -0
- package/modules/auth/index.d.ts +3 -0
- package/modules/auth/services/auth.model.d.ts +8 -0
- package/modules/auth/services/auth.service.d.ts +17 -0
- package/modules/auth/services/index.d.ts +2 -0
- package/modules/index.d.ts +1 -0
- package/package.json +61 -57
- package/utilities/models/src/maybe-async.model.d.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-components-document-builder.mjs","sources":["../../../projects/sd-angular/components/document-builder/src/components/header-footer-builder/plugins/page-number.plugin.ts","../../../projects/sd-angular/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.ts","../../../projects/sd-angular/components/document-builder/src/plugins/page-orientation.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/comment.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/variable.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/table-fit.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/image-upload.plugin.ts","../../../projects/sd-angular/components/document-builder/src/document-builder.component.ts","../../../projects/sd-angular/components/document-builder/src/document-builder.component.html","../../../projects/sd-angular/components/document-builder/sd-angular-core-components-document-builder.ts"],"sourcesContent":["import { Plugin, ButtonView } from 'ckeditor5';\r\n\r\nexport class PageNumberPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n // 1. Đăng ký nút \"Số trang hiện tại\"\r\n editor.ui.componentFactory.add('pageNumber', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n view.set({\r\n label: 'Số trang hiện tại',\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H4V4h12v12zM6 6h2v2H6zm0 4h2v2H6zm0 4h2v2H6zm4-8h4v2h-4zm0 4h4v2h-4zm0 4h4v2h-4z\"/></svg>', // Icon đơn giản\r\n tooltip: true\r\n });\r\n\r\n // Khi bấm nút -> Chèn HTML đánh dấu\r\n view.on('execute', () => {\r\n editor.model.change(writer => {\r\n const viewFragment = editor.data.processor.toView(\r\n // Đây là HTML chuẩn để Word hiểu là số trang (dùng cho cách xuất MHTML/.doc)\r\n // Hoặc là marker để Backend replace\r\n '<span class=\"page-number-marker\" style=\"mso-field-code: PAGE; background: #eee; border: 1px dashed #999; padding: 0 4px;\">[PAGE]</span> ' \r\n );\r\n const modelFragment = editor.data.toModel(viewFragment);\r\n editor.model.insertContent(modelFragment);\r\n });\r\n });\r\n return view;\r\n });\r\n\r\n // 2. Đăng ký nút \"Tổng số trang\"\r\n editor.ui.componentFactory.add('totalPages', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n view.set({\r\n label: 'Tổng số trang',\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/></svg>',\r\n tooltip: true\r\n });\r\n\r\n view.on('execute', () => {\r\n editor.model.change(writer => {\r\n const viewFragment = editor.data.processor.toView(\r\n '<span class=\"total-page-marker\" style=\"mso-field-code: NUMPAGES; background: #eee; border: 1px dashed #999; padding: 0 4px;\">[TOTAL]</span> '\r\n );\r\n const modelFragment = editor.data.toModel(viewFragment);\r\n editor.model.insertContent(modelFragment);\r\n });\r\n });\r\n return view;\r\n });\r\n }\r\n}","import { Component, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { CKEditorModule } from '@ckeditor/ckeditor5-angular';\r\n\r\nimport {\r\n ClassicEditor,\r\n EditorConfig,\r\n Essentials,\r\n Paragraph,\r\n Bold,\r\n Italic,\r\n Underline,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n Alignment,\r\n // Import Plugin tự viết\r\n // PageNumberPlugin (nếu import từ file ngoài)\r\n} from 'ckeditor5';\r\nimport { PageNumberPlugin } from './plugins/page-number.plugin';\r\n\r\n@Component({\r\n selector: 'sd-header-footer-builder',\r\n standalone: true,\r\n imports: [CommonModule, CKEditorModule],\r\n template: `\r\n <div class=\"header-footer-editor-wrapper\">\r\n <ckeditor [editor]=\"Editor\" [config]=\"config\" (ready)=\"onReady($event)\"> </ckeditor>\r\n </div>\r\n `,\r\n styles: [\r\n `\r\n /* Style tối giản cho vùng soạn thảo Header/Footer */\r\n :host ::ng-deep .header-footer-editor-wrapper .ck-editor__editable_inline {\r\n min-height: 100px; /* Header thường ngắn */\r\n max-height: 200px;\r\n padding: 10px 20px;\r\n border: 1px solid #ddd;\r\n }\r\n\r\n /* Style hiển thị cho Placeholder số trang trong lúc soạn thảo */\r\n :host ::ng-deep .page-number-marker,\r\n :host ::ng-deep .total-page-marker {\r\n font-size: 11px;\r\n color: #555;\r\n cursor: default;\r\n user-select: none;\r\n }\r\n `,\r\n ],\r\n})\r\nexport class SdHeaderFooterBuilder {\r\n #editor!: ClassicEditor;\r\n Editor = ClassicEditor;\r\n\r\n #model: string | undefined | null;\r\n @Input() set model(value: string | undefined | null) {\r\n if (this.#model !== value) {\r\n this.#model = value;\r\n }\r\n }\r\n\r\n @Output() modelChange = new EventEmitter<string>();\r\n config: EditorConfig = {\r\n licenseKey: 'GPL', // Hoặc key thương mại nếu có\r\n // 1. PLUGIN RÚT GỌN (Bỏ Table, List, PageBreak...)\r\n plugins: [\r\n Essentials,\r\n Paragraph,\r\n Bold,\r\n Italic,\r\n Underline,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n Alignment,\r\n PageNumberPlugin, // <--- Plugin số trang\r\n ],\r\n // 2. TOOLBAR ĐƠN GIẢN\r\n toolbar: {\r\n items: [\r\n 'undo',\r\n 'redo',\r\n '|',\r\n 'fontSize',\r\n 'fontColor',\r\n '|',\r\n 'bold',\r\n 'italic',\r\n 'underline',\r\n '|',\r\n 'alignment', // Căn trái/phải/giữa (Quan trọng cho Header/Footer)\r\n '|',\r\n 'pageNumber',\r\n 'totalPages', // <--- 2 nút mới\r\n ],\r\n shouldNotGroupWhenFull: true,\r\n },\r\n // Cấu hình alignment\r\n alignment: {\r\n options: ['left', 'center', 'right'],\r\n },\r\n };\r\n\r\n onReady(editor: ClassicEditor): void {\r\n this.#editor = editor;\r\n this.#editor.setData(this.#model || '');\r\n this.#editor.model.document.on('change:data', () => {\r\n this.#model = this.#editor.getData();\r\n this.modelChange.next(this.#model);\r\n });\r\n }\r\n}\r\n","import { ButtonView, Plugin } from 'ckeditor5';\r\n// Icon khổ dọc (Mặc định cũ)\r\nconst ICON_PORTRAIT =\r\n '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6V4h8v12z\"/></svg>';\r\n\r\n// Icon khổ ngang (Mới)\r\nconst ICON_LANDSCAPE =\r\n '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 4H2C.9 4 0 4.9 0 6v8c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 10H2V6h16v8z\"/></svg>';\r\nexport class PageOrientationPlugin extends Plugin {\r\n public static readonly pluginName = 'PageOrientationPlugin';\r\n \r\n private _currentOrientation: 'PORTRAIT' | 'LANDSCAPE' = 'PORTRAIT';\r\n private orientationChangeEmitter?: (orientation: 'PORTRAIT' | 'LANDSCAPE') => void;\r\n private buttonView?: ButtonView;\r\n\r\n init() {\r\n const editor = this.editor;\r\n const componentFactory = editor.ui.componentFactory;\r\n\r\n // Đăng ký nút tên là 'pageOrientation'\r\n componentFactory.add('pageOrientation', locale => {\r\n const view = new ButtonView(locale);\r\n this.buttonView = view;\r\n\r\n view.set({\r\n // label: 'Xoay giấy (A4)',\r\n icon: ICON_PORTRAIT,\r\n // tooltip: true,\r\n // withText: true,\r\n class: 'btn-orientation', // Class để style nếu cần\r\n });\r\n\r\n // Xử lý khi bấm nút\r\n view.on('execute', () => {\r\n this.toggleOrientation();\r\n });\r\n\r\n return view;\r\n });\r\n }\r\n\r\n /**\r\n * Toggle between portrait and landscape orientation\r\n */\r\n toggleOrientation(): void {\r\n const newOrientation = this._currentOrientation === 'PORTRAIT' ? 'LANDSCAPE' : 'PORTRAIT';\r\n this.setOrientation(newOrientation);\r\n }\r\n\r\n /**\r\n * Set orientation programmatically\r\n */\r\n setOrientation(orientation: 'PORTRAIT' | 'LANDSCAPE'): void {\r\n const editor = this.editor;\r\n const editingView = editor.editing.view;\r\n const rootElement = editingView.document.getRoot();\r\n\r\n editor.editing.view.change(writer => {\r\n if (orientation === 'LANDSCAPE') {\r\n writer.addClass('landscape', rootElement!);\r\n } else {\r\n writer.removeClass('landscape', rootElement!);\r\n }\r\n });\r\n\r\n // Update button icon\r\n if (this.buttonView) {\r\n this.buttonView.icon = orientation === 'LANDSCAPE' ? ICON_LANDSCAPE : ICON_PORTRAIT;\r\n }\r\n\r\n this._currentOrientation = orientation;\r\n this.orientationChangeEmitter?.(orientation);\r\n }\r\n\r\n /**\r\n * Get current orientation\r\n */\r\n getOrientation(): 'PORTRAIT' | 'LANDSCAPE' {\r\n return this._currentOrientation;\r\n }\r\n\r\n /**\r\n * Register callback for orientation changes\r\n */\r\n onOrientationChange(callback: (orientation: 'PORTRAIT' | 'LANDSCAPE') => void): void {\r\n this.orientationChangeEmitter = callback;\r\n }\r\n}\r\n","import { Plugin, ButtonView, Config } from 'ckeditor5';\r\nimport { SdDocumentBuilderComment, SdEditorConfig } from '../document-builder.model';\r\nimport { SdResolveMaybeAsync } from '@sd-angular/core/utilities';\r\n\r\nexport class CommentPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n\r\n // --- 1. CONVERSION: MODEL MARKER -> VIEW CSS ---\r\n // Biến Marker thành Highlight màu vàng\r\n editor.conversion.for('editingDowncast').markerToHighlight({\r\n model: 'comment', // Khớp với prefix của markerId (ví dụ: comment:12345)\r\n view: {\r\n classes: 'ck-comment-marker', // Class CSS sẽ được gắn vào thẻ <span> bao quanh text\r\n },\r\n });\r\n\r\n // --- 3. ĐĂNG KÝ UI COMPONENT: 'addCommentBtn' ---\r\n editor.ui.componentFactory.add('addCommentBtn', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n // Lấy config từ Angular\r\n const config = editor.config as Config<SdEditorConfig>;\r\n const getOption = config.get('getOption') as SdEditorConfig['getOption'];\r\n const option = getOption?.();\r\n\r\n // ⭐ ẨN BUTTON NẾU KHÔNG CÓ onAddComment\r\n if (!option?.onAddComment) {\r\n // Trả về button rỗng hoặc null để không hiển thị\r\n view.set({\r\n label: '',\r\n isVisible: false,\r\n });\r\n return view;\r\n }\r\n\r\n view.set({\r\n label: 'Thêm bình luận',\r\n // Icon SVG comment\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 13v6l-4-4H4a2 2 0 01-2-2V4a2 2 0 012-2h14a2 2 0 012 2v9zM5 7h10v2H5V7zm0 4h10v2H5v-2z\"/></svg>',\r\n tooltip: true,\r\n isEnabled: false, // Mặc định disable\r\n });\r\n\r\n // 4. Logic Enable/Disable: Dựa theo Selection\r\n const selection = editor.model.document.selection;\r\n\r\n // Lắng nghe sự kiện change selection để bật/tắt nút\r\n this.listenTo(selection, 'change', () => {\r\n // Enable khi có bôi đen text (không phải collapsed)\r\n view.isEnabled = !selection.isCollapsed;\r\n });\r\n\r\n // 5. Logic Execute: Khi bấm nút\r\n this.listenTo(view, 'execute', () => {\r\n const range = selection.getFirstRange();\r\n if (!range || !option?.onAddComment) return;\r\n // Helper lấy text thuần từ range\r\n let selectedText = '';\r\n for (const item of range.getItems()) {\r\n if (item.is('$text') || item.is('$textProxy')) {\r\n selectedText += (item as any).data;\r\n }\r\n }\r\n // ⭐ BẮN EVENT RA NGOÀI - KHÔNG TỰ ADD MARKER\r\n // Angular component sẽ xử lý logic (mở modal, validation, etc.)\r\n // và gọi lại hàm addComment() nếu cần\r\n option.onAddComment(range);\r\n });\r\n\r\n return view;\r\n });\r\n }\r\n}\r\n","import { Config, Plugin, Widget, toWidget } from 'ckeditor5';\r\nimport { SdDocumentBuilderOption, SdDocumentBuilderVariable, SdEditorConfig } from '../document-builder.model';\r\nimport { SdResolveMaybeAsync, SdUtilities } from '@sd-angular/core/utilities';\r\n\r\nexport class VariablePlugin extends Plugin {\r\n // Khai báo dependencies nếu cần (VD: Widget)\r\n static get requires() {\r\n return [Widget];\r\n }\r\n\r\n init() {\r\n const editor = this.editor;\r\n const schema = editor.model.schema;\r\n const conversion = editor.conversion;\r\n const editingView = editor.editing.view;\r\n\r\n // 1. Định nghĩa Schema (Model)\r\n schema.register('variable', {\r\n inheritAllFrom: '$inlineObject',\r\n allowAttributes: ['id', 'value', 'display', 'data'],\r\n });\r\n\r\n // 2. Conversion: Model -> View (Hiển thị ra HTML)\r\n conversion.for('downcast').elementToElement({\r\n model: 'variable',\r\n view: (modelItem, { writer: viewWriter }) => {\r\n const id = modelItem.getAttribute('id') as string;\r\n const display = modelItem.getAttribute('display') as string;\r\n const value = modelItem.getAttribute('value') as string;\r\n // Xử lý data (Object -> String)\r\n const rawData = modelItem.getAttribute('data');\r\n const dataJson = rawData ? JSON.stringify(rawData) : '';\r\n const widgetElement = viewWriter.createContainerElement('span', {\r\n class: 'variable-widget',\r\n 'data-id': id,\r\n 'data-value': value,\r\n 'data-display': display,\r\n 'data-json': dataJson,\r\n });\r\n const innerText = viewWriter.createText(`{{${display}}}`);\r\n viewWriter.insert(viewWriter.createPositionAt(widgetElement, 0), innerText);\r\n return toWidget(widgetElement, viewWriter);\r\n },\r\n });\r\n\r\n // 3. Conversion: View -> Model (Khi load data hoặc paste)\r\n conversion.for('upcast').elementToElement({\r\n view: {\r\n name: 'span',\r\n classes: 'variable-widget',\r\n },\r\n model: (viewElement, { writer: modelWriter }) => {\r\n // Lấy text bên trong làm label, bỏ dấu {{ }}\r\n // const textNode = viewElement.getChild(0);\r\n // let label = '';\r\n // if (textNode && textNode.is('$text')) {\r\n // label = textNode.data.replace(/{{|}}/g, '');\r\n // }\r\n const dataJson = viewElement.getAttribute('data-json');\r\n let parsedData = null;\r\n try {\r\n parsedData = dataJson ? JSON.parse(dataJson) : null;\r\n } catch (e) {\r\n console.error('Lỗi parse variable data', e);\r\n }\r\n return modelWriter.createElement('variable', {\r\n id: viewElement.getAttribute('data-id'),\r\n value: viewElement.getAttribute('data-value'),\r\n display: viewElement.getAttribute('data-display'),\r\n data: parsedData, // Lưu vào model dưới dạng Object gốc\r\n });\r\n },\r\n });\r\n\r\n // 4. Xử lý sự kiện Drop\r\n this.listenTo(editingView.document, 'drop', async (evt, data) => {\r\n const dataTransfer = (data as any).dataTransfer;\r\n const jsonData = dataTransfer.getData('ck-variable');\r\n\r\n if (!jsonData) return;\r\n\r\n // Ngăn trình duyệt xử lý mặc định\r\n evt.stop();\r\n\r\n let variable: SdDocumentBuilderVariable = JSON.parse(jsonData);\r\n\r\n const config = editor.config as Config<SdEditorConfig>;\r\n const getOption = config.get('getOption') as SdEditorConfig['getOption'];\r\n const option = getOption?.();\r\n if (option?.onDropVariable) {\r\n const result = await SdResolveMaybeAsync<boolean | SdDocumentBuilderVariable>(option.onDropVariable(variable, 0));\r\n //* Hỗ trợ dữ liệu có sẵn sẽ chỉ cần nhận vào boolean\r\n if (typeof result === 'boolean') {\r\n if (!result) return;\r\n } else {\r\n //* Hỗ trợ dữ liệu lấy từ API (Kiểm tra xem result có đúng định dạng interface SdDocumentBuilderVariable hay không?)\r\n if (this.#isSdDocumentBuilderVariableResult(result)) {\r\n variable = result;\r\n } else {\r\n throw new Error('Dữ liệu variable không hợp lệ');\r\n }\r\n }\r\n }\r\n\r\n // Xác định vị trí thả chính xác (Quan trọng)\r\n // data.dropRange là vị trí con chuột trên View khi thả\r\n const viewRange = (data as any).dropRange;\r\n const modelRange = editor.editing.mapper.toModelRange(viewRange);\r\n\r\n editor.model.change(writer => {\r\n // A. Chèn biến\r\n const variableElem = writer.createElement('variable', {\r\n id: variable.id,\r\n value: variable.value,\r\n display: variable.display,\r\n data: variable.data,\r\n });\r\n\r\n editor.model.insertContent(variableElem, modelRange);\r\n\r\n // B. Đặt con trỏ ra sau biến\r\n writer.setSelection(variableElem, 'after');\r\n\r\n // C. [QUAN TRỌNG] XÓA SẠCH CÁC MARKER DROP\r\n // Thay vì chỉ xóa 'drop-target', ta duyệt tìm tất cả marker có tên bắt đầu bằng 'drop-target'\r\n // Vì đôi khi CKEditor tạo ra các biến thể khác nhau\r\n for (const marker of editor.model.markers) {\r\n if (marker.name.startsWith('drop-target')) {\r\n writer.removeMarker(marker);\r\n }\r\n }\r\n });\r\n\r\n // FIX LỖI: Focus lại vào editor để xóa các artifact của việc kéo thả\r\n editor.editing.view.focus();\r\n\r\n // [BỔ SUNG] XÓA CLASS RÁC TRÊN VIEW (NẾU MARKER KHÔNG HẾT)\r\n // Đôi khi View chưa kịp render lại, ta ép xóa class thủ công trên root nếu cần\r\n // (Thường bước C ở trên là đủ, nhưng đây là chốt chặn cuối cùng bằng JS)\r\n const viewRoot = editor.editing.view.document.getRoot();\r\n if (viewRoot) {\r\n editor.editing.view.change(viewWriter => {\r\n // Loại bỏ class decoration nếu nó bị dính vào root (hiếm gặp nhưng có thể)\r\n viewWriter.removeClass('ck-clipboard-drop-target-position', viewRoot);\r\n viewWriter.removeClass('ck-clipboard-drop-target-line', viewRoot);\r\n });\r\n }\r\n });\r\n // this.listenTo(editingView.document, 'drop', (evt, data) => {\r\n // const config = editor.config as Config<SdEditorConfig>;\r\n // const getOption = config.get('getOption') as SdEditorConfig['getOption'];\r\n // const option = getOption?.();\r\n\r\n // // Dữ liệu kéo thả\r\n // const dataTransfer = (data as any).dataTransfer;\r\n // const jsonData = dataTransfer.getData('ck-variable');\r\n\r\n // if (!jsonData) return;\r\n\r\n // evt.stop();\r\n\r\n // const variable: SdDocumentBuilderVariable = JSON.parse(jsonData);\r\n\r\n // // Gọi callback ra ngoài Angular (nếu có)\r\n // if (option && option.onDropVariable) {\r\n // const allow = option.onDropVariable(variable, 0);\r\n // if (allow === false) return; // Angular chặn drop\r\n // }\r\n\r\n // // Insert vào Model\r\n // editor.model.change(writer => {\r\n // const variableElem = writer.createElement('variable', {\r\n // id: variable.id,\r\n // label: variable.label\r\n // });\r\n // editor.model.insertContent(variableElem);\r\n // });\r\n // });\r\n }\r\n\r\n #isSdDocumentBuilderVariableResult = (obj: any): obj is SdDocumentBuilderVariable => {\r\n return (\r\n obj !== null &&\r\n obj !== undefined &&\r\n typeof obj === 'object' &&\r\n !Array.isArray(obj) &&\r\n typeof obj.id === 'string' &&\r\n typeof obj.value === 'string' &&\r\n typeof obj.display === 'string'\r\n );\r\n };\r\n}\r\n","import { Plugin } from 'ckeditor5';\r\n\r\nexport class TableFitPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n // Can thiệp vào quá trình convert từ View (HTML Paste) sang Model\r\n editor.conversion.for('upcast').add(dispatcher => {\r\n dispatcher.on(\r\n 'element:table',\r\n (evt, data, conversionApi) => {\r\n // 1. Gọi consume để báo với CKEditor là chúng ta sẽ xử lý element này\r\n if (!conversionApi.consumable.consume(data.viewItem, { name: true })) {\r\n return;\r\n }\r\n\r\n // 2. Thực hiện chuyển đổi mặc định để tạo ra model element\r\n const { modelCursor, modelRange } = conversionApi.convertChildren(data.viewItem, data.modelCursor);\r\n\r\n // 3. Bây giờ modelRange chắc chắn tồn tại, ta tìm element table trong đó\r\n for (const item of modelRange.getItems()) {\r\n if (item.is('element', 'table')) {\r\n editor.model.change(writer => {\r\n writer.setAttribute('tableWidth', '100%', item);\r\n });\r\n }\r\n }\r\n\r\n // 4. Cập nhật modelCursor để dispatcher biết đã xử lý xong tới đâu\r\n data.modelRange = modelRange;\r\n data.modelCursor = modelCursor;\r\n },\r\n { priority: 'low' }\r\n );\r\n // Chạy sau cùng để ghi đè các logic mặc định\r\n });\r\n\r\n // Lắng nghe lệnh insertTable để can thiệp ngay sau khi bảng được tạo\r\n const insertTableCommand = editor.commands.get('insertTable');\r\n\r\n if (insertTableCommand) {\r\n // Dùng 'on' event để hook vào sau khi lệnh thực thi\r\n this.listenTo(insertTableCommand, 'execute', (evt, args) => {\r\n editor.model.change(writer => {\r\n // Lấy vị trí con trỏ hiện tại (nơi bảng vừa được chèn)\r\n const selection = editor.model.document.selection;\r\n const position = selection.getFirstPosition();\r\n\r\n if (!position) return;\r\n\r\n // Tìm element table vừa chèn (nó nằm ở vị trí cha của selection)\r\n // Khi vừa insert, con trỏ thường nằm trong ô đầu tiên của bảng\r\n const tableElement = position.findAncestor('table');\r\n\r\n if (tableElement) {\r\n // Ép width 100% cho bảng mới vẽ\r\n writer.setAttribute('tableWidth', '100%', tableElement);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n}\r\n","import { Plugin } from 'ckeditor5';\r\n\r\n/**\r\n * Custom base64 upload adapter plugin for CKEditor 5.\r\n * Converts uploaded images to base64 data URLs instead of uploading to a server.\r\n */\r\nexport class ImageUploadPlugin extends Plugin {\r\n static get pluginName() {\r\n return 'ImageUploadPlugin' as const;\r\n }\r\n\r\n init() {\r\n const editor = this.editor;\r\n\r\n // Register the custom upload adapter\r\n editor.plugins.get('FileRepository').createUploadAdapter = (loader: any) => {\r\n return new Base64UploadAdapter(loader);\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Custom upload adapter that converts images to base64 data URLs.\r\n */\r\nclass Base64UploadAdapter {\r\n private loader: any;\r\n\r\n constructor(loader: any) {\r\n this.loader = loader;\r\n }\r\n\r\n /**\r\n * Starts the upload process and converts the file to base64.\r\n * @returns Promise that resolves with the base64 URL\r\n */\r\n upload(): Promise<{ default: string }> {\r\n return this.loader.file.then((file: File) => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n\r\n reader.onload = () => {\r\n const base64Url = reader.result as string;\r\n resolve({ default: base64Url });\r\n };\r\n\r\n reader.onerror = () => {\r\n reject('Failed to convert image to base64');\r\n };\r\n\r\n reader.readAsDataURL(file);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Aborts the upload process.\r\n */\r\n abort(): void {\r\n // For base64 conversion, there's nothing to abort\r\n // This method is required by the UploadAdapter interface\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { Component, EventEmitter, Input, Output } from '@angular/core';\r\nimport { CKEditorModule } from '@ckeditor/ckeditor5-angular';\r\n\r\nimport {\r\n Bold,\r\n ClassicEditor,\r\n Essentials,\r\n GeneralHtmlSupport,\r\n Heading,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n FontFamily,\r\n Italic,\r\n List,\r\n ModelElement,\r\n ModelRange,\r\n PageBreak,\r\n Paragraph,\r\n PasteFromOffice,\r\n Table, // <--- 1. Quản lý viền/màu của cả bảng\r\n TableCellProperties, // <--- 2. Quản lý viền/màu của từng ô\r\n TableColumnResize,\r\n TableProperties,\r\n TableToolbar,\r\n Underline,\r\n Undo,\r\n Alignment, // Canh lề\r\n Subscript, // Mũ dưới (H₂O)\r\n Superscript,\r\n Image,\r\n ImageUpload,\r\n ImageToolbar,\r\n ImageCaption,\r\n ImageResize,\r\n ImageStyle,\r\n} from 'ckeditor5';\r\nimport {\r\n SdDocumentBuilderComment,\r\n SdDocumentBuilderHeading,\r\n SdDocumentBuilderOption,\r\n SdDocumentBuilderVariable,\r\n SdEditorConfig,\r\n} from './document-builder.model';\r\nimport { CommentPlugin, PageOrientationPlugin, TableFitPlugin, VariablePlugin, ImageUploadPlugin } from './plugins';\r\nimport { SdUtilities } from '@sd-angular/core/utilities/extensions';\r\nimport { throttleTime, Subject, Subscription } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'sd-document-builder',\r\n standalone: true,\r\n imports: [CommonModule, CKEditorModule],\r\n templateUrl: './document-builder.component.html',\r\n styleUrls: [\r\n './document-builder.component.scss',\r\n './plugins/comment.plugin.scss',\r\n './plugins/variable.plugin.scss',\r\n './plugins/table-fit.plugin.scss',\r\n './scss/toolbar.scss',\r\n ],\r\n // changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class SdDocumentBuilder {\r\n #id = '1212';\r\n\r\n @Input({ required: true }) option!: SdDocumentBuilderOption;\r\n disabled = false;\r\n\r\n @Input('disabled') set _disabled(val: boolean | '' | undefined | null) {\r\n this.disabled = val === '' || !!val;\r\n this.#updateState();\r\n }\r\n\r\n Editor = ClassicEditor;\r\n #editor!: ClassicEditor;\r\n\r\n // Config\r\n config: SdEditorConfig = {\r\n getOption: () => this.option,\r\n licenseKey: 'GPL', // Hoặc key thương mại nếu có\r\n plugins: [\r\n GeneralHtmlSupport,\r\n FontSize,\r\n FontColor,\r\n FontFamily,\r\n FontBackgroundColor,\r\n Bold,\r\n Italic,\r\n Underline,\r\n Essentials,\r\n Paragraph,\r\n Heading,\r\n List,\r\n Table,\r\n TableToolbar,\r\n TableProperties,\r\n TableCellProperties,\r\n TableColumnResize,\r\n PasteFromOffice,\r\n PageBreak,\r\n Undo,\r\n Alignment, // Canh lề\r\n Subscript, // Mũ dưới (H₂O)\r\n Superscript, // Mũ trên (x²)\r\n // Image\r\n Image,\r\n ImageUpload,\r\n ImageToolbar,\r\n ImageCaption,\r\n ImageResize,\r\n ImageStyle,\r\n // Custom Plugin\r\n PageOrientationPlugin,\r\n CommentPlugin,\r\n VariablePlugin,\r\n TableFitPlugin,\r\n ImageUploadPlugin,\r\n ],\r\n toolbar: {\r\n items: [\r\n 'pageOrientation',\r\n '|',\r\n 'heading',\r\n 'fontFamily',\r\n '|',\r\n 'fontSize',\r\n 'fontColor',\r\n 'fontBackgroundColor',\r\n '|',\r\n 'bold',\r\n 'italic',\r\n 'underline',\r\n 'subscript',\r\n 'superscript',\r\n '|',\r\n 'alignment',\r\n 'bulletedList',\r\n 'numberedList',\r\n '|',\r\n 'insertTable',\r\n 'imageUpload',\r\n 'pageBreak',\r\n '|',\r\n 'undo',\r\n 'redo',\r\n '|',\r\n 'addCommentBtn',\r\n ],\r\n shouldNotGroupWhenFull: true,\r\n },\r\n\r\n image: {\r\n toolbar: ['toggleImageCaption', '|', 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side'],\r\n },\r\n\r\n fontSize: {\r\n options: [\r\n // Định nghĩa từng size một cách tường minh\r\n {\r\n title: '9',\r\n model: '9pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '9pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '10',\r\n model: '10pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '10pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '11',\r\n model: '11pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '11pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '12',\r\n model: '12pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '12pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '13',\r\n model: '13pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '13pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '14',\r\n model: '14pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '14pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '16',\r\n model: '16pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '16pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '18',\r\n model: '18pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '18pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '20',\r\n model: '20pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '20pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '24',\r\n model: '24pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '24pt' },\r\n priority: 7,\r\n },\r\n },\r\n ],\r\n supportAllValues: false, // Khuyên dùng false để ép user chọn đúng size chuẩn\r\n },\r\n // 4. Cấu hình bảng màu (Tùy chọn)\r\n fontColor: {\r\n columns: 5,\r\n documentColors: 10,\r\n },\r\n fontBackgroundColor: {\r\n columns: 5,\r\n documentColors: 10,\r\n },\r\n table: {\r\n contentToolbar: [\r\n 'tableColumn',\r\n 'tableRow',\r\n 'mergeTableCells',\r\n '|',\r\n 'tableProperties', // <--- Nút chỉnh thuộc tính bảng (Viền, Màu, Width)\r\n 'tableCellProperties',\r\n ],\r\n },\r\n // Quan trọng: Cho phép paste style từ Word nhưng bỏ qua margin/padding\r\n htmlSupport: {\r\n allow: [\r\n {\r\n name: /.*/,\r\n attributes: /.*/, // attributes chấp nhận boolean\r\n classes: /.*/, // Cho phép mọi class\r\n styles: {\r\n // Cho phép tất cả styles trừ margin và padding\r\n match: /^(?!margin|padding).*/,\r\n },\r\n },\r\n ],\r\n },\r\n };\r\n @Output() contentChange = new EventEmitter<string>(); // Emit HTML content\r\n #subscription = new Subscription();\r\n #contentChangeSubject = new Subject<string>();\r\n #editorChangeRxjs = new Subject<void>();\r\n\r\n ngOnInit() {\r\n // https://onemount.atlassian.net/browse/SM-1862\r\n // Debounce trong rxjs không hỗ trợ leading -->\r\n this.#subscription.add(\r\n this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {\r\n this.contentChange.emit(content);\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n onReady(editor: ClassicEditor) {\r\n this.#editor = editor;\r\n\r\n // Setup orientation plugin callback\r\n try {\r\n const orientationPlugin = editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.onOrientationChange === 'function') {\r\n orientationPlugin.onOrientationChange(orientation => {\r\n this.option.onOrientation?.(orientation);\r\n });\r\n\r\n // Set initial orientation if provided\r\n if (this.option.orientation) {\r\n orientationPlugin.setOrientation(this.option.orientation);\r\n }\r\n }\r\n } catch (error) {\r\n console.warn('PageOrientationPlugin not available:', error);\r\n }\r\n\r\n // Đăng ký sự kiện lắng nghe Selection để làm Comment\r\n editor.model.document.selection.on('change', $event => {\r\n this.option.onSelection?.(this.#editor.model.document.selection, $event);\r\n });\r\n // ⭐ ĐĂNG KÝ SỰ KIỆN LẮNG NGHE THAY ĐỔI NỘI DUNG\r\n editor.model.document.on('change:data', () => {\r\n const content = editor.getData();\r\n this.#contentChangeSubject.next(content);\r\n });\r\n this.#updateState();\r\n }\r\n\r\n #updateState(): void {\r\n if (!this.#editor) return;\r\n if (this.disabled) {\r\n // Bật chế độ chỉ đọc với ID khóa\r\n this.#editor.enableReadOnlyMode(this.#id);\r\n } else {\r\n // Tắt chế độ chỉ đọc với ID khóa tương ứng\r\n this.#editor.disableReadOnlyMode(this.#id);\r\n }\r\n }\r\n\r\n scrollToComment = (markerId: string) => {\r\n if (!this.#editor) return;\r\n\r\n const editor = this.#editor;\r\n const marker = editor.model.markers.get(markerId);\r\n\r\n if (marker) {\r\n // 1. Set Selection vào Marker đó trước\r\n this.#editor.model.change(writer => {\r\n writer.setSelection(marker.getRange());\r\n });\r\n\r\n // 2. Sau đó gọi scrollToTheSelection\r\n this.#editor.editing.view.scrollToTheSelection({\r\n alignToTop: true,\r\n });\r\n editor.editing.view.focus();\r\n } else {\r\n console.warn(`Marker with id ${markerId} not found.`);\r\n }\r\n };\r\n\r\n setContent = (html: string) => {\r\n this.#editor?.setData?.(html);\r\n };\r\n\r\n getContent = () => {\r\n if (this.#editor) {\r\n return this.#editor.getData();\r\n }\r\n return '';\r\n };\r\n\r\n setOrientation = (orientation: 'PORTRAIT' | 'LANDSCAPE'): void => {\r\n if (!this.#editor) return;\r\n\r\n try {\r\n const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.setOrientation === 'function') {\r\n orientationPlugin.setOrientation(orientation);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to set orientation:', error);\r\n }\r\n };\r\n\r\n getOrientation = (): 'PORTRAIT' | 'LANDSCAPE' => {\r\n if (!this.#editor) return 'PORTRAIT';\r\n\r\n try {\r\n const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.getOrientation === 'function') {\r\n return orientationPlugin.getOrientation();\r\n }\r\n } catch (error) {\r\n console.warn('Failed to get orientation:', error);\r\n }\r\n\r\n return 'PORTRAIT';\r\n };\r\n\r\n getVariables = (): SdDocumentBuilderVariable[] => {\r\n if (!this.#editor) return [];\r\n\r\n const model = this.#editor.model;\r\n const root = model.document.getRoot();\r\n\r\n if (!root) return [];\r\n\r\n const variables: SdDocumentBuilderVariable[] = [];\r\n // Duyệt qua tất cả các phần tử trong range\r\n // range.getItems() sẽ trả về từng node (text, element...)\r\n try {\r\n const range = model.createRangeIn(root);\r\n\r\n for (const item of range.getItems()) {\r\n // Sử dụng item.is('element', 'variable') là chính xác\r\n if (item.is('element', 'variable')) {\r\n variables.push({\r\n id: item.getAttribute('id') as string,\r\n value: item.getAttribute('value') as string,\r\n display: item.getAttribute('display') as string,\r\n data: item.getAttribute('data'),\r\n });\r\n }\r\n }\r\n } catch (e) {\r\n console.error(e);\r\n return [];\r\n }\r\n\r\n return variables;\r\n };\r\n\r\n getComments(): SdDocumentBuilderComment[] {\r\n if (!this.#editor) return [];\r\n\r\n const markers = this.#editor.model.markers;\r\n const comments: SdDocumentBuilderComment[] = [];\r\n\r\n // Duyệt qua tất cả markers trong Model\r\n for (const marker of markers) {\r\n // Chỉ lấy marker do plugin comment tạo ra (prefix 'comment:')\r\n if (marker.name.startsWith('comment:')) {\r\n // Lấy text nằm trong vùng marker đó\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n comments.push({\r\n markerId: marker.name,\r\n selectedText: currentText,\r\n });\r\n }\r\n }\r\n\r\n return comments;\r\n }\r\n\r\n scrollToTop() {\r\n setTimeout(() => {\r\n if (this.#editor) {\r\n const editableElement = this.#editor.ui.view.editable.element;\r\n if (editableElement) {\r\n const scrollContainer = editableElement.closest('.builder-container');\r\n if (scrollContainer) {\r\n scrollContainer.scrollTo({\r\n top: 0,\r\n behavior: 'smooth',\r\n });\r\n } else {\r\n editableElement.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }\r\n }\r\n }, 100);\r\n }\r\n\r\n // Kho lưu trữ tham chiếu Model của Heading (để phục vụ scroll)\r\n #headingElementsMap = new Map<string, ModelElement>();\r\n heading = {\r\n // ========================================================================\r\n // HÀM LẤY DANH SÁCH HEADING (TOC)\r\n // ========================================================================\r\n getHeadings: (): SdDocumentBuilderHeading[] => {\r\n if (!this.#editor) return [];\r\n\r\n const root = this.#editor.model.document.getRoot();\r\n if (!root) return [];\r\n\r\n // Reset lại map mỗi lần quét\r\n this.#headingElementsMap.clear();\r\n\r\n const headings: SdDocumentBuilderHeading[] = [];\r\n const range = this.#editor.model.createRangeIn(root);\r\n\r\n // Biến đếm để tạo ID unique\r\n let index = 0;\r\n\r\n for (const item of range.getItems()) {\r\n // Kiểm tra xem item có phải là Element và tên bắt đầu bằng 'heading' không\r\n if (item.is('element') && item.name.startsWith('heading')) {\r\n // 1. Lấy text của heading\r\n const text = this.#getTextFromElement(item);\r\n // 2. Xác định Level (heading1 -> 1, heading2 -> 2)\r\n // item.name có dạng 'heading1', 'heading2'\r\n const level = parseInt(item.name.replace('heading', ''), 10) || 1;\r\n // 3. Tạo ID runtime (Dùng để map khi click scroll)\r\n // Bạn có thể generate slug từ text nếu muốn, ở đây mình dùng index cho đơn giản và unique\r\n const id = `heading_${index}_${Date.now()}`;\r\n // 4. Lưu tham chiếu Model Element vào Map\r\n this.#headingElementsMap.set(id, item as ModelElement);\r\n headings.push({\r\n id: id,\r\n text: text,\r\n level: level,\r\n type: item.name,\r\n });\r\n index++;\r\n }\r\n }\r\n\r\n return headings;\r\n },\r\n // ========================================================================\r\n // HÀM SCROLL TO HEADING\r\n // ========================================================================\r\n scrollToHeading: (id: string) => {\r\n if (!this.#editor) return;\r\n\r\n // 1. Lấy Model Element từ kho lưu trữ\r\n const modelElement = this.#headingElementsMap.get(id);\r\n\r\n if (modelElement) {\r\n const editor = this.#editor;\r\n const view = editor.editing.view;\r\n // 2. Chuyển đổi Model Element -> View Element\r\n // mapper.toViewElement sẽ trả về thẻ HTML ảo (View Element) tương ứng (ví dụ thẻ <h2>)\r\n const viewElement = editor.editing.mapper.toViewElement(modelElement);\r\n if (viewElement) {\r\n // 3. Từ View Element ảo -> Lấy ra DOM thật (HTMLElement)\r\n const domElement = view.domConverter.mapViewToDom(viewElement);\r\n\r\n if (domElement) {\r\n // 4. Dùng hàm native của trình duyệt để cuộn\r\n domElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start',\r\n inline: 'nearest',\r\n });\r\n // 5. (Tùy chọn) Focus và đặt con trỏ vào đó\r\n view.focus();\r\n editor.model.change(writer => {\r\n writer.setSelection(modelElement, 'on');\r\n });\r\n }\r\n }\r\n } else {\r\n console.warn(`Heading with id ${id} not found.`);\r\n }\r\n },\r\n };\r\n\r\n // ========================================================================\r\n // HELPER: LẤY TEXT TỪ ELEMENT (Đệ quy nhẹ)\r\n // ========================================================================\r\n #getTextFromElement = (element: ModelElement): string => {\r\n let text = '';\r\n // Heading trong Model chứa các text node con\r\n for (const child of element.getChildren()) {\r\n if (child.is('$text') || child.is('$textProxy')) {\r\n text += (child as any).data;\r\n }\r\n }\r\n return text;\r\n };\r\n\r\n #getTextFromRange = (range: ModelRange): string => {\r\n let text = '';\r\n for (const item of range.getItems()) {\r\n // TextProxy là một phần của Text Node nằm trong Range\r\n if (item.is('$textProxy') || item.is('$text')) {\r\n text += (item as any).data;\r\n }\r\n }\r\n return text;\r\n };\r\n\r\n // ========================================================================\r\n // COMMENT MANAGEMENT\r\n // ========================================================================\r\n comment = {\r\n /**\r\n * Lấy tất cả comments trong document\r\n * @returns Danh sách tất cả comments\r\n */\r\n all: (): SdDocumentBuilderComment[] => {\r\n if (!this.#editor) return [];\r\n\r\n const markers = this.#editor.model.markers;\r\n const comments: SdDocumentBuilderComment[] = [];\r\n\r\n // Duyệt qua tất cả markers trong Model\r\n for (const marker of markers) {\r\n // Chỉ lấy marker do plugin comment tạo ra (prefix 'comment:')\r\n if (marker.name.startsWith('comment:')) {\r\n // Lấy text nằm trong vùng marker đó\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n comments.push({\r\n markerId: marker.name,\r\n selectedText: currentText,\r\n });\r\n }\r\n }\r\n\r\n return comments;\r\n },\r\n\r\n /**\r\n * Thêm comment vào vùng text đang được chọn\r\n * @param comment - Dữ liệu comment\r\n * @param data - Dữ liệu extra data\r\n * @returns SdDocumentBuilderComment hoặc null nếu không có text được chọn\r\n */\r\n add: <T = any>(range: ModelRange, comment: string, data?: T): SdDocumentBuilderComment<T> | null => {\r\n if (!this.#editor) return null;\r\n const model = this.#editor.model;\r\n if (!range) return null;\r\n // 3. Lấy text từ range\r\n const selectedText = this.#getTextFromRange(range);\r\n if (!selectedText.trim()) {\r\n console.warn('Selected text is empty');\r\n return null;\r\n }\r\n // 4. Tạo ID unique cho marker\r\n const markerId = `comment:${Date.now()}`;\r\n // 5. Tạo marker trong model\r\n model.change(writer => {\r\n writer.addMarker(markerId, {\r\n range,\r\n usingOperation: true, // Quan trọng: Cho phép undo/redo\r\n affectsData: true, // Lưu marker vào data khi getData()\r\n });\r\n });\r\n return {\r\n markerId,\r\n selectedText,\r\n comment,\r\n createdAt: new Date(),\r\n data,\r\n };\r\n },\r\n\r\n /**\r\n * Cập nhật nội dung comment\r\n * @param markerId - ID của marker\r\n * @param commentData - Dữ liệu mới\r\n * @returns Comment đã cập nhật hoặc null\r\n */\r\n update: <T = any>(markerId: string, comment: string, data?: T): SdDocumentBuilderComment<T> | null => {\r\n if (!this.#editor) return null;\r\n const marker = this.#editor.model.markers.get(markerId);\r\n if (!marker) {\r\n console.warn(`Marker ${markerId} not found`);\r\n return null;\r\n }\r\n // Lấy text hiện tại từ marker (có thể đã thay đổi)\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n return {\r\n markerId: markerId,\r\n selectedText: currentText,\r\n comment,\r\n data,\r\n };\r\n },\r\n\r\n /**\r\n * Lấy chi tiết comment theo markerId\r\n * @param markerId - ID của marker\r\n * @returns Comment hoặc null\r\n */\r\n detail: (markerId: string): SdDocumentBuilderComment | null => {\r\n if (!this.#editor) return null;\r\n const marker = this.#editor.model.markers.get(markerId);\r\n if (!marker) return null;\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n return {\r\n markerId: markerId,\r\n selectedText: currentText,\r\n };\r\n },\r\n\r\n /**\r\n * Xóa comment theo markerId\r\n * @param markerId - ID của marker cần xóa\r\n * @returns true nếu xóa thành công, false nếu không tìm thấy\r\n */\r\n remove: (markerId: string): boolean => {\r\n if (!this.#editor) return false;\r\n const model = this.#editor.model;\r\n const marker = model.markers.get(markerId);\r\n if (!marker) {\r\n console.warn(`Marker ${markerId} not found`);\r\n return false;\r\n }\r\n model.change(writer => {\r\n writer.removeMarker(markerId);\r\n });\r\n return true;\r\n },\r\n\r\n /**\r\n * Scroll đến vị trí comment\r\n * @param markerId - ID của marker cần scroll tới\r\n */\r\n scroll: (markerId: string): void => {\r\n if (!this.#editor) return;\r\n const editor = this.#editor;\r\n const marker = editor.model.markers.get(markerId);\r\n if (marker) {\r\n // 1. Set Selection vào Marker đó trước\r\n editor.model.change(writer => {\r\n writer.setSelection(marker.getRange());\r\n });\r\n\r\n // 2. Sau đó gọi scrollToTheSelection\r\n editor.editing.view.scrollToTheSelection({\r\n alignToTop: true,\r\n });\r\n editor.editing.view.focus();\r\n } else {\r\n console.warn(`Marker with id ${markerId} not found.`);\r\n }\r\n },\r\n };\r\n\r\n // exportDocx(fileName: string = 'document.docx'): void {\r\n // if (!this.#editor) return;\r\n\r\n // // 1. Kiểm tra xem Editor đang ở chế độ Landscape hay Portrait\r\n // // (Dựa vào class 'landscape' mà Plugin PageOrientation đã toggle trên View)\r\n // const rootElement = this.#editor.editing.view.document.getRoot();\r\n // const isLandscape = rootElement?.hasClass('landscape');\r\n\r\n // const orientation = isLandscape ? 'landscape' : 'portrait';\r\n\r\n // // 2. Lấy nội dung HTML\r\n // const contentHtml = this.#editor.getData();\r\n\r\n // // 3. Chuẩn bị HTML với CSS @page động\r\n // const fullHtml = `\r\n // <!DOCTYPE html>\r\n // <html>\r\n // <head>\r\n // <meta charset=\"UTF-8\">\r\n // <style>\r\n // /* --- CẤU HÌNH KHỔ GIẤY DỰA TRÊN TRẠNG THÁI --- */\r\n // @page {\r\n // size: A4 ${orientation}; /* Thêm portrait hoặc landscape vào đây */\r\n // margin: 20mm;\r\n // }\r\n\r\n // body {\r\n // font-family: 'Times New Roman', serif;\r\n // font-size: 13pt;\r\n // line-height: 1.5;\r\n // }\r\n\r\n // /* --- STYLE CHO BẢNG BIỂU --- */\r\n // table {\r\n // width: 100%;\r\n // border-collapse: collapse;\r\n // }\r\n // td, th {\r\n // border: 1px solid black;\r\n // padding: 5px;\r\n // }\r\n\r\n // /* --- STYLE CHO BIẾN --- */\r\n // .variable-widget {\r\n // color: #1565c0;\r\n // background-color: #e3f2fd;\r\n // font-weight: bold;\r\n // border: 1px solid #90caf9;\r\n // padding: 0 4px;\r\n // border-radius: 4px;\r\n // }\r\n\r\n // /* --- ẨN COMMENT KHI IN --- */\r\n // .ck-comment-marker {\r\n // background-color: transparent;\r\n // border: none;\r\n // }\r\n // </style>\r\n // </head>\r\n // <body>\r\n // ${contentHtml}\r\n // </body>\r\n // </html>\r\n // `;\r\n\r\n // // 3. Convert sang Blob (Dạng file Binary)\r\n // asBlob(fullHtml, {\r\n // orientation: 'portrait', // 'portrait' hoặc 'landscape'\r\n // margins: { top: 720, right: 720, bottom: 720, left: 720 }, // Đơn vị twips (1440 twips = 1 inch)\r\n // }).then(blob => {\r\n // if (blob instanceof Blob) {\r\n // SdUtilities.downloadBlob(blob, fileName);\r\n // }\r\n // });\r\n // }\r\n\r\n // ========================================================================\r\n // 4. HÀM EXPORT DOCX (FULL HEADER/FOOTER + PAGE NUMBER)\r\n // ========================================================================\r\n /**\r\n * Xuất file Word có Header/Footer\r\n * @param fileName Tên file\r\n * @param headerText Nội dung Header (hoặc HTML)\r\n * '<p style=\"text-align: center; font-weight: bold;\">CÔNG TY CỔ PHẦN CÔNG NGHỆ ABC</p>'\r\n * @param footerText Nội dung Footer (hoặc HTML)\r\n * '<p style=\"text-align: right; font-size: 10pt;\">Trang <span style=\"mso-field-code: PAGE\"></span> / <span style=\"mso-field-code: NUMPAGES\"></span></p>'\r\n */\r\n exportDocx(args: { fileName?: string; header?: string; footer?: string }): void {\r\n if (!this.#editor) return;\r\n const fileName = args?.fileName || `document_${Date.now()}.docx`;\r\n const header = args?.header || ``;\r\n const footer = args?.footer || ``;\r\n // 1. Kiểm tra xoay giấy\r\n const rootElement = this.#editor.editing.view.document.getRoot();\r\n const isLandscape = rootElement?.hasClass('landscape');\r\n const orientation = isLandscape ? 'landscape' : 'portrait';\r\n\r\n // Kích thước giấy cho Word (A4)\r\n // Portrait: 21cm x 29.7cm\r\n // Landscape: 29.7cm x 21cm\r\n // @page size trong CSS Word đôi khi cần set cứng width/height để header không bị lệch\r\n const pageCss = isLandscape\r\n ? 'size: 29.7cm 21cm; mso-page-orientation: landscape;'\r\n : 'size: 21cm 29.7cm; mso-page-orientation: portrait;';\r\n\r\n const contentHtml = this.#editor.getData();\r\n\r\n // 2. TẠO HTML CHUẨN MICROSOFT WORD XML\r\n // Phải có xmlns:o và xmlns:w thì Word mới hiểu được các lệnh mso-\r\n const fullHtml = `\r\n <html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <title>Export Document</title>\r\n \r\n <style>\r\n /* --- 1. SETUP TRANG GIẤY & HEADER/FOOTER --- */\r\n @page {\r\n ${pageCss}\r\n margin: 2.0cm; /* Lề chuẩn 2cm */\r\n \r\n /* Kỹ thuật map ID của Word */\r\n mso-header: header1;\r\n mso-footer: footer1;\r\n }\r\n\r\n /* Quan trọng: Ẩn các div header/footer khỏi luồng văn bản chính */\r\n /* Chúng sẽ chỉ hiện thị khi được @page gọi thông qua mso-header/footer */\r\n div#header1 { display: none; }\r\n div#footer1 { display: none; }\r\n\r\n /* --- 2. STYLE CƠ BẢN --- */\r\n body {\r\n font-family: 'Times New Roman', serif;\r\n font-size: 13pt;\r\n line-height: 1.5;\r\n tab-interval: 36pt;\r\n }\r\n \r\n /* Style Bảng */\r\n table { width: 100%; border-collapse: collapse; }\r\n td, th { border: 1px solid black; padding: 5px; }\r\n\r\n /* Style Biến (Giữ nguyên giao diện đẹp của bạn) */\r\n .variable-widget {\r\n color: #1565c0; font-weight: bold;\r\n background: #e3f2fd; padding: 0 4px; border-radius: 4px;\r\n border: 1px solid #90caf9;\r\n }\r\n \r\n /* Ẩn Comment khi in/xuất file */\r\n .ck-comment-marker { background-color: transparent; border: none; text-decoration: none; }\r\n </style>\r\n </head>\r\n <body>\r\n \r\n <div id=\"header1\">\r\n <div style=\"mso-element:header\">\r\n ${header}\r\n <div style='border-bottom: 1px solid #000; margin-top: 5px; margin-bottom: 20px;'></div>\r\n </div>\r\n </div>\r\n\r\n <div id=\"footer1\">\r\n <div style=\"mso-element:footer\">\r\n <div style='border-top: 1px solid #000; margin-top: 20px; margin-bottom: 5px;'></div>\r\n ${footer}\r\n </div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n ${contentHtml}\r\n </div>\r\n\r\n </body>\r\n </html>\r\n `;\r\n\r\n // 3. TẠO BLOB VÀ TẢI XUỐNG\r\n // Lưu ý: Dùng type 'application/msword' thay vì dùng thư viện html-docx-js\r\n // Thêm '\\ufeff' (BOM) để fix lỗi font tiếng Việt\r\n const blob = new Blob(['\\ufeff', fullHtml], { type: 'application/msword' });\r\n SdUtilities.downloadBlob(blob, fileName);\r\n // 3. Convert & Save\r\n // asBlob(fullHtml, {\r\n // orientation: orientation as 'portrait' | 'landscape',\r\n // margins: { top: 720, right: 720, bottom: 720, left: 720 },\r\n // }).then(blob => {\r\n // if (blob instanceof Blob) {\r\n // SdUtilities.downloadBlob(blob, fileName);\r\n // }\r\n // });\r\n }\r\n}\r\n","<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-document-builder.mjs","sources":["../../../projects/sd-angular/components/document-builder/src/components/header-footer-builder/plugins/page-number.plugin.ts","../../../projects/sd-angular/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.ts","../../../projects/sd-angular/components/document-builder/src/plugins/page-orientation.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/comment.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/variable.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/table-fit.plugin.ts","../../../projects/sd-angular/components/document-builder/src/plugins/image-upload.plugin.ts","../../../projects/sd-angular/components/document-builder/src/document-builder.component.ts","../../../projects/sd-angular/components/document-builder/src/document-builder.component.html","../../../projects/sd-angular/components/document-builder/sd-angular-core-components-document-builder.ts"],"sourcesContent":["import { Plugin, ButtonView } from 'ckeditor5';\r\n\r\nexport class PageNumberPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n // 1. Đăng ký nút \"Số trang hiện tại\"\r\n editor.ui.componentFactory.add('pageNumber', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n view.set({\r\n label: 'Số trang hiện tại',\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H4V4h12v12zM6 6h2v2H6zm0 4h2v2H6zm0 4h2v2H6zm4-8h4v2h-4zm0 4h4v2h-4zm0 4h4v2h-4z\"/></svg>', // Icon đơn giản\r\n tooltip: true\r\n });\r\n\r\n // Khi bấm nút -> Chèn HTML đánh dấu\r\n view.on('execute', () => {\r\n editor.model.change(writer => {\r\n const viewFragment = editor.data.processor.toView(\r\n // Đây là HTML chuẩn để Word hiểu là số trang (dùng cho cách xuất MHTML/.doc)\r\n // Hoặc là marker để Backend replace\r\n '<span class=\"page-number-marker\" style=\"mso-field-code: PAGE; background: #eee; border: 1px dashed #999; padding: 0 4px;\">[PAGE]</span> ' \r\n );\r\n const modelFragment = editor.data.toModel(viewFragment);\r\n editor.model.insertContent(modelFragment);\r\n });\r\n });\r\n return view;\r\n });\r\n\r\n // 2. Đăng ký nút \"Tổng số trang\"\r\n editor.ui.componentFactory.add('totalPages', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n view.set({\r\n label: 'Tổng số trang',\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/></svg>',\r\n tooltip: true\r\n });\r\n\r\n view.on('execute', () => {\r\n editor.model.change(writer => {\r\n const viewFragment = editor.data.processor.toView(\r\n '<span class=\"total-page-marker\" style=\"mso-field-code: NUMPAGES; background: #eee; border: 1px dashed #999; padding: 0 4px;\">[TOTAL]</span> '\r\n );\r\n const modelFragment = editor.data.toModel(viewFragment);\r\n editor.model.insertContent(modelFragment);\r\n });\r\n });\r\n return view;\r\n });\r\n }\r\n}","import { Component, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { CKEditorModule } from '@ckeditor/ckeditor5-angular';\r\n\r\nimport {\r\n ClassicEditor,\r\n EditorConfig,\r\n Essentials,\r\n Paragraph,\r\n Bold,\r\n Italic,\r\n Underline,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n Alignment,\r\n // Import Plugin tự viết\r\n // PageNumberPlugin (nếu import từ file ngoài)\r\n} from 'ckeditor5';\r\nimport { PageNumberPlugin } from './plugins/page-number.plugin';\r\n\r\n@Component({\r\n selector: 'sd-header-footer-builder',\r\n standalone: true,\r\n imports: [CommonModule, CKEditorModule],\r\n template: `\r\n <div class=\"header-footer-editor-wrapper\">\r\n <ckeditor [editor]=\"Editor\" [config]=\"config\" (ready)=\"onReady($event)\"> </ckeditor>\r\n </div>\r\n `,\r\n styles: [\r\n `\r\n /* Style tối giản cho vùng soạn thảo Header/Footer */\r\n :host ::ng-deep .header-footer-editor-wrapper .ck-editor__editable_inline {\r\n min-height: 100px; /* Header thường ngắn */\r\n max-height: 200px;\r\n padding: 10px 20px;\r\n border: 1px solid #ddd;\r\n }\r\n\r\n /* Style hiển thị cho Placeholder số trang trong lúc soạn thảo */\r\n :host ::ng-deep .page-number-marker,\r\n :host ::ng-deep .total-page-marker {\r\n font-size: 11px;\r\n color: #555;\r\n cursor: default;\r\n user-select: none;\r\n }\r\n `,\r\n ],\r\n})\r\nexport class SdHeaderFooterBuilder {\r\n #editor!: ClassicEditor;\r\n Editor = ClassicEditor;\r\n\r\n #model: string | undefined | null;\r\n @Input() set model(value: string | undefined | null) {\r\n if (this.#model !== value) {\r\n this.#model = value;\r\n }\r\n }\r\n\r\n @Output() modelChange = new EventEmitter<string>();\r\n config: EditorConfig = {\r\n licenseKey: 'GPL', // Hoặc key thương mại nếu có\r\n // 1. PLUGIN RÚT GỌN (Bỏ Table, List, PageBreak...)\r\n plugins: [\r\n Essentials,\r\n Paragraph,\r\n Bold,\r\n Italic,\r\n Underline,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n Alignment,\r\n PageNumberPlugin, // <--- Plugin số trang\r\n ],\r\n // 2. TOOLBAR ĐƠN GIẢN\r\n toolbar: {\r\n items: [\r\n 'undo',\r\n 'redo',\r\n '|',\r\n 'fontSize',\r\n 'fontColor',\r\n '|',\r\n 'bold',\r\n 'italic',\r\n 'underline',\r\n '|',\r\n 'alignment', // Căn trái/phải/giữa (Quan trọng cho Header/Footer)\r\n '|',\r\n 'pageNumber',\r\n 'totalPages', // <--- 2 nút mới\r\n ],\r\n shouldNotGroupWhenFull: true,\r\n },\r\n // Cấu hình alignment\r\n alignment: {\r\n options: ['left', 'center', 'right'],\r\n },\r\n };\r\n\r\n onReady(editor: ClassicEditor): void {\r\n this.#editor = editor;\r\n this.#editor.setData(this.#model || '');\r\n this.#editor.model.document.on('change:data', () => {\r\n this.#model = this.#editor.getData();\r\n this.modelChange.next(this.#model);\r\n });\r\n }\r\n}\r\n","import { ButtonView, Plugin } from 'ckeditor5';\r\n// Icon khổ dọc (Mặc định cũ)\r\nconst ICON_PORTRAIT =\r\n '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6V4h8v12z\"/></svg>';\r\n\r\n// Icon khổ ngang (Mới)\r\nconst ICON_LANDSCAPE =\r\n '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 4H2C.9 4 0 4.9 0 6v8c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 10H2V6h16v8z\"/></svg>';\r\nexport class PageOrientationPlugin extends Plugin {\r\n public static readonly pluginName = 'PageOrientationPlugin';\r\n \r\n private _currentOrientation: 'PORTRAIT' | 'LANDSCAPE' = 'PORTRAIT';\r\n private orientationChangeEmitter?: (orientation: 'PORTRAIT' | 'LANDSCAPE') => void;\r\n private buttonView?: ButtonView;\r\n\r\n init() {\r\n const editor = this.editor;\r\n const componentFactory = editor.ui.componentFactory;\r\n\r\n // Đăng ký nút tên là 'pageOrientation'\r\n componentFactory.add('pageOrientation', locale => {\r\n const view = new ButtonView(locale);\r\n this.buttonView = view;\r\n\r\n view.set({\r\n // label: 'Xoay giấy (A4)',\r\n icon: ICON_PORTRAIT,\r\n // tooltip: true,\r\n // withText: true,\r\n class: 'btn-orientation', // Class để style nếu cần\r\n });\r\n\r\n // Xử lý khi bấm nút\r\n view.on('execute', () => {\r\n this.toggleOrientation();\r\n });\r\n\r\n return view;\r\n });\r\n }\r\n\r\n /**\r\n * Toggle between portrait and landscape orientation\r\n */\r\n toggleOrientation(): void {\r\n const newOrientation = this._currentOrientation === 'PORTRAIT' ? 'LANDSCAPE' : 'PORTRAIT';\r\n this.setOrientation(newOrientation);\r\n }\r\n\r\n /**\r\n * Set orientation programmatically\r\n */\r\n setOrientation(orientation: 'PORTRAIT' | 'LANDSCAPE'): void {\r\n const editor = this.editor;\r\n const editingView = editor.editing.view;\r\n const rootElement = editingView.document.getRoot();\r\n\r\n editor.editing.view.change(writer => {\r\n if (orientation === 'LANDSCAPE') {\r\n writer.addClass('landscape', rootElement!);\r\n } else {\r\n writer.removeClass('landscape', rootElement!);\r\n }\r\n });\r\n\r\n // Update button icon\r\n if (this.buttonView) {\r\n this.buttonView.icon = orientation === 'LANDSCAPE' ? ICON_LANDSCAPE : ICON_PORTRAIT;\r\n }\r\n\r\n this._currentOrientation = orientation;\r\n this.orientationChangeEmitter?.(orientation);\r\n }\r\n\r\n /**\r\n * Get current orientation\r\n */\r\n getOrientation(): 'PORTRAIT' | 'LANDSCAPE' {\r\n return this._currentOrientation;\r\n }\r\n\r\n /**\r\n * Register callback for orientation changes\r\n */\r\n onOrientationChange(callback: (orientation: 'PORTRAIT' | 'LANDSCAPE') => void): void {\r\n this.orientationChangeEmitter = callback;\r\n }\r\n}\r\n","import { Plugin, ButtonView, Config } from 'ckeditor5';\r\nimport { SdDocumentBuilderComment, SdEditorConfig } from '../document-builder.model';\r\nimport { SdResolveMaybeAsync } from '@sd-angular/core/utilities';\r\n\r\nexport class CommentPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n\r\n // --- 1. CONVERSION: MODEL MARKER -> VIEW CSS ---\r\n // Biến Marker thành Highlight màu vàng\r\n editor.conversion.for('editingDowncast').markerToHighlight({\r\n model: 'comment', // Khớp với prefix của markerId (ví dụ: comment:12345)\r\n view: {\r\n classes: 'ck-comment-marker', // Class CSS sẽ được gắn vào thẻ <span> bao quanh text\r\n },\r\n });\r\n\r\n // --- 3. ĐĂNG KÝ UI COMPONENT: 'addCommentBtn' ---\r\n editor.ui.componentFactory.add('addCommentBtn', locale => {\r\n const view = new ButtonView(locale);\r\n\r\n // Lấy config từ Angular\r\n const config = editor.config as Config<SdEditorConfig>;\r\n const getOption = config.get('getOption') as SdEditorConfig['getOption'];\r\n const option = getOption?.();\r\n\r\n // ⭐ ẨN BUTTON NẾU KHÔNG CÓ onAddComment\r\n if (!option?.onAddComment) {\r\n // Trả về button rỗng hoặc null để không hiển thị\r\n view.set({\r\n label: '',\r\n isVisible: false,\r\n });\r\n return view;\r\n }\r\n\r\n view.set({\r\n label: 'Thêm bình luận',\r\n // Icon SVG comment\r\n icon: '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 13v6l-4-4H4a2 2 0 01-2-2V4a2 2 0 012-2h14a2 2 0 012 2v9zM5 7h10v2H5V7zm0 4h10v2H5v-2z\"/></svg>',\r\n tooltip: true,\r\n isEnabled: false, // Mặc định disable\r\n });\r\n\r\n // 4. Logic Enable/Disable: Dựa theo Selection\r\n const selection = editor.model.document.selection;\r\n\r\n // Lắng nghe sự kiện change selection để bật/tắt nút\r\n this.listenTo(selection, 'change', () => {\r\n // Enable khi có bôi đen text (không phải collapsed)\r\n view.isEnabled = !selection.isCollapsed;\r\n });\r\n\r\n // 5. Logic Execute: Khi bấm nút\r\n this.listenTo(view, 'execute', () => {\r\n const range = selection.getFirstRange();\r\n if (!range || !option?.onAddComment) return;\r\n // Helper lấy text thuần từ range\r\n let selectedText = '';\r\n for (const item of range.getItems()) {\r\n if (item.is('$text') || item.is('$textProxy')) {\r\n selectedText += (item as any).data;\r\n }\r\n }\r\n // ⭐ BẮN EVENT RA NGOÀI - KHÔNG TỰ ADD MARKER\r\n // Angular component sẽ xử lý logic (mở modal, validation, etc.)\r\n // và gọi lại hàm addComment() nếu cần\r\n option.onAddComment(range);\r\n });\r\n\r\n return view;\r\n });\r\n }\r\n}\r\n","import { Config, ModelNode, ModelWriter, Plugin, Widget, toWidget } from 'ckeditor5';\r\nimport { SdDocumentBuilderVariable, SdEditorConfig } from '../document-builder.model';\r\nimport { SdResolveMaybeAsync } from '@sd-angular/core/utilities';\r\n\r\nexport class VariablePlugin extends Plugin {\r\n // Khai báo dependencies nếu cần (VD: Widget)\r\n static get requires() {\r\n return [Widget];\r\n }\r\n\r\n init() {\r\n const editor = this.editor;\r\n const schema = editor.model.schema;\r\n const conversion = editor.conversion;\r\n const editingView = editor.editing.view;\r\n\r\n // 1. Định nghĩa Schema (Model)\r\n schema.register('variable', {\r\n inheritAllFrom: '$inlineObject',\r\n allowWhere: '$text',\r\n isInline: true,\r\n isObject: true,\r\n allowAttributes: ['id', 'value', 'display', 'data'],\r\n });\r\n\r\n // 2. Conversion: Model -> View (Hiển thị ra HTML)\r\n conversion.for('downcast').elementToElement({\r\n model: 'variable',\r\n view: (modelItem, { writer: viewWriter }) => {\r\n const id = modelItem.getAttribute('id') as string;\r\n const display = modelItem.getAttribute('display') as string;\r\n const value = modelItem.getAttribute('value') as string;\r\n // Xử lý data (Object -> String)\r\n const rawData = modelItem.getAttribute('data');\r\n const dataJson = rawData ? JSON.stringify(rawData) : '';\r\n const widgetElement = viewWriter.createContainerElement('span', {\r\n class: 'variable-widget',\r\n 'data-id': id,\r\n 'data-value': value,\r\n 'data-display': display,\r\n 'data-json': dataJson,\r\n });\r\n const innerText = viewWriter.createText(`{{${display}}}`);\r\n viewWriter.insert(viewWriter.createPositionAt(widgetElement, 0), innerText);\r\n return toWidget(widgetElement, viewWriter);\r\n },\r\n });\r\n\r\n // 3. Conversion: View -> Model (Khi load data hoặc paste)\r\n conversion.for('upcast').elementToElement({\r\n view: {\r\n name: 'span',\r\n classes: 'variable-widget',\r\n },\r\n model: (viewElement, { writer: modelWriter }) => {\r\n const dataJson = viewElement.getAttribute('data-json');\r\n let parsedData = null;\r\n try {\r\n parsedData = dataJson ? JSON.parse(dataJson) : null;\r\n } catch (e) {\r\n console.error('Lỗi parse variable data', e);\r\n }\r\n return modelWriter.createElement('variable', {\r\n id: viewElement.getAttribute('data-id'),\r\n value: viewElement.getAttribute('data-value'),\r\n display: viewElement.getAttribute('data-display'),\r\n data: parsedData, // Lưu vào model dưới dạng Object gốc\r\n });\r\n },\r\n });\r\n\r\n // 4. Xử lý sự kiện Drop\r\n this.listenTo(editingView.document, 'drop', async (evt, data) => {\r\n const dataTransfer = (data as any).dataTransfer;\r\n const jsonData = dataTransfer.getData('ck-variable');\r\n\r\n if (!jsonData) return;\r\n\r\n // Ngăn trình duyệt xử lý mặc định\r\n evt.stop();\r\n\r\n let variable: SdDocumentBuilderVariable = JSON.parse(jsonData);\r\n\r\n const config = editor.config as Config<SdEditorConfig>;\r\n const getOption = config.get('getOption') as SdEditorConfig['getOption'];\r\n const option = getOption?.();\r\n if (option?.onDropVariable) {\r\n const result = await SdResolveMaybeAsync<boolean | SdDocumentBuilderVariable>(option.onDropVariable(variable, 0));\r\n //* Hỗ trợ dữ liệu có sẵn sẽ chỉ cần nhận vào boolean\r\n if (typeof result === 'boolean') {\r\n if (!result) return;\r\n } else {\r\n //* Hỗ trợ dữ liệu lấy từ API (Kiểm tra xem result có đúng định dạng interface SdDocumentBuilderVariable hay không?)\r\n if (this.#isSdDocumentBuilderVariableResult(result)) {\r\n variable = result;\r\n } else {\r\n throw new Error('Dữ liệu variable không hợp lệ');\r\n }\r\n }\r\n }\r\n\r\n // Xác định vị trí thả chính xác (Quan trọng)\r\n // data.dropRange là vị trí con chuột trên View khi thả\r\n const viewRange = (data as any).dropRange;\r\n const modelRange = editor.editing.mapper.toModelRange(viewRange);\r\n\r\n editor.model.change(writer => {\r\n // A. Chèn biến\r\n const variableElem = writer.createElement('variable', {\r\n id: variable.id,\r\n value: variable.value,\r\n display: variable.display,\r\n data: variable.data,\r\n });\r\n\r\n editor.model.insertContent(variableElem, modelRange);\r\n\r\n // B. Đặt con trỏ ra sau biến\r\n writer.setSelection(variableElem, 'after');\r\n\r\n // C. [QUAN TRỌNG] XÓA SẠCH CÁC MARKER DROP\r\n // Thay vì chỉ xóa 'drop-target', ta duyệt tìm tất cả marker có tên bắt đầu bằng 'drop-target'\r\n // Vì đôi khi CKEditor tạo ra các biến thể khác nhau\r\n for (const marker of editor.model.markers) {\r\n if (marker.name.startsWith('drop-target')) {\r\n writer.removeMarker(marker);\r\n }\r\n }\r\n });\r\n\r\n // FIX LỖI: Focus lại vào editor để xóa các artifact của việc kéo thả\r\n editor.editing.view.focus();\r\n\r\n // [BỔ SUNG] XÓA CLASS RÁC TRÊN VIEW (NẾU MARKER KHÔNG HẾT)\r\n // Đôi khi View chưa kịp render lại, ta ép xóa class thủ công trên root nếu cần\r\n // (Thường bước C ở trên là đủ, nhưng đây là chốt chặn cuối cùng bằng JS)\r\n const viewRoot = editor.editing.view.document.getRoot();\r\n if (viewRoot) {\r\n editor.editing.view.change(viewWriter => {\r\n // Loại bỏ class decoration nếu nó bị dính vào root (hiếm gặp nhưng có thể)\r\n viewWriter.removeClass('ck-clipboard-drop-target-position', viewRoot);\r\n viewWriter.removeClass('ck-clipboard-drop-target-line', viewRoot);\r\n });\r\n }\r\n });\r\n\r\n // 5. Lắng nghe sự kiện bàn phím\r\n let isNavigating = false;\r\n this.editor.editing.view.document.on(\r\n 'keydown',\r\n (evt, data) => {\r\n // Mã phím mũi tên: 37 (Left), 38 (Up), 39 (Right), 40 (Down)\r\n const isArrowKey = data.keyCode >= 37 && data.keyCode <= 40;\r\n if (isArrowKey) {\r\n isNavigating = true;\r\n } else {\r\n isNavigating = false;\r\n }\r\n },\r\n { priority: 'high' }\r\n );\r\n\r\n // 6. Lắng nghe sự kiện Click chuột\r\n this.editor.editing.view.document.on('mousedown', () => {\r\n isNavigating = true;\r\n });\r\n\r\n this.listenTo(editor.model.document.selection, 'change:range', () => {\r\n // Nếu không phải là hành động click hoặc mũi tên thì thoát hàm.\r\n if (!isNavigating) {\r\n return;\r\n }\r\n\r\n const model = editor.model;\r\n const selection = model.document.selection;\r\n if (!selection.isCollapsed) return;\r\n\r\n const position = selection.getFirstPosition();\r\n const nodeBefore = position?.nodeBefore;\r\n if (!position) return;\r\n\r\n // Kiểm tra: Node đứng trước con trỏ là variable\r\n if (nodeBefore && nodeBefore.is('element', 'variable')) {\r\n // Lấy node ngay sau variable để kiểm tra\r\n const nextNode = nodeBefore.nextSibling;\r\n\r\n // Logic: Nếu phía sau KHÔNG CÓ GÌ hoặc KHÔNG PHẢI LÀ TEXT\r\n if (!nextNode || !nextNode.is('$text')) {\r\n model.change(writer => {\r\n // Chèn thêm con trỏ variable\r\n writer.insertText('\\u00A0', nodeBefore, 'after');\r\n\r\n // Lấy vị trí ngay sau variable (lúc này đang là đầu của text node mới)\r\n const posAfterVariable = writer.createPositionAfter(nodeBefore);\r\n\r\n // Dịch chuyển vị trí đó sang phải 1 đơn vị (bỏ qua ký tự vừa thêm)\r\n const targetPos = posAfterVariable.getShiftedBy(1);\r\n\r\n // 3. Đặt con trỏ vào vị trí đã tính toán\r\n writer.setSelection(targetPos);\r\n });\r\n }\r\n }\r\n });\r\n\r\n // 7. Handle xóa variable\r\n this.editor.editing.view.document.on(\r\n 'keydown',\r\n (evt, data) => {\r\n // Mã phím 8 là Backspace, 46 là Delete\r\n const btnBackspace = data.keyCode === 8\r\n const btnDelete = data.keyCode === 46\r\n if ( btnBackspace|| btnDelete) {\r\n const selection = editor.model.document.selection;\r\n const model = editor.model;\r\n\r\n // CASE 1: Nếu con trỏ đang nhấp nháy (Collapsed)\r\n if (selection.isCollapsed) {\r\n const position = selection.getFirstPosition();\r\n // Với Backspace ta kiểm tra nodeBefore, với Delete ta kiểm tra nodeAfter\r\n const targetNode = data.keyCode === 8 ? position?.nodeBefore : position?.nodeAfter;\r\n\r\n if (targetNode && targetNode.is('element', 'variable')) {\r\n data.preventDefault();\r\n evt.stop();\r\n\r\n model.change(writer => {\r\n // Chọn bao quanh Variable đó\r\n writer.setSelection(targetNode, 'on');\r\n });\r\n return;\r\n }\r\n }\r\n // CASE 2: Nếu đang có một vùng chọn (đã được highlight từ lần bấm trước)\r\n else {\r\n const selectedElement = selection.getSelectedElement();\r\n\r\n // Nếu phần tử đang được chọn chính là variable\r\n if (selectedElement && selectedElement.is('element', 'variable')) {\r\n // Cho phép hành động mặc định diễn ra (CKEditor sẽ tự xóa phần tử đang được chọn)\r\n // Hoặc chủ động xóa để chắc chắn:\r\n data.preventDefault();\r\n evt.stop();\r\n\r\n model.change(writer => {\r\n writer.remove(selectedElement);\r\n });\r\n }\r\n }\r\n }\r\n },\r\n { priority: 'highest' }\r\n );\r\n }\r\n\r\n #isSdDocumentBuilderVariableResult = (obj: any): obj is SdDocumentBuilderVariable => {\r\n return (\r\n obj !== null &&\r\n obj !== undefined &&\r\n typeof obj === 'object' &&\r\n !Array.isArray(obj) &&\r\n typeof obj.id === 'string' &&\r\n typeof obj.value === 'string' &&\r\n typeof obj.display === 'string'\r\n );\r\n };\r\n}\r\n","import { Plugin } from 'ckeditor5';\r\n\r\nexport class TableFitPlugin extends Plugin {\r\n init() {\r\n const editor = this.editor;\r\n // Can thiệp vào quá trình convert từ View (HTML Paste) sang Model\r\n editor.conversion.for('upcast').add(dispatcher => {\r\n dispatcher.on(\r\n 'element:table',\r\n (evt, data, conversionApi) => {\r\n // 1. Gọi consume để báo với CKEditor là chúng ta sẽ xử lý element này\r\n if (!conversionApi.consumable.consume(data.viewItem, { name: true })) {\r\n return;\r\n }\r\n\r\n // 2. Thực hiện chuyển đổi mặc định để tạo ra model element\r\n const { modelCursor, modelRange } = conversionApi.convertChildren(data.viewItem, data.modelCursor);\r\n\r\n // 3. Bây giờ modelRange chắc chắn tồn tại, ta tìm element table trong đó\r\n for (const item of modelRange.getItems()) {\r\n if (item.is('element', 'table')) {\r\n editor.model.change(writer => {\r\n writer.setAttribute('tableWidth', '100%', item);\r\n });\r\n }\r\n }\r\n\r\n // 4. Cập nhật modelCursor để dispatcher biết đã xử lý xong tới đâu\r\n data.modelRange = modelRange;\r\n data.modelCursor = modelCursor;\r\n },\r\n { priority: 'low' }\r\n );\r\n // Chạy sau cùng để ghi đè các logic mặc định\r\n });\r\n\r\n // Lắng nghe lệnh insertTable để can thiệp ngay sau khi bảng được tạo\r\n const insertTableCommand = editor.commands.get('insertTable');\r\n\r\n if (insertTableCommand) {\r\n // Dùng 'on' event để hook vào sau khi lệnh thực thi\r\n this.listenTo(insertTableCommand, 'execute', (evt, args) => {\r\n editor.model.change(writer => {\r\n // Lấy vị trí con trỏ hiện tại (nơi bảng vừa được chèn)\r\n const selection = editor.model.document.selection;\r\n const position = selection.getFirstPosition();\r\n\r\n if (!position) return;\r\n\r\n // Tìm element table vừa chèn (nó nằm ở vị trí cha của selection)\r\n // Khi vừa insert, con trỏ thường nằm trong ô đầu tiên của bảng\r\n const tableElement = position.findAncestor('table');\r\n\r\n if (tableElement) {\r\n // Ép width 100% cho bảng mới vẽ\r\n writer.setAttribute('tableWidth', '100%', tableElement);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n}\r\n","import { Plugin } from 'ckeditor5';\r\n\r\n/**\r\n * Custom base64 upload adapter plugin for CKEditor 5.\r\n * Converts uploaded images to base64 data URLs instead of uploading to a server.\r\n */\r\nexport class ImageUploadPlugin extends Plugin {\r\n static get pluginName() {\r\n return 'ImageUploadPlugin' as const;\r\n }\r\n\r\n init() {\r\n const editor = this.editor;\r\n\r\n // Register the custom upload adapter\r\n editor.plugins.get('FileRepository').createUploadAdapter = (loader: any) => {\r\n return new Base64UploadAdapter(loader);\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Custom upload adapter that converts images to base64 data URLs.\r\n */\r\nclass Base64UploadAdapter {\r\n private loader: any;\r\n\r\n constructor(loader: any) {\r\n this.loader = loader;\r\n }\r\n\r\n /**\r\n * Starts the upload process and converts the file to base64.\r\n * @returns Promise that resolves with the base64 URL\r\n */\r\n upload(): Promise<{ default: string }> {\r\n return this.loader.file.then((file: File) => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n\r\n reader.onload = () => {\r\n const base64Url = reader.result as string;\r\n resolve({ default: base64Url });\r\n };\r\n\r\n reader.onerror = () => {\r\n reject('Failed to convert image to base64');\r\n };\r\n\r\n reader.readAsDataURL(file);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Aborts the upload process.\r\n */\r\n abort(): void {\r\n // For base64 conversion, there's nothing to abort\r\n // This method is required by the UploadAdapter interface\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { Component, EventEmitter, Input, Output } from '@angular/core';\r\nimport { CKEditorModule } from '@ckeditor/ckeditor5-angular';\r\n\r\nimport {\r\n Bold,\r\n ClassicEditor,\r\n Essentials,\r\n GeneralHtmlSupport,\r\n Heading,\r\n FontSize,\r\n FontColor,\r\n FontBackgroundColor,\r\n FontFamily,\r\n Italic,\r\n List,\r\n ModelElement,\r\n ModelRange,\r\n PageBreak,\r\n Paragraph,\r\n PasteFromOffice,\r\n Table, // <--- 1. Quản lý viền/màu của cả bảng\r\n TableCellProperties, // <--- 2. Quản lý viền/màu của từng ô\r\n TableColumnResize,\r\n TableProperties,\r\n TableToolbar,\r\n Underline,\r\n Undo,\r\n Alignment, // Canh lề\r\n Subscript, // Mũ dưới (H₂O)\r\n Superscript,\r\n Image,\r\n ImageUpload,\r\n ImageToolbar,\r\n ImageCaption,\r\n ImageResize,\r\n ImageStyle,\r\n} from 'ckeditor5';\r\nimport {\r\n SdDocumentBuilderComment,\r\n SdDocumentBuilderHeading,\r\n SdDocumentBuilderOption,\r\n SdDocumentBuilderVariable,\r\n SdEditorConfig,\r\n} from './document-builder.model';\r\nimport { CommentPlugin, PageOrientationPlugin, TableFitPlugin, VariablePlugin, ImageUploadPlugin } from './plugins';\r\nimport { SdUtilities } from '@sd-angular/core/utilities/extensions';\r\nimport { throttleTime, Subject, Subscription } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'sd-document-builder',\r\n standalone: true,\r\n imports: [CommonModule, CKEditorModule],\r\n templateUrl: './document-builder.component.html',\r\n styleUrls: [\r\n './document-builder.component.scss',\r\n './plugins/comment.plugin.scss',\r\n './plugins/variable.plugin.scss',\r\n './plugins/table-fit.plugin.scss',\r\n './scss/toolbar.scss',\r\n ],\r\n // changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class SdDocumentBuilder {\r\n #id = '1212';\r\n\r\n @Input({ required: true }) option!: SdDocumentBuilderOption;\r\n disabled = false;\r\n\r\n @Input('disabled') set _disabled(val: boolean | '' | undefined | null) {\r\n this.disabled = val === '' || !!val;\r\n this.#updateState();\r\n }\r\n\r\n Editor = ClassicEditor;\r\n #editor!: ClassicEditor;\r\n\r\n // Config\r\n config: SdEditorConfig = {\r\n getOption: () => this.option,\r\n licenseKey: 'GPL', // Hoặc key thương mại nếu có\r\n plugins: [\r\n GeneralHtmlSupport,\r\n FontSize,\r\n FontColor,\r\n FontFamily,\r\n FontBackgroundColor,\r\n Bold,\r\n Italic,\r\n Underline,\r\n Essentials,\r\n Paragraph,\r\n Heading,\r\n List,\r\n Table,\r\n TableToolbar,\r\n TableProperties,\r\n TableCellProperties,\r\n TableColumnResize,\r\n PasteFromOffice,\r\n PageBreak,\r\n Undo,\r\n Alignment, // Canh lề\r\n Subscript, // Mũ dưới (H₂O)\r\n Superscript, // Mũ trên (x²)\r\n // Image\r\n Image,\r\n ImageUpload,\r\n ImageToolbar,\r\n ImageCaption,\r\n ImageResize,\r\n ImageStyle,\r\n // Custom Plugin\r\n PageOrientationPlugin,\r\n CommentPlugin,\r\n VariablePlugin,\r\n TableFitPlugin,\r\n ImageUploadPlugin,\r\n ],\r\n toolbar: {\r\n items: [\r\n 'pageOrientation',\r\n '|',\r\n 'heading',\r\n 'fontFamily',\r\n '|',\r\n 'fontSize',\r\n 'fontColor',\r\n 'fontBackgroundColor',\r\n '|',\r\n 'bold',\r\n 'italic',\r\n 'underline',\r\n 'subscript',\r\n 'superscript',\r\n '|',\r\n 'alignment',\r\n 'bulletedList',\r\n 'numberedList',\r\n '|',\r\n 'insertTable',\r\n 'imageUpload',\r\n 'pageBreak',\r\n '|',\r\n 'undo',\r\n 'redo',\r\n '|',\r\n 'addCommentBtn',\r\n ],\r\n shouldNotGroupWhenFull: true,\r\n },\r\n\r\n image: {\r\n toolbar: ['toggleImageCaption', '|', 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side'],\r\n },\r\n\r\n fontSize: {\r\n options: [\r\n // Định nghĩa từng size một cách tường minh\r\n {\r\n title: '9',\r\n model: '9pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '9pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '10',\r\n model: '10pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '10pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '11',\r\n model: '11pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '11pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '12',\r\n model: '12pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '12pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '13',\r\n model: '13pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '13pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '14',\r\n model: '14pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '14pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '16',\r\n model: '16pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '16pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '18',\r\n model: '18pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '18pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '20',\r\n model: '20pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '20pt' },\r\n priority: 7,\r\n },\r\n },\r\n {\r\n title: '24',\r\n model: '24pt',\r\n view: {\r\n name: 'span',\r\n styles: { 'font-size': '24pt' },\r\n priority: 7,\r\n },\r\n },\r\n ],\r\n supportAllValues: false, // Khuyên dùng false để ép user chọn đúng size chuẩn\r\n },\r\n // 4. Cấu hình bảng màu (Tùy chọn)\r\n fontColor: {\r\n columns: 5,\r\n documentColors: 10,\r\n },\r\n fontBackgroundColor: {\r\n columns: 5,\r\n documentColors: 10,\r\n },\r\n table: {\r\n contentToolbar: [\r\n 'tableColumn',\r\n 'tableRow',\r\n 'mergeTableCells',\r\n '|',\r\n 'tableProperties', // <--- Nút chỉnh thuộc tính bảng (Viền, Màu, Width)\r\n 'tableCellProperties',\r\n ],\r\n },\r\n // Quan trọng: Cho phép paste style từ Word nhưng bỏ qua margin/padding\r\n htmlSupport: {\r\n allow: [\r\n {\r\n name: /.*/,\r\n attributes: /.*/, // attributes chấp nhận boolean\r\n classes: /.*/, // Cho phép mọi class\r\n styles: {\r\n // Cho phép tất cả styles trừ margin và padding\r\n match: /^(?!margin|padding).*/,\r\n },\r\n },\r\n ],\r\n },\r\n };\r\n @Output() contentChange = new EventEmitter<string>(); // Emit HTML content\r\n #subscription = new Subscription();\r\n #contentChangeSubject = new Subject<string>();\r\n #editorChangeRxjs = new Subject<void>();\r\n\r\n ngOnInit() {\r\n // https://onemount.atlassian.net/browse/SM-1862\r\n // Debounce trong rxjs không hỗ trợ leading -->\r\n this.#subscription.add(\r\n this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {\r\n this.contentChange.emit(content);\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n onReady(editor: ClassicEditor) {\r\n this.#editor = editor;\r\n\r\n // Setup orientation plugin callback\r\n try {\r\n const orientationPlugin = editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.onOrientationChange === 'function') {\r\n orientationPlugin.onOrientationChange(orientation => {\r\n this.option.onOrientation?.(orientation);\r\n });\r\n\r\n // Set initial orientation if provided\r\n if (this.option.orientation) {\r\n orientationPlugin.setOrientation(this.option.orientation);\r\n }\r\n }\r\n } catch (error) {\r\n console.warn('PageOrientationPlugin not available:', error);\r\n }\r\n\r\n // Đăng ký sự kiện lắng nghe Selection để làm Comment\r\n editor.model.document.selection.on('change', $event => {\r\n this.option.onSelection?.(this.#editor.model.document.selection, $event);\r\n });\r\n // ⭐ ĐĂNG KÝ SỰ KIỆN LẮNG NGHE THAY ĐỔI NỘI DUNG\r\n editor.model.document.on('change:data', () => {\r\n const content = editor.getData();\r\n this.#contentChangeSubject.next(content);\r\n });\r\n this.#updateState();\r\n }\r\n\r\n #updateState(): void {\r\n if (!this.#editor) return;\r\n if (this.disabled) {\r\n // Bật chế độ chỉ đọc với ID khóa\r\n this.#editor.enableReadOnlyMode(this.#id);\r\n } else {\r\n // Tắt chế độ chỉ đọc với ID khóa tương ứng\r\n this.#editor.disableReadOnlyMode(this.#id);\r\n }\r\n }\r\n\r\n scrollToComment = (markerId: string) => {\r\n if (!this.#editor) return;\r\n\r\n const editor = this.#editor;\r\n const marker = editor.model.markers.get(markerId);\r\n\r\n if (marker) {\r\n // 1. Set Selection vào Marker đó trước\r\n this.#editor.model.change(writer => {\r\n writer.setSelection(marker.getRange());\r\n });\r\n\r\n // 2. Sau đó gọi scrollToTheSelection\r\n this.#editor.editing.view.scrollToTheSelection({\r\n alignToTop: true,\r\n });\r\n editor.editing.view.focus();\r\n } else {\r\n console.warn(`Marker with id ${markerId} not found.`);\r\n }\r\n };\r\n\r\n setContent = (html: string) => {\r\n this.#editor?.setData?.(html);\r\n };\r\n\r\n getContent = () => {\r\n if (this.#editor) {\r\n return this.#editor.getData();\r\n }\r\n return '';\r\n };\r\n\r\n setOrientation = (orientation: 'PORTRAIT' | 'LANDSCAPE'): void => {\r\n if (!this.#editor) return;\r\n\r\n try {\r\n const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.setOrientation === 'function') {\r\n orientationPlugin.setOrientation(orientation);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to set orientation:', error);\r\n }\r\n };\r\n\r\n getOrientation = (): 'PORTRAIT' | 'LANDSCAPE' => {\r\n if (!this.#editor) return 'PORTRAIT';\r\n\r\n try {\r\n const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin') as PageOrientationPlugin;\r\n if (orientationPlugin && typeof orientationPlugin.getOrientation === 'function') {\r\n return orientationPlugin.getOrientation();\r\n }\r\n } catch (error) {\r\n console.warn('Failed to get orientation:', error);\r\n }\r\n\r\n return 'PORTRAIT';\r\n };\r\n\r\n getVariables = (): SdDocumentBuilderVariable[] => {\r\n if (!this.#editor) return [];\r\n\r\n const model = this.#editor.model;\r\n const root = model.document.getRoot();\r\n\r\n if (!root) return [];\r\n\r\n const variables: SdDocumentBuilderVariable[] = [];\r\n // Duyệt qua tất cả các phần tử trong range\r\n // range.getItems() sẽ trả về từng node (text, element...)\r\n try {\r\n const range = model.createRangeIn(root);\r\n\r\n for (const item of range.getItems()) {\r\n // Sử dụng item.is('element', 'variable') là chính xác\r\n if (item.is('element', 'variable')) {\r\n variables.push({\r\n id: item.getAttribute('id') as string,\r\n value: item.getAttribute('value') as string,\r\n display: item.getAttribute('display') as string,\r\n data: item.getAttribute('data'),\r\n });\r\n }\r\n }\r\n } catch (e) {\r\n console.error(e);\r\n return [];\r\n }\r\n\r\n return variables;\r\n };\r\n\r\n getComments(): SdDocumentBuilderComment[] {\r\n if (!this.#editor) return [];\r\n\r\n const markers = this.#editor.model.markers;\r\n const comments: SdDocumentBuilderComment[] = [];\r\n\r\n // Duyệt qua tất cả markers trong Model\r\n for (const marker of markers) {\r\n // Chỉ lấy marker do plugin comment tạo ra (prefix 'comment:')\r\n if (marker.name.startsWith('comment:')) {\r\n // Lấy text nằm trong vùng marker đó\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n comments.push({\r\n markerId: marker.name,\r\n selectedText: currentText,\r\n });\r\n }\r\n }\r\n\r\n return comments;\r\n }\r\n\r\n scrollToTop() {\r\n setTimeout(() => {\r\n if (this.#editor) {\r\n const editableElement = this.#editor.ui.view.editable.element;\r\n if (editableElement) {\r\n const scrollContainer = editableElement.closest('.builder-container');\r\n if (scrollContainer) {\r\n scrollContainer.scrollTo({\r\n top: 0,\r\n behavior: 'smooth',\r\n });\r\n } else {\r\n editableElement.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }\r\n }\r\n }, 100);\r\n }\r\n\r\n // Kho lưu trữ tham chiếu Model của Heading (để phục vụ scroll)\r\n #headingElementsMap = new Map<string, ModelElement>();\r\n heading = {\r\n // ========================================================================\r\n // HÀM LẤY DANH SÁCH HEADING (TOC)\r\n // ========================================================================\r\n getHeadings: (): SdDocumentBuilderHeading[] => {\r\n if (!this.#editor) return [];\r\n\r\n const root = this.#editor.model.document.getRoot();\r\n if (!root) return [];\r\n\r\n // Reset lại map mỗi lần quét\r\n this.#headingElementsMap.clear();\r\n\r\n const headings: SdDocumentBuilderHeading[] = [];\r\n const range = this.#editor.model.createRangeIn(root);\r\n\r\n // Biến đếm để tạo ID unique\r\n let index = 0;\r\n\r\n for (const item of range.getItems()) {\r\n // Kiểm tra xem item có phải là Element và tên bắt đầu bằng 'heading' không\r\n if (item.is('element') && item.name.startsWith('heading')) {\r\n // 1. Lấy text của heading\r\n const text = this.#getTextFromElement(item);\r\n // 2. Xác định Level (heading1 -> 1, heading2 -> 2)\r\n // item.name có dạng 'heading1', 'heading2'\r\n const level = parseInt(item.name.replace('heading', ''), 10) || 1;\r\n // 3. Tạo ID runtime (Dùng để map khi click scroll)\r\n // Bạn có thể generate slug từ text nếu muốn, ở đây mình dùng index cho đơn giản và unique\r\n const id = `heading_${index}_${Date.now()}`;\r\n // 4. Lưu tham chiếu Model Element vào Map\r\n this.#headingElementsMap.set(id, item as ModelElement);\r\n headings.push({\r\n id: id,\r\n text: text,\r\n level: level,\r\n type: item.name,\r\n });\r\n index++;\r\n }\r\n }\r\n\r\n return headings;\r\n },\r\n // ========================================================================\r\n // HÀM SCROLL TO HEADING\r\n // ========================================================================\r\n scrollToHeading: (id: string) => {\r\n if (!this.#editor) return;\r\n\r\n // 1. Lấy Model Element từ kho lưu trữ\r\n const modelElement = this.#headingElementsMap.get(id);\r\n\r\n if (modelElement) {\r\n const editor = this.#editor;\r\n const view = editor.editing.view;\r\n // 2. Chuyển đổi Model Element -> View Element\r\n // mapper.toViewElement sẽ trả về thẻ HTML ảo (View Element) tương ứng (ví dụ thẻ <h2>)\r\n const viewElement = editor.editing.mapper.toViewElement(modelElement);\r\n if (viewElement) {\r\n // 3. Từ View Element ảo -> Lấy ra DOM thật (HTMLElement)\r\n const domElement = view.domConverter.mapViewToDom(viewElement);\r\n\r\n if (domElement) {\r\n // 4. Dùng hàm native của trình duyệt để cuộn\r\n domElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start',\r\n inline: 'nearest',\r\n });\r\n // 5. (Tùy chọn) Focus và đặt con trỏ vào đó\r\n view.focus();\r\n editor.model.change(writer => {\r\n writer.setSelection(modelElement, 'on');\r\n });\r\n }\r\n }\r\n } else {\r\n console.warn(`Heading with id ${id} not found.`);\r\n }\r\n },\r\n };\r\n\r\n // ========================================================================\r\n // HELPER: LẤY TEXT TỪ ELEMENT (Đệ quy nhẹ)\r\n // ========================================================================\r\n #getTextFromElement = (element: ModelElement): string => {\r\n let text = '';\r\n // Heading trong Model chứa các text node con\r\n for (const child of element.getChildren()) {\r\n if (child.is('$text') || child.is('$textProxy')) {\r\n text += (child as any).data;\r\n }\r\n }\r\n return text;\r\n };\r\n\r\n #getTextFromRange = (range: ModelRange): string => {\r\n let text = '';\r\n for (const item of range.getItems()) {\r\n // TextProxy là một phần của Text Node nằm trong Range\r\n if (item.is('$textProxy') || item.is('$text')) {\r\n text += (item as any).data;\r\n }\r\n }\r\n return text;\r\n };\r\n\r\n // ========================================================================\r\n // COMMENT MANAGEMENT\r\n // ========================================================================\r\n comment = {\r\n /**\r\n * Lấy tất cả comments trong document\r\n * @returns Danh sách tất cả comments\r\n */\r\n all: (): SdDocumentBuilderComment[] => {\r\n if (!this.#editor) return [];\r\n\r\n const markers = this.#editor.model.markers;\r\n const comments: SdDocumentBuilderComment[] = [];\r\n\r\n // Duyệt qua tất cả markers trong Model\r\n for (const marker of markers) {\r\n // Chỉ lấy marker do plugin comment tạo ra (prefix 'comment:')\r\n if (marker.name.startsWith('comment:')) {\r\n // Lấy text nằm trong vùng marker đó\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n comments.push({\r\n markerId: marker.name,\r\n selectedText: currentText,\r\n });\r\n }\r\n }\r\n\r\n return comments;\r\n },\r\n\r\n /**\r\n * Thêm comment vào vùng text đang được chọn\r\n * @param comment - Dữ liệu comment\r\n * @param data - Dữ liệu extra data\r\n * @returns SdDocumentBuilderComment hoặc null nếu không có text được chọn\r\n */\r\n add: <T = any>(range: ModelRange, comment: string, data?: T): SdDocumentBuilderComment<T> | null => {\r\n if (!this.#editor) return null;\r\n const model = this.#editor.model;\r\n if (!range) return null;\r\n // 3. Lấy text từ range\r\n const selectedText = this.#getTextFromRange(range);\r\n if (!selectedText.trim()) {\r\n console.warn('Selected text is empty');\r\n return null;\r\n }\r\n // 4. Tạo ID unique cho marker\r\n const markerId = `comment:${Date.now()}`;\r\n // 5. Tạo marker trong model\r\n model.change(writer => {\r\n writer.addMarker(markerId, {\r\n range,\r\n usingOperation: true, // Quan trọng: Cho phép undo/redo\r\n affectsData: true, // Lưu marker vào data khi getData()\r\n });\r\n });\r\n return {\r\n markerId,\r\n selectedText,\r\n comment,\r\n createdAt: new Date(),\r\n data,\r\n };\r\n },\r\n\r\n /**\r\n * Cập nhật nội dung comment\r\n * @param markerId - ID của marker\r\n * @param commentData - Dữ liệu mới\r\n * @returns Comment đã cập nhật hoặc null\r\n */\r\n update: <T = any>(markerId: string, comment: string, data?: T): SdDocumentBuilderComment<T> | null => {\r\n if (!this.#editor) return null;\r\n const marker = this.#editor.model.markers.get(markerId);\r\n if (!marker) {\r\n console.warn(`Marker ${markerId} not found`);\r\n return null;\r\n }\r\n // Lấy text hiện tại từ marker (có thể đã thay đổi)\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n return {\r\n markerId: markerId,\r\n selectedText: currentText,\r\n comment,\r\n data,\r\n };\r\n },\r\n\r\n /**\r\n * Lấy chi tiết comment theo markerId\r\n * @param markerId - ID của marker\r\n * @returns Comment hoặc null\r\n */\r\n detail: (markerId: string): SdDocumentBuilderComment | null => {\r\n if (!this.#editor) return null;\r\n const marker = this.#editor.model.markers.get(markerId);\r\n if (!marker) return null;\r\n const currentText = this.#getTextFromRange(marker.getRange());\r\n return {\r\n markerId: markerId,\r\n selectedText: currentText,\r\n };\r\n },\r\n\r\n /**\r\n * Xóa comment theo markerId\r\n * @param markerId - ID của marker cần xóa\r\n * @returns true nếu xóa thành công, false nếu không tìm thấy\r\n */\r\n remove: (markerId: string): boolean => {\r\n if (!this.#editor) return false;\r\n const model = this.#editor.model;\r\n const marker = model.markers.get(markerId);\r\n if (!marker) {\r\n console.warn(`Marker ${markerId} not found`);\r\n return false;\r\n }\r\n model.change(writer => {\r\n writer.removeMarker(markerId);\r\n });\r\n return true;\r\n },\r\n\r\n /**\r\n * Scroll đến vị trí comment\r\n * @param markerId - ID của marker cần scroll tới\r\n */\r\n scroll: (markerId: string): void => {\r\n if (!this.#editor) return;\r\n const editor = this.#editor;\r\n const marker = editor.model.markers.get(markerId);\r\n if (marker) {\r\n // 1. Set Selection vào Marker đó trước\r\n editor.model.change(writer => {\r\n writer.setSelection(marker.getRange());\r\n });\r\n\r\n // 2. Sau đó gọi scrollToTheSelection\r\n editor.editing.view.scrollToTheSelection({\r\n alignToTop: true,\r\n });\r\n editor.editing.view.focus();\r\n } else {\r\n console.warn(`Marker with id ${markerId} not found.`);\r\n }\r\n },\r\n };\r\n\r\n // exportDocx(fileName: string = 'document.docx'): void {\r\n // if (!this.#editor) return;\r\n\r\n // // 1. Kiểm tra xem Editor đang ở chế độ Landscape hay Portrait\r\n // // (Dựa vào class 'landscape' mà Plugin PageOrientation đã toggle trên View)\r\n // const rootElement = this.#editor.editing.view.document.getRoot();\r\n // const isLandscape = rootElement?.hasClass('landscape');\r\n\r\n // const orientation = isLandscape ? 'landscape' : 'portrait';\r\n\r\n // // 2. Lấy nội dung HTML\r\n // const contentHtml = this.#editor.getData();\r\n\r\n // // 3. Chuẩn bị HTML với CSS @page động\r\n // const fullHtml = `\r\n // <!DOCTYPE html>\r\n // <html>\r\n // <head>\r\n // <meta charset=\"UTF-8\">\r\n // <style>\r\n // /* --- CẤU HÌNH KHỔ GIẤY DỰA TRÊN TRẠNG THÁI --- */\r\n // @page {\r\n // size: A4 ${orientation}; /* Thêm portrait hoặc landscape vào đây */\r\n // margin: 20mm;\r\n // }\r\n\r\n // body {\r\n // font-family: 'Times New Roman', serif;\r\n // font-size: 13pt;\r\n // line-height: 1.5;\r\n // }\r\n\r\n // /* --- STYLE CHO BẢNG BIỂU --- */\r\n // table {\r\n // width: 100%;\r\n // border-collapse: collapse;\r\n // }\r\n // td, th {\r\n // border: 1px solid black;\r\n // padding: 5px;\r\n // }\r\n\r\n // /* --- STYLE CHO BIẾN --- */\r\n // .variable-widget {\r\n // color: #1565c0;\r\n // background-color: #e3f2fd;\r\n // font-weight: bold;\r\n // border: 1px solid #90caf9;\r\n // padding: 0 4px;\r\n // border-radius: 4px;\r\n // }\r\n\r\n // /* --- ẨN COMMENT KHI IN --- */\r\n // .ck-comment-marker {\r\n // background-color: transparent;\r\n // border: none;\r\n // }\r\n // </style>\r\n // </head>\r\n // <body>\r\n // ${contentHtml}\r\n // </body>\r\n // </html>\r\n // `;\r\n\r\n // // 3. Convert sang Blob (Dạng file Binary)\r\n // asBlob(fullHtml, {\r\n // orientation: 'portrait', // 'portrait' hoặc 'landscape'\r\n // margins: { top: 720, right: 720, bottom: 720, left: 720 }, // Đơn vị twips (1440 twips = 1 inch)\r\n // }).then(blob => {\r\n // if (blob instanceof Blob) {\r\n // SdUtilities.downloadBlob(blob, fileName);\r\n // }\r\n // });\r\n // }\r\n\r\n // ========================================================================\r\n // 4. HÀM EXPORT DOCX (FULL HEADER/FOOTER + PAGE NUMBER)\r\n // ========================================================================\r\n /**\r\n * Xuất file Word có Header/Footer\r\n * @param fileName Tên file\r\n * @param headerText Nội dung Header (hoặc HTML)\r\n * '<p style=\"text-align: center; font-weight: bold;\">CÔNG TY CỔ PHẦN CÔNG NGHỆ ABC</p>'\r\n * @param footerText Nội dung Footer (hoặc HTML)\r\n * '<p style=\"text-align: right; font-size: 10pt;\">Trang <span style=\"mso-field-code: PAGE\"></span> / <span style=\"mso-field-code: NUMPAGES\"></span></p>'\r\n */\r\n exportDocx(args: { fileName?: string; header?: string; footer?: string }): void {\r\n if (!this.#editor) return;\r\n const fileName = args?.fileName || `document_${Date.now()}.docx`;\r\n const header = args?.header || ``;\r\n const footer = args?.footer || ``;\r\n // 1. Kiểm tra xoay giấy\r\n const rootElement = this.#editor.editing.view.document.getRoot();\r\n const isLandscape = rootElement?.hasClass('landscape');\r\n const orientation = isLandscape ? 'landscape' : 'portrait';\r\n\r\n // Kích thước giấy cho Word (A4)\r\n // Portrait: 21cm x 29.7cm\r\n // Landscape: 29.7cm x 21cm\r\n // @page size trong CSS Word đôi khi cần set cứng width/height để header không bị lệch\r\n const pageCss = isLandscape\r\n ? 'size: 29.7cm 21cm; mso-page-orientation: landscape;'\r\n : 'size: 21cm 29.7cm; mso-page-orientation: portrait;';\r\n\r\n const contentHtml = this.#editor.getData();\r\n\r\n // 2. TẠO HTML CHUẨN MICROSOFT WORD XML\r\n // Phải có xmlns:o và xmlns:w thì Word mới hiểu được các lệnh mso-\r\n const fullHtml = `\r\n <html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <title>Export Document</title>\r\n \r\n <style>\r\n /* --- 1. SETUP TRANG GIẤY & HEADER/FOOTER --- */\r\n @page {\r\n ${pageCss}\r\n margin: 2.0cm; /* Lề chuẩn 2cm */\r\n \r\n /* Kỹ thuật map ID của Word */\r\n mso-header: header1;\r\n mso-footer: footer1;\r\n }\r\n\r\n /* Quan trọng: Ẩn các div header/footer khỏi luồng văn bản chính */\r\n /* Chúng sẽ chỉ hiện thị khi được @page gọi thông qua mso-header/footer */\r\n div#header1 { display: none; }\r\n div#footer1 { display: none; }\r\n\r\n /* --- 2. STYLE CƠ BẢN --- */\r\n body {\r\n font-family: 'Times New Roman', serif;\r\n font-size: 13pt;\r\n line-height: 1.5;\r\n tab-interval: 36pt;\r\n }\r\n \r\n /* Style Bảng */\r\n table { width: 100%; border-collapse: collapse; }\r\n td, th { border: 1px solid black; padding: 5px; }\r\n\r\n /* Style Biến (Giữ nguyên giao diện đẹp của bạn) */\r\n .variable-widget {\r\n color: #1565c0; font-weight: bold;\r\n background: #e3f2fd; padding: 0 4px; border-radius: 4px;\r\n border: 1px solid #90caf9;\r\n }\r\n \r\n /* Ẩn Comment khi in/xuất file */\r\n .ck-comment-marker { background-color: transparent; border: none; text-decoration: none; }\r\n </style>\r\n </head>\r\n <body>\r\n \r\n <div id=\"header1\">\r\n <div style=\"mso-element:header\">\r\n ${header}\r\n <div style='border-bottom: 1px solid #000; margin-top: 5px; margin-bottom: 20px;'></div>\r\n </div>\r\n </div>\r\n\r\n <div id=\"footer1\">\r\n <div style=\"mso-element:footer\">\r\n <div style='border-top: 1px solid #000; margin-top: 20px; margin-bottom: 5px;'></div>\r\n ${footer}\r\n </div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n ${contentHtml}\r\n </div>\r\n\r\n </body>\r\n </html>\r\n `;\r\n\r\n // 3. TẠO BLOB VÀ TẢI XUỐNG\r\n // Lưu ý: Dùng type 'application/msword' thay vì dùng thư viện html-docx-js\r\n // Thêm '\\ufeff' (BOM) để fix lỗi font tiếng Việt\r\n const blob = new Blob(['\\ufeff', fullHtml], { type: 'application/msword' });\r\n SdUtilities.downloadBlob(blob, fileName);\r\n // 3. Convert & Save\r\n // asBlob(fullHtml, {\r\n // orientation: orientation as 'portrait' | 'landscape',\r\n // margins: { top: 720, right: 720, bottom: 720, left: 720 },\r\n // }).then(blob => {\r\n // if (blob instanceof Blob) {\r\n // SdUtilities.downloadBlob(blob, fileName);\r\n // }\r\n // });\r\n }\r\n}\r\n","<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|