@mirrormedia/lilith-draft-editor
Version:
## Installation
224 lines (186 loc) • 8.14 kB
JavaScript
;
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;