UNPKG

@mirrormedia/lilith-draft-editor

Version:
224 lines (186 loc) 8.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _lodash = _interopRequireDefault(require("lodash")); var _apiDataInstance = _interopRequireDefault(require("./api-data-instance")); var _entities = _interopRequireDefault(require("./entities")); var _draftJs = require("draft-js"); var _draftConvert = require("draft-convert"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint-disable @typescript-eslint/no-var-requires */ // import sizeOf from 'image-size'; // import htmlparser2 from 'htmlparser2' // eslint-disable-next-line no-undef const htmlparser2 = require('htmlparser2'); /** * @typedef {Object} DraftEditor.TableEntity.TableStyles * @property {Record<string, string>[]} rows * @property {Record<string, string>[]} columns * @property {Record<string, string>[][]} cells */ /** * @typedef {import('./jsdoc').RawDraftContentState} RawDraftContentState * @typedef {import('./jsdoc').RawDraftContentBlock} RawDraftContentBlock * @typedef {import('./jsdoc').EntityMap} EntityMap * @typedef {RawDraftContentState[][]} DraftEditor.TableEntity.TableData */ const processor = { /** * @param {EntityMap} entityMap * @param {RawDraftContentBlock} block */ convertBlock(entityMap, block) { let alignment = 'center'; let content; const entityRange = block.entityRanges[0]; const styles = {}; // current block's entity data // ex: // entity.type = IMAGE, entity.data={id,name,url...} const entity = entityMap[entityRange.key]; let type = _lodash.default.get(entity, 'type', ''); // backward compatible. Old entity type might be lower case switch (type && type.toUpperCase()) { case _entities.default.INFOBOX.type: { var _entity$data, _entity$data2; // About INFOBOX atomic block entity data structure, // see `../views/editor/info-box.tsx` for more information. content = [{ title: entity === null || entity === void 0 ? void 0 : (_entity$data = entity.data) === null || _entity$data === void 0 ? void 0 : _entity$data.title, body: entity === null || entity === void 0 ? void 0 : (_entity$data2 = entity.data) === null || _entity$data2 === void 0 ? void 0 : _entity$data2.body }]; break; } case _entities.default.COLORBOX.type: { var _entity$data3, _entity$data4; content = [{ color: entity === null || entity === void 0 ? void 0 : (_entity$data3 = entity.data) === null || _entity$data3 === void 0 ? void 0 : _entity$data3.color, body: entity === null || entity === void 0 ? void 0 : (_entity$data4 = entity.data) === null || _entity$data4 === void 0 ? void 0 : _entity$data4.body }]; break; } case _entities.default.TABLE.type: { var _content; // About TABLE atomic block entity data structure, // see `../views/editor/table.tsx` for more information. content = entity === null || entity === void 0 ? void 0 : entity.data; /** @type DraftEditor.TableEntity.TableData */ // since apiData is now only for app, // keep the rows data structure for app to style the table const tableData = (_content = content) === null || _content === void 0 ? void 0 : _content.tableData; const rows = tableData === null || tableData === void 0 ? void 0 : tableData.map(row => { const cols = row === null || row === void 0 ? void 0 : row.map(col => { return { html: (0, _draftConvert.convertToHTML)((0, _draftJs.convertFromRaw)(col)) }; }); return cols; }); content = rows; break; } case _entities.default.DIVIDER.type: content = ['<hr>']; break; case _entities.default.BLOCKQUOTE.type: // this is different from default blockquote of draftjs // so we name our specific blockquote as 'quoteby' type = 'quoteby'; alignment = (entity === null || entity === void 0 ? void 0 : entity.data) && (entity === null || entity === void 0 ? void 0 : entity.data.alignment) || alignment; content = _lodash.default.get(entity, 'data'); content = Array.isArray(content) ? content : [content]; break; case _entities.default.AUDIO.type: case _entities.default['AUDIO-V2'].type: case _entities.default.IMAGE.type: case _entities.default.IMAGEDIFF.type: case _entities.default.SLIDESHOW.type: case _entities.default['SLIDESHOW-V2'].type: case _entities.default.VIDEO.type: case _entities.default['VIDEO-V2'].type: case _entities.default.YOUTUBE.type: case _entities.default.BACKGROUNDIMAGE.type: case _entities.default.BACKGROUNDVIDEO.type: case _entities.default.RELATEDPOST.type: case _entities.default.SIDEINDEX.type: alignment = (entity === null || entity === void 0 ? void 0 : entity.data) && (entity === null || entity === void 0 ? void 0 : entity.data.alignment) || alignment; content = _lodash.default.get(entity, 'data'); content = Array.isArray(content) ? content : [content]; break; case _entities.default.IMAGELINK.type: { // use Embedded component to dangerouslySetInnerHTML type = _entities.default.EMBEDDEDCODE.type; alignment = (entity === null || entity === void 0 ? void 0 : entity.data) && (entity === null || entity === void 0 ? void 0 : entity.data.alignment) || alignment; const description = _lodash.default.get(entity, ['data', 'description'], ''); const url = _lodash.default.get(entity, ['data', 'url'], ''); content = [{ caption: description, embeddedCodeWithoutScript: `<img alt="${description}" src="${url}" class="img-responsive"/>`, url: url }]; break; } case _entities.default.EMBEDDEDCODE.type: { alignment = (entity === null || entity === void 0 ? void 0 : entity.data) && (entity === null || entity === void 0 ? void 0 : entity.data.alignment) || alignment; const caption = _lodash.default.get(entity, ['data', 'caption'], ''); const embeddedCode = _lodash.default.get(entity, ['data', 'embeddedCode'], ''); /** @type {Record<string, any>} */ const script = {}; /** @type {typeof script[]} */ const scripts = []; let scriptTagStart = false; let height; let width; const parser = new htmlparser2.Parser({ onopentag: (name, attribs) => { if (name === 'script') { scriptTagStart = true; script.attribs = attribs; } else if (name === 'iframe') { height = _lodash.default.get(attribs, 'height', 0); width = _lodash.default.get(attribs, 'width', 0); } }, ontext: text => { if (scriptTagStart) { script.text = text; } }, onclosetag: tagname => { if (tagname === 'script' && scriptTagStart) { scriptTagStart = false; scripts.push(script); } } }); parser.write(embeddedCode); parser.end(); content = [{ caption, embeddedCode, embeddedCodeWithoutScript: embeddedCode.replace(/<script(.+?)\/script>/g, ''), height, scripts, width }]; break; } default: return; } // block type of api data should be lower case return new _apiDataInstance.default({ id: block.key, alignment, type: type && type.toLowerCase(), content, styles }); } }; var _default = processor; exports.default = _default;