UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

85 lines (84 loc) 4.22 kB
import { EmptyBatchUpdatableObject } from "@devexpress/utils/lib/class/batch-updatable"; import { ModelChecker } from "../../../model/model-checks/check-all"; import { ModelCreatorOptions } from "../../../model/creator/options"; import { ModelCreator } from "../../../model/creator/creator"; import { MaskedCharacterProperties } from "../../../model/character/character-properties"; import { SubDocumentPosition } from "../../../model/sub-document"; import { ClientModelManager } from "../../../model-manager"; import { MaskedCharacterPropertiesBundle } from "../../../rich-utils/properties-bundle"; import { Measurer } from "../../../measurer/measurer"; import { DocumentImporterErrors } from "../../document-importer-errors"; import { FormatImagesImporter } from "../../utils/images-import"; import { HtmlImporter } from "./html-importer"; export class HtmlDocumentImporter { importFromFile(blob, modelOptions, callback, reject) { this.init(modelOptions); const reader = new FileReader(); reader.onload = () => { this.importFromString(reader.result, modelOptions, callback, reject); }; reader.onerror = (_ev) => { reject(DocumentImporterErrors.HtmlFileReaderError); }; reader.readAsText(blob); } importFromString(text, modelOptions, callback, reject, charPropsBundle) { this.init(modelOptions); try { this.fillModel(text, charPropsBundle); if (!new ModelChecker(this.documentModel).checkAll()) throw new Error(); } catch (err) { reject(DocumentImporterErrors.HtmlImportError); return; } callback(this.documentModel, this.formatImagesImporter); } init(modelOptions) { const options = new ModelCreatorOptions(); options.addSection = true; options.addParagraph = true; this.formatImagesImporter = new FormatImagesImporter(); this.documentModel = new ModelCreator(options).createModel(modelOptions).fillModel(); this.modelManager = new ClientModelManager(this.documentModel, modelOptions, new EmptyBatchUpdatableObject()); } fillModel(text, charPropsBundle) { const container = document.body.appendChild(this.createContainer()); try { container.innerHTML = HtmlImporter.convertHtml(text); charPropsBundle = charPropsBundle || this.createMaskedCharacterPropertiesBundle(); const measurer = new Measurer(''); const position = new SubDocumentPosition(this.documentModel.mainSubDocument, 0); const initElements = container.childNodes; new HtmlImporter(this.modelManager, measurer, position, initElements, charPropsBundle, this.formatImagesImporter).import(); this.removeLastParagraph(); } finally { document.body.removeChild(container); } } createMaskedCharacterPropertiesBundle() { const maskedCharacterProperties = MaskedCharacterProperties.createDefault(this.documentModel); const style = this.modelManager.model.stylesManager.getDefaultCharacterStyle(); return new MaskedCharacterPropertiesBundle(maskedCharacterProperties, style); } createContainer() { const container = document.createElement('DIV'); container.id = 'import-container'; container.style.width = '0'; container.style.height = '0'; container.style.overflow = 'hidden'; return container; } removeLastParagraph() { const lastParagraph = this.documentModel.mainSubDocument.getLastParagraph(); if (lastParagraph.length > 1) return; const section = this.documentModel.getSectionByPosition(lastParagraph.startLogPosition.value); const lastChunk = this.documentModel.mainSubDocument.getLastChunk(); this.documentModel.mainSubDocument.paragraphs.pop(); section.setLength(this.documentModel.mainSubDocument, section.getLength() - lastParagraph.length); lastChunk.removeRun(lastChunk.textRuns.length - 1); } }