@mirrormedia/lilith-draft-editor 1.1.0-alpha.3 → 1.1.0-alpha.4

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.
Files changed (72) hide show
  1. package/lib/draft-js/buttons/annotation.js +22 -0
  2. package/lib/draft-js/buttons/audio.js +16 -3
  3. package/lib/draft-js/buttons/background-color.js +26 -0
  4. package/lib/draft-js/buttons/background-image.js +32 -13
  5. package/lib/draft-js/buttons/background-video.js +32 -13
  6. package/lib/draft-js/buttons/color-box.js +21 -5
  7. package/lib/draft-js/buttons/divider.js +12 -3
  8. package/lib/draft-js/buttons/embedded-code.js +16 -5
  9. package/lib/draft-js/buttons/enlarge.js +3 -0
  10. package/lib/draft-js/buttons/font-color.js +26 -0
  11. package/lib/draft-js/buttons/image.js +16 -5
  12. package/lib/draft-js/buttons/info-box.js +21 -5
  13. package/lib/draft-js/buttons/link.js +19 -0
  14. package/lib/draft-js/buttons/media.js +16 -3
  15. package/lib/draft-js/buttons/related-post.js +14 -3
  16. package/lib/draft-js/buttons/selector/align-selector.js +11 -2
  17. package/lib/draft-js/buttons/selector/audio-selector.js +33 -4
  18. package/lib/draft-js/buttons/selector/image-selector.js +50 -6
  19. package/lib/draft-js/buttons/selector/pagination.js +6 -2
  20. package/lib/draft-js/buttons/selector/post-selector.js +39 -6
  21. package/lib/draft-js/buttons/selector/search-box.js +9 -0
  22. package/lib/draft-js/buttons/selector/video-selector.js +33 -4
  23. package/lib/draft-js/buttons/side-index.js +31 -15
  24. package/lib/draft-js/buttons/slideshow.js +16 -7
  25. package/lib/draft-js/buttons/table.js +11 -5
  26. package/lib/draft-js/buttons/text-align.js +14 -0
  27. package/lib/draft-js/buttons/video.js +16 -3
  28. package/lib/draft-js/const.js +2 -0
  29. package/lib/draft-js/draft-converter/api-data-instance.js +14 -0
  30. package/lib/draft-js/draft-converter/atomic-block-processor.js +41 -12
  31. package/lib/draft-js/draft-converter/entities.js +0 -1
  32. package/lib/draft-js/draft-converter/index.js +29 -10
  33. package/lib/draft-js/draft-converter/inline-styles-processor.js +55 -22
  34. package/lib/draft-js/modifier.js +13 -5
  35. package/lib/index.js +4 -0
  36. package/lib/website/mirrormedia/block-renderer/background-image-block.js +14 -2
  37. package/lib/website/mirrormedia/block-renderer/background-video-block.js +14 -2
  38. package/lib/website/mirrormedia/block-renderer/color-box-block.js +14 -2
  39. package/lib/website/mirrormedia/block-renderer/embedded-code-block.js +12 -3
  40. package/lib/website/mirrormedia/block-renderer/info-box-block.js +14 -2
  41. package/lib/website/mirrormedia/block-renderer/side-index-block.js +13 -2
  42. package/lib/website/mirrormedia/block-renderer/slideshow-block.js +11 -4
  43. package/lib/website/mirrormedia/block-renderer/table-block.js +62 -28
  44. package/lib/website/mirrormedia/block-renderer-fn.js +30 -0
  45. package/lib/website/mirrormedia/draft-editor.js +106 -10
  46. package/lib/website/mirrormedia/entity-decorator.js +4 -0
  47. package/lib/website/mirrormedia/index.js +3 -0
  48. package/lib/website/mirrormedia/selector/align-selector.js +11 -2
  49. package/lib/website/mirrormedia/selector/audio-selector.js +33 -4
  50. package/lib/website/mirrormedia/selector/image-selector.js +49 -6
  51. package/lib/website/mirrormedia/selector/pagination.js +6 -2
  52. package/lib/website/mirrormedia/selector/post-selector.js +39 -6
  53. package/lib/website/mirrormedia/selector/search-box.js +9 -0
  54. package/lib/website/mirrormedia/selector/video-selector.js +32 -4
  55. package/lib/website/readr/block-renderer/background-image-block.js +14 -2
  56. package/lib/website/readr/block-renderer/background-video-block.js +14 -2
  57. package/lib/website/readr/block-renderer/color-box-block.js +14 -2
  58. package/lib/website/readr/block-renderer/info-box-block.js +14 -2
  59. package/lib/website/readr/block-renderer/side-index-block.js +13 -2
  60. package/lib/website/readr/block-renderer/table-block.js +62 -28
  61. package/lib/website/readr/block-renderer-fn.js +28 -0
  62. package/lib/website/readr/draft-editor.js +106 -10
  63. package/lib/website/readr/entity-decorator.js +4 -0
  64. package/lib/website/readr/index.js +3 -0
  65. package/lib/website/readr/selector/align-selector.js +11 -2
  66. package/lib/website/readr/selector/audio-selector.js +33 -16
  67. package/lib/website/readr/selector/image-selector.js +49 -6
  68. package/lib/website/readr/selector/pagination.js +6 -2
  69. package/lib/website/readr/selector/post-selector.js +39 -6
  70. package/lib/website/readr/selector/search-box.js +9 -0
  71. package/lib/website/readr/selector/video-selector.js +32 -4
  72. package/package.json +2 -2
@@ -4,23 +4,27 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+
7
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
+
8
10
  var _apiDataInstance = _interopRequireDefault(require("./api-data-instance"));
11
+
9
12
  var _entities = _interopRequireDefault(require("./entities"));
13
+
10
14
  var _server = _interopRequireDefault(require("react-dom/server"));
15
+
11
16
  var _draftJs = require("draft-js");
17
+
12
18
  var _draftConvert = require("draft-convert");
19
+
13
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
- /* eslint-disable @typescript-eslint/no-var-requires */
15
21
 
22
+ /* eslint-disable @typescript-eslint/no-var-requires */
16
23
  // import sizeOf from 'image-size';
17
-
18
24
  // eslint-disable-line
19
-
20
25
  // import htmlparser2 from 'htmlparser2'
21
26
  // eslint-disable-next-line no-undef
22
27
  const htmlparser2 = require('htmlparser2');
23
-
24
28
  /**
25
29
  * @typedef {Object} DraftEditor.TableEntity.TableStyles
26
30
  * @property {Record<string, string>[]} rows
@@ -32,23 +36,26 @@ const htmlparser2 = require('htmlparser2');
32
36
  * @typedef {RawDraftContentState[][]} DraftEditor.TableEntity.TableData
33
37
  */
34
38
 
39
+
35
40
  const processor = {
36
41
  convertBlock(entityMap, block) {
37
42
  let alignment = 'center';
38
43
  let content;
39
44
  let entityRange = block.entityRanges[0];
40
- let styles = {};
41
- // current block's entity data
45
+ let styles = {}; // current block's entity data
42
46
  // ex:
43
47
  // entity.type = IMAGE, entity.data={id,name,url...}
48
+
44
49
  const entity = entityMap[entityRange.key];
45
- let type = _lodash.default.get(entity, 'type', '');
46
50
 
47
- // backward compatible. Old entity type might be lower case
51
+ let type = _lodash.default.get(entity, 'type', ''); // backward compatible. Old entity type might be lower case
52
+
53
+
48
54
  switch (type && type.toUpperCase()) {
49
55
  case _entities.default.INFOBOX.type:
50
56
  {
51
57
  var _entity$data, _entity$data2;
58
+
52
59
  // About INFOBOX atomic block entity data structure,
53
60
  // see `../views/editor/info-box.tsx` for more information.
54
61
  content = [{
@@ -57,29 +64,37 @@ const processor = {
57
64
  }];
58
65
  break;
59
66
  }
67
+
60
68
  case _entities.default.COLORBOX.type:
61
69
  {
62
70
  var _entity$data3, _entity$data4;
71
+
63
72
  content = [{
64
73
  color: entity === null || entity === void 0 ? void 0 : (_entity$data3 = entity.data) === null || _entity$data3 === void 0 ? void 0 : _entity$data3.color,
65
74
  body: entity === null || entity === void 0 ? void 0 : (_entity$data4 = entity.data) === null || _entity$data4 === void 0 ? void 0 : _entity$data4.body
66
75
  }];
67
76
  break;
68
77
  }
78
+
69
79
  case _entities.default.TABLE.type:
70
80
  {
71
81
  var _content, _content2;
82
+
72
83
  // About TABLE atomic block entity data structure,
73
84
  // see `../views/editor/table.tsx` for more information.
74
85
  content = entity === null || entity === void 0 ? void 0 : entity.data;
75
86
  /** @type DraftEditor.TableEntity.TableStyles */
87
+
76
88
  const tableStyles = (_content = content) === null || _content === void 0 ? void 0 : _content.tableStyles;
77
89
  /** @type DraftEditor.TableEntity.TableData */
90
+
78
91
  const tableData = (_content2 = content) === null || _content2 === void 0 ? void 0 : _content2.tableData;
79
92
  const rowsJsx = tableData === null || tableData === void 0 ? void 0 : tableData.map((row, rIndex) => {
80
93
  var _tableStyles$rows;
94
+
81
95
  const colsJsx = row === null || row === void 0 ? void 0 : row.map((col, cIndex) => {
82
96
  var _tableStyles$columns, _tableStyles$cells, _tableStyles$cells$rI;
97
+
83
98
  const colStyle = tableStyles === null || tableStyles === void 0 ? void 0 : (_tableStyles$columns = tableStyles.columns) === null || _tableStyles$columns === void 0 ? void 0 : _tableStyles$columns[cIndex];
84
99
  const cellStyle = tableStyles === null || tableStyles === void 0 ? void 0 : (_tableStyles$cells = tableStyles.cells) === null || _tableStyles$cells === void 0 ? void 0 : (_tableStyles$cells$rI = _tableStyles$cells[rIndex]) === null || _tableStyles$cells$rI === void 0 ? void 0 : _tableStyles$cells$rI[cIndex];
85
100
  return /*#__PURE__*/React.createElement("td", {
@@ -94,17 +109,20 @@ const processor = {
94
109
  key: `row_${rIndex}`,
95
110
  style: tableStyles === null || tableStyles === void 0 ? void 0 : (_tableStyles$rows = tableStyles.rows) === null || _tableStyles$rows === void 0 ? void 0 : _tableStyles$rows[rIndex]
96
111
  }, colsJsx);
97
- });
98
- // Use `React.renderToStsaticMarkup` to generate plain HTML string
112
+ }); // Use `React.renderToStsaticMarkup` to generate plain HTML string
113
+
99
114
  const html = _server.default.renderToStaticMarkup( /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("tbody", null, rowsJsx)));
115
+
100
116
  content = [{
101
117
  html
102
118
  }];
103
119
  break;
104
120
  }
121
+
105
122
  case _entities.default.DIVIDER.type:
106
123
  content = ['<hr>'];
107
124
  break;
125
+
108
126
  case _entities.default.BLOCKQUOTE.type:
109
127
  // this is different from default blockquote of draftjs
110
128
  // so we name our specific blockquote as 'quoteby'
@@ -113,6 +131,7 @@ const processor = {
113
131
  content = _lodash.default.get(entity, 'data');
114
132
  content = Array.isArray(content) ? content : [content];
115
133
  break;
134
+
116
135
  case _entities.default.AUDIO.type:
117
136
  case _entities.default.IMAGE.type:
118
137
  case _entities.default.IMAGEDIFF.type:
@@ -128,13 +147,17 @@ const processor = {
128
147
  content = _lodash.default.get(entity, 'data');
129
148
  content = Array.isArray(content) ? content : [content];
130
149
  break;
150
+
131
151
  case _entities.default.IMAGELINK.type:
132
152
  {
133
153
  // use Embedded component to dangerouslySetInnerHTML
134
154
  type = _entities.default.EMBEDDEDCODE.type;
135
155
  alignment = entity.data && entity.data.alignment || alignment;
156
+
136
157
  let description = _lodash.default.get(entity, ['data', 'description'], '');
158
+
137
159
  let url = _lodash.default.get(entity, ['data', 'url'], '');
160
+
138
161
  content = [{
139
162
  caption: description,
140
163
  embeddedCodeWithoutScript: `<img alt="${description}" src="${url}" class="img-responsive"/>`,
@@ -142,11 +165,15 @@ const processor = {
142
165
  }];
143
166
  break;
144
167
  }
168
+
145
169
  case _entities.default.EMBEDDEDCODE.type:
146
170
  {
147
171
  alignment = entity.data && entity.data.alignment || alignment;
172
+
148
173
  let caption = _lodash.default.get(entity, ['data', 'caption'], '');
174
+
149
175
  let embeddedCode = _lodash.default.get(entity, ['data', 'embeddedCode'], '');
176
+
150
177
  let script = {};
151
178
  let scripts = [];
152
179
  let scriptTagStart = false;
@@ -186,11 +213,12 @@ const processor = {
186
213
  }];
187
214
  break;
188
215
  }
216
+
189
217
  default:
190
218
  return;
191
- }
219
+ } // block type of api data should be lower case
220
+
192
221
 
193
- // block type of api data should be lower case
194
222
  return new _apiDataInstance.default({
195
223
  id: block.key,
196
224
  alignment,
@@ -199,6 +227,7 @@ const processor = {
199
227
  styles
200
228
  });
201
229
  }
230
+
202
231
  };
203
232
  var _default = processor;
204
233
  exports.default = _default;
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  // 'use strict';
8
-
9
8
  const ENTITY = {
10
9
  DIVIDER: {
11
10
  type: 'DIVIDER'
@@ -4,19 +4,27 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+
7
8
  var _immutable = require("immutable");
9
+
8
10
  var _lodash = _interopRequireDefault(require("lodash"));
11
+
9
12
  var InlineStylesProcessor = _interopRequireWildcard(require("./inline-styles-processor"));
13
+
10
14
  var _apiDataInstance = _interopRequireDefault(require("./api-data-instance"));
15
+
11
16
  var _atomicBlockProcessor = _interopRequireDefault(require("./atomic-block-processor"));
17
+
12
18
  var _entities = _interopRequireDefault(require("./entities"));
19
+
13
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
+
14
22
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
+
15
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
- // Modified from https://github.com/dburrows/draft-js-basic-html-editor/blob/master/src/utils/draftRawToHtml.js
17
25
 
26
+ // Modified from https://github.com/dburrows/draft-js-basic-html-editor/blob/master/src/utils/draftRawToHtml.js
18
27
  // 'use strict';
19
-
20
28
  let defaultBlockTagMap = {
21
29
  atomic: `<div>%content%</div>`,
22
30
  blockquote: `<blockquote>%content%</blockquote>`,
@@ -46,6 +54,7 @@ let defaultEntityTagMap = {
46
54
  [_entities.default.INFOBOX.type]: ['<div class="info-box-container center"><div class="info-box-title"><%= data.title %></div><div class="info-box-body"><%= data.body %></div>', '</div>'],
47
55
  [_entities.default.STOREDIMAGE.type]: ['<img alt="<%= data.name %>" src="<%= data.url %>" srcset="<%= data.urlMobileSized %> 800w, <%= data.urlTabletSized %> 1280w, <%= data.urlDesktopSized %> 2400w" class="center">', '</img>'],
48
56
  [_entities.default.IMAGE.type]: ['<img alt="<%=data.name%>" src="<%=data.url%>" srcset="<%= data.mobile.url %> 800w, <%= data.tablet.url %> 1280w, <%= data.desktop.url %> 2400w" class="center">', '</img>'],
57
+
49
58
  /*[ENTITY.IMAGEDIFF.type]: ['<!-- imageDiff component start --> <ol class="image-diff-container"> <% _.forEach(data, function(image, index) { if (index > 1) { return; } %><li class="image-diff-item"><img src="<%- image.url %>" /></li><% }); %>', '</ol><!-- imageDiff component end-->'],
50
59
  [ENTITY.IMAGELINK.type]: ['<img alt="<%= data.description %>" src="<%= data.url %>" class="<%= data.alignment %>">', '</img>'],*/
51
60
  [_entities.default.LINK.type]: ['<a target="_blank" href="<%= data.url %>">', '</a>'],
@@ -57,35 +66,39 @@ let nestedTagMap = {
57
66
  'ordered-list-item': ['<ol>', '</ol>'],
58
67
  'unordered-list-item': ['<ul>', '</ul>']
59
68
  };
69
+
60
70
  function _convertInlineStyle(block, entityMap, blockTagMap, entityTagMap) {
61
71
  return blockTagMap[block.type] ? blockTagMap[block.type].replace('%content%', InlineStylesProcessor.convertToHtml(inlineTagMap, entityTagMap, entityMap, block)) : blockTagMap.default.replace('%content%', InlineStylesProcessor.convertToHtml(inlineTagMap, block));
62
72
  }
73
+
63
74
  function _convertBlocksToHtml(blocks, entityMap, blockTagMap, entityTagMap) {
64
75
  let html = '';
65
76
  let nestLevel = []; // store the list type of the previous item: null/ol/ul
77
+
66
78
  blocks.forEach(block => {
67
79
  // create tag for <ol> or <ul>: deal with ordered/unordered list item
68
80
  // if the block is a list-item && the previous block is not a list-item
69
81
  if (nestedTagMap[block.type] && nestLevel[0] !== block.type) {
70
82
  html += nestedTagMap[block.type][0]; // start with <ol> or <ul>
83
+
71
84
  nestLevel.unshift(block.type);
72
- }
85
+ } // end tag with </ol> or </ul>: deal with ordered/unordered list item
86
+
73
87
 
74
- // end tag with </ol> or </ul>: deal with ordered/unordered list item
75
88
  if (nestLevel.length > 0 && nestLevel[0] !== block.type) {
76
89
  html += nestedTagMap[nestLevel.shift()][1]; // close with </ol> or </ul>
77
90
  }
78
91
 
79
92
  html += _convertInlineStyle(block, entityMap, blockTagMap, entityTagMap);
80
- });
93
+ }); // end tag with </ol> or </ul>: or if it is the last block
81
94
 
82
- // end tag with </ol> or </ul>: or if it is the last block
83
95
  if (blocks.length > 0 && nestedTagMap[blocks[blocks.length - 1].type]) {
84
96
  html += nestedTagMap[nestLevel.shift()][1]; // close with </ol> or </ul>
85
97
  }
86
98
 
87
99
  return html;
88
100
  }
101
+
89
102
  function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
90
103
  let apiDataArr = (0, _immutable.List)();
91
104
  let content = [];
@@ -102,6 +115,7 @@ function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
102
115
  content = [];
103
116
  nestLevel.shift();
104
117
  }
118
+
105
119
  if (block.type.startsWith('atomic') || block.type.startsWith('media')) {
106
120
  try {
107
121
  apiDataArr = apiDataArr.push(_atomicBlockProcessor.default.convertBlock(entityMap, block));
@@ -110,6 +124,7 @@ function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
110
124
  }
111
125
  } else {
112
126
  var _block$data;
127
+
113
128
  let converted = InlineStylesProcessor.convertToHtml(inlineTagMap, entityTagMap, entityMap, block);
114
129
  const type = block.type;
115
130
  const textAlign = (_block$data = block.data) === null || _block$data === void 0 ? void 0 : _block$data.textAlign;
@@ -121,9 +136,8 @@ function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
121
136
  }));
122
137
  }
123
138
  } else {
124
- let converted = InlineStylesProcessor.convertToHtml(inlineTagMap, entityTagMap, entityMap, block);
139
+ let converted = InlineStylesProcessor.convertToHtml(inlineTagMap, entityTagMap, entityMap, block); // previous block is not an item-list block
125
140
 
126
- // previous block is not an item-list block
127
141
  if (nestLevel.length === 0) {
128
142
  nestLevel.unshift(block.type);
129
143
  content.push(converted);
@@ -141,9 +155,8 @@ function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
141
155
  nestLevel[0] = block.type;
142
156
  }
143
157
  }
144
- });
158
+ }); // last block is a item-list
145
159
 
146
- // last block is a item-list
147
160
  if (blocks.length > 0 && nestLevel.length > 0) {
148
161
  let block = blocks[blocks.length - 1];
149
162
  apiDataArr = apiDataArr.push(new _apiDataInstance.default({
@@ -152,8 +165,10 @@ function convertBlocksToApiData(blocks, entityMap, entityTagMap) {
152
165
  content: content
153
166
  }));
154
167
  }
168
+
155
169
  return apiDataArr;
156
170
  }
171
+
157
172
  function convertRawToHtml(raw, blockTagMap, entityTagMap) {
158
173
  blockTagMap = _lodash.default.merge({}, defaultBlockTagMap, blockTagMap);
159
174
  entityTagMap = entityTagMap || defaultEntityTagMap;
@@ -164,17 +179,21 @@ function convertRawToHtml(raw, blockTagMap, entityTagMap) {
164
179
  html = _convertBlocksToHtml(blocks, entityMap, blockTagMap, entityTagMap);
165
180
  return html;
166
181
  }
182
+
167
183
  function convertRawToApiData(raw) {
168
184
  let apiData;
169
185
  raw = raw || {};
170
186
  const blocks = Array.isArray(raw.blocks) ? raw.blocks : [];
171
187
  const entityMap = typeof raw.entityMap === 'object' ? raw.entityMap : {};
188
+
172
189
  let entityTagMap = _lodash.default.merge({}, defaultEntityTagMap, {
173
190
  [_entities.default.ANNOTATION.type]: [`<span data-entity-type="annotation" data-annotation-body="<%= data.bodyEscapedHTML %>">`, '</span>']
174
191
  });
192
+
175
193
  apiData = convertBlocksToApiData(blocks, entityMap, entityTagMap);
176
194
  return apiData;
177
195
  }
196
+
178
197
  var _default = {
179
198
  convertToHtml: convertRawToHtml,
180
199
  convertToApiData: convertRawToApiData
@@ -4,56 +4,72 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.convertToHtml = convertToHtml;
7
+
7
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
+
8
10
  var _const = require("../const");
11
+
9
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
- // Modified from https://github.com/dburrows/draft-js-basic-html-editor/blob/master/src/utils/processInlineStylesAndEntities.js
11
13
 
14
+ // Modified from https://github.com/dburrows/draft-js-basic-html-editor/blob/master/src/utils/processInlineStylesAndEntities.js
12
15
  function tagForCustomInlineStyle(style) {
13
16
  const customInlineStylePrefixs = [_const.CUSTOM_STYLE_PREFIX_FONT_COLOR, _const.CUSTOM_STYLE_PREFIX_BACKGROUND_COLOR];
14
17
  const stylePrefix = customInlineStylePrefixs.find(prefix => style.startsWith(prefix));
15
18
  let tag, value;
19
+
16
20
  switch (stylePrefix) {
17
21
  case _const.CUSTOM_STYLE_PREFIX_FONT_COLOR:
18
22
  value = style.split(_const.CUSTOM_STYLE_PREFIX_FONT_COLOR)[1];
19
23
  tag = [`<span style="color: ${value}">`, '</span>'];
20
24
  break;
25
+
21
26
  case _const.CUSTOM_STYLE_PREFIX_BACKGROUND_COLOR:
22
27
  value = style.split(_const.CUSTOM_STYLE_PREFIX_BACKGROUND_COLOR)[1];
23
28
  tag = [`<span style="background-color: ${value}">`, '</span>'];
24
29
  break;
30
+
25
31
  default:
26
32
  break;
27
33
  }
34
+
28
35
  return tag;
29
36
  }
37
+
30
38
  function _fullfilIntersection(block) {
31
39
  // SORT BEFORE PROCESSING
32
40
  let sortedISRanges = _lodash.default.sortBy(block.inlineStyleRanges, 'offset');
41
+
33
42
  let sortedEntityRanges = _lodash.default.sortBy(block.entityRanges, 'offset');
43
+
34
44
  let splitedISInline = [];
45
+
35
46
  for (let i = 0; i < sortedEntityRanges.length; i++) {
36
47
  let entityRange = sortedEntityRanges[i];
48
+
37
49
  for (let j = 0; j < sortedISRanges.length; j++) {
38
50
  let entityOffset = _lodash.default.get(entityRange, 'offset', 0);
51
+
39
52
  let entityLength = _lodash.default.get(entityRange, 'length', 0);
53
+
40
54
  let inlineLength = _lodash.default.get(sortedISRanges, [j, 'length'], 0);
55
+
41
56
  let inlineOffset = _lodash.default.get(sortedISRanges, [j, 'offset'], 0);
57
+
42
58
  let inlineStyle = _lodash.default.get(sortedISRanges, [j, 'style'], '');
59
+
43
60
  let nextEntityOffset = _lodash.default.get(sortedEntityRanges, [i + 1, 'offset'], 0);
44
- let nextEntityLength = _lodash.default.get(sortedEntityRanges, [i + 1, 'length'], 0);
45
61
 
46
- // handle intersections of inline style and entity
62
+ let nextEntityLength = _lodash.default.get(sortedEntityRanges, [i + 1, 'length'], 0); // handle intersections of inline style and entity
47
63
  // <a></a> is entity
48
64
  // <abbr></abbr> is next entity
49
65
  // <strong></strong> is inline style
50
- if (nextEntityOffset >= inlineOffset && nextEntityOffset < inlineOffset + inlineLength && nextEntityOffset + nextEntityLength > inlineOffset + inlineLength &&
51
- // <a><strong></a></strong>
66
+
67
+
68
+ if (nextEntityOffset >= inlineOffset && nextEntityOffset < inlineOffset + inlineLength && nextEntityOffset + nextEntityLength > inlineOffset + inlineLength && // <a><strong></a></strong>
52
69
  entityOffset < inlineOffset && entityOffset + entityLength > inlineOffset && entityOffset + entityLength <= inlineOffset + inlineLength) {
53
70
  // <strong><abbr></strong></abbr>
54
71
  // situation: <a><strong></a><abbr></strong></abbr>
55
72
  // should be: <a><strong></strong></a><strong></strong><abbr><strong></strong></abbr>
56
-
57
73
  // skip next entity checking
58
74
  i = i + 1;
59
75
  splitedISInline.push({
@@ -105,92 +121,109 @@ function _fullfilIntersection(block) {
105
121
  }
106
122
  }
107
123
  }
124
+
108
125
  _lodash.default.forEachRight(splitedISInline, ele => {
109
126
  sortedISRanges.splice(ele.index, 1, ...ele.replace);
110
127
  });
128
+
111
129
  return sortedISRanges;
112
130
  }
131
+
113
132
  function _inlineTag(inlineTagMap, inlineStyleRanges, tagInsertMap = {}) {
114
133
  // SORT BEFORE PROCESSING
115
- let sortedRanges = _lodash.default.sortBy(inlineStyleRanges, 'offset');
134
+ let sortedRanges = _lodash.default.sortBy(inlineStyleRanges, 'offset'); // map all the tag insertions we're going to do
135
+
116
136
 
117
- // map all the tag insertions we're going to do
118
137
  sortedRanges.forEach(function (range) {
119
- let tag = inlineTagMap[range.style];
138
+ let tag = inlineTagMap[range.style]; // handle dynamic inline style
120
139
 
121
- // handle dynamic inline style
122
140
  if (!tag) {
123
141
  tag = tagForCustomInlineStyle(range.style);
124
142
  }
143
+
125
144
  if (!tagInsertMap[range.offset]) {
126
145
  tagInsertMap[range.offset] = [];
127
- }
146
+ } // add starting tag to the end of the array to form the tag nesting
147
+
128
148
 
129
- // add starting tag to the end of the array to form the tag nesting
130
149
  tagInsertMap[range.offset].push(tag[0]);
150
+
131
151
  if (tag[1]) {
132
152
  if (!tagInsertMap[range.offset + range.length]) {
133
153
  tagInsertMap[range.offset + range.length] = [];
134
- }
135
- // add closing tags to start of array, otherwise tag nesting will be invalid
154
+ } // add closing tags to start of array, otherwise tag nesting will be invalid
155
+
156
+
136
157
  tagInsertMap[range.offset + range.length].unshift(tag[1]);
137
158
  }
138
159
  });
139
160
  return tagInsertMap;
140
161
  }
162
+
141
163
  function _entityTag(entityTagMap, entityMap, entityRanges, tagInsertMap = {}) {
142
164
  _lodash.default.forEach(entityRanges, range => {
143
165
  let entity = entityMap[range.key];
144
166
  let type = entity.type && entity.type.toUpperCase();
145
167
  let tag = entityTagMap[type];
146
168
  let data = entity.data;
169
+
147
170
  let compiledTag0 = _lodash.default.template(tag[0], {
148
171
  variable: 'data'
149
172
  })(data);
173
+
150
174
  let compiledTag1 = _lodash.default.template(tag[1], {
151
175
  variable: 'data'
152
176
  })(data);
177
+
153
178
  if (!tagInsertMap[range.offset]) {
154
179
  tagInsertMap[range.offset] = [];
155
- }
180
+ } // add starting tag
181
+
156
182
 
157
- // add starting tag
158
183
  tagInsertMap[range.offset].push(compiledTag0);
184
+
159
185
  if (tag[1]) {
160
186
  if (!tagInsertMap[range.offset + range.length]) {
161
187
  tagInsertMap[range.offset + range.length] = [];
162
- }
163
- // add closing tags to start of array, otherwise tag nesting will be invalid
188
+ } // add closing tags to start of array, otherwise tag nesting will be invalid
189
+
190
+
164
191
  tagInsertMap[range.offset + range.length].unshift(compiledTag1);
165
192
  }
166
193
  });
194
+
167
195
  return tagInsertMap;
168
196
  }
197
+
169
198
  function convertToHtml(inlineTagMap, entityTagMap, entityMap, block) {
170
199
  // exit if there is no inlineStyleRanges/entityRanges or length === 0 as well
171
200
  if (!block.inlineStyleRanges && !block.entityRanges || block.inlineStyleRanges.length === 0 && block.entityRanges.length === 0) {
172
201
  return block.text;
173
202
  }
203
+
174
204
  let html = block.text;
205
+
175
206
  let inlineStyleRanges = _fullfilIntersection(block);
207
+
176
208
  let tagInsertMap = {};
177
209
  tagInsertMap = _entityTag(entityTagMap, entityMap, block.entityRanges, tagInsertMap);
178
- tagInsertMap = _inlineTag(inlineTagMap, inlineStyleRanges, tagInsertMap);
210
+ tagInsertMap = _inlineTag(inlineTagMap, inlineStyleRanges, tagInsertMap); // sort on position, as we'll need to keep track of offset
179
211
 
180
- // sort on position, as we'll need to keep track of offset
181
212
  let orderedKeys = Object.keys(tagInsertMap).sort(function (a, b) {
182
213
  a = Number(a);
183
214
  b = Number(b);
215
+
184
216
  if (a > b) {
185
217
  return 1;
186
218
  }
219
+
187
220
  if (a < b) {
188
221
  return -1;
189
222
  }
223
+
190
224
  return 0;
191
- });
225
+ }); // insert tags into string, keep track of offset caused by our text insertions
192
226
 
193
- // insert tags into string, keep track of offset caused by our text insertions
194
227
  let offset = 0;
195
228
  orderedKeys.forEach(function (pos) {
196
229
  let index = Number(pos);
@@ -4,12 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Modifier = void 0;
7
+
7
8
  var _draftJs = require("draft-js");
9
+
8
10
  var _immutable = require("immutable");
9
- const Modifier = {
10
- ..._draftJs.Modifier
11
- };
12
11
 
12
+ const Modifier = { ..._draftJs.Modifier
13
+ };
13
14
  /*
14
15
  This method is specified for custom inline style such as 'FONT_COLOR_#ffffff'.
15
16
  For this kind of inline style there may be more than one style name 'FONT_COLOR_#ffffff', 'FONT_COLOR_#000000'.
@@ -21,18 +22,20 @@ const Modifier = {
21
22
 
22
23
  Reference: https://github.com/facebook/draft-js/blob/main/src/model/transaction/ContentStateInlineStyle.js#L39-L88
23
24
  */
25
+
24
26
  exports.Modifier = Modifier;
27
+
25
28
  Modifier.removeInlineStyleByPrefix = (contentState, selectionState, inlineStylePrefix) => {
26
29
  const blockMap = contentState.getBlockMap();
27
30
  const startKey = selectionState.getStartKey();
28
31
  const startOffset = selectionState.getStartOffset();
29
32
  const endKey = selectionState.getEndKey();
30
- const endOffset = selectionState.getEndOffset();
33
+ const endOffset = selectionState.getEndOffset(); // loop through all selected blocks and every block chars to remove specific inline style
31
34
 
32
- // loop through all selected blocks and every block chars to remove specific inline style
33
35
  const newBlocks = blockMap.skipUntil((_, k) => k === startKey).takeUntil((_, k) => k === endKey).concat((0, _immutable.Map)([[endKey, blockMap.get(endKey)]])).map((block, blockKey) => {
34
36
  let sliceStart;
35
37
  let sliceEnd;
38
+
36
39
  if (startKey === endKey) {
37
40
  sliceStart = startOffset;
38
41
  sliceEnd = endOffset;
@@ -40,16 +43,21 @@ Modifier.removeInlineStyleByPrefix = (contentState, selectionState, inlineStyleP
40
43
  sliceStart = blockKey === startKey ? startOffset : 0;
41
44
  sliceEnd = blockKey === endKey ? endOffset : block.getLength();
42
45
  }
46
+
43
47
  let chars = block.getCharacterList();
44
48
  let current;
49
+
45
50
  while (sliceStart < sliceEnd) {
46
51
  current = chars.get(sliceStart);
47
52
  const inlineStyle = current.getStyle().find(styleName => styleName.startsWith(inlineStylePrefix));
53
+
48
54
  if (inlineStyle) {
49
55
  chars = chars.set(sliceStart, _draftJs.CharacterMetadata.removeStyle(current, inlineStyle));
50
56
  }
57
+
51
58
  sliceStart++;
52
59
  }
60
+
53
61
  return block.set('characterList', chars);
54
62
  });
55
63
  return contentState.merge({
package/lib/index.js CHANGED
@@ -21,7 +21,11 @@ Object.defineProperty(exports, "draftConverter", {
21
21
  return _draftConverter.default;
22
22
  }
23
23
  });
24
+
24
25
  var _draftConverter = _interopRequireDefault(require("./draft-js/draft-converter"));
26
+
25
27
  var _mirrormedia = _interopRequireDefault(require("./website/mirrormedia"));
28
+
26
29
  var _readr = _interopRequireDefault(require("./website/readr"));
30
+
27
31
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }