1 | import Parse from '../parse';
|
2 | import { helperGetLastLIne } from '../helpers';
|
3 | import { isObject } from '../utils';
|
4 |
|
5 | const getUrlType = (url) => {
|
6 | if (url.includes('guihuazhi.com')) {
|
7 | if (url.includes('article')) {
|
8 | return 'article';
|
9 | } else if (url.includes('topic')) {
|
10 | return 'topic';
|
11 | } else {
|
12 | return 'other';
|
13 | }
|
14 | } else {
|
15 | return 'other';
|
16 | }
|
17 | };
|
18 |
|
19 | let routes = {
|
20 | article: {
|
21 | route: '/app/article/detail',
|
22 | id: 'aid'
|
23 | },
|
24 | topic: {
|
25 | route: '/app/topic/detail',
|
26 | id: 'topicId'
|
27 | },
|
28 | other: {
|
29 | route: '',
|
30 | id: 'id'
|
31 | }
|
32 | };
|
33 |
|
34 | const getId = (url) => {
|
35 | let str = url.split('?')[0].split('/').pop();
|
36 | return str.slice(0, -5);
|
37 | };
|
38 |
|
39 | const textToJson = (element) => {
|
40 | return {
|
41 | type: 'string',
|
42 | content: element.nodeValue
|
43 | };
|
44 | };
|
45 |
|
46 | const strongToJson = (element) => {
|
47 | return {
|
48 | type: 'string',
|
49 | bold: 1,
|
50 | content: element.innerText
|
51 | };
|
52 | };
|
53 |
|
54 | const aToJson = (element) => {
|
55 | let link = element.href;
|
56 | let type = getUrlType(link);
|
57 | let info = routes[type];
|
58 | return {
|
59 | type: 'link',
|
60 | content: element.innerText,
|
61 | route: {
|
62 | route: info.route,
|
63 | webUrl: link,
|
64 | params: {
|
65 | [info.id]: getId(link)
|
66 | }
|
67 | }
|
68 | };
|
69 | };
|
70 |
|
71 | const getValue = (element) => {
|
72 | let elementList = element.childNodes;
|
73 | let length = elementList.length;
|
74 | let value = [];
|
75 | for (let i = 0; i < length; i++) {
|
76 | let element = elementList[i];
|
77 | let elementType = element.nodeName;
|
78 | let func = elementListToJsonMap[elementType];
|
79 | if (func) {
|
80 | let result = func(element);
|
81 | value.push(result);
|
82 | }
|
83 | }
|
84 | return value;
|
85 | };
|
86 |
|
87 | const blockElementToJson = (element) => {
|
88 | let o = {
|
89 | type: 'text'
|
90 | };
|
91 | if (element.nodeName === 'H2') {
|
92 | o.head = 1;
|
93 | } else if (element.nodeName === 'BLOCKQUOTE') {
|
94 | o.block = 1;
|
95 | }
|
96 | if (element.classList.contains('ql-align-center')) {
|
97 | o.center = 1;
|
98 | }
|
99 | o.value = getValue(element);
|
100 | return o;
|
101 | };
|
102 |
|
103 | const hrToJson = () => {
|
104 | return {
|
105 | type: 'line'
|
106 | };
|
107 | };
|
108 |
|
109 | const imageToJson = (element) => {
|
110 | let o = {
|
111 | type: 'image'
|
112 | };
|
113 | let height = element.getAttribute('height');
|
114 | let width = element.getAttribute('width');
|
115 | let size = element.getAttribute('size');
|
116 | let format = element.getAttribute('format');
|
117 | let url = element.getAttribute('url');
|
118 | let value = element.getAttribute('value');
|
119 | o = Object.assign(o, {height, width, size, format, url, desc: value});
|
120 | return o;
|
121 | };
|
122 |
|
123 | const videoToJson = (element) => {
|
124 | let o = {
|
125 | type: 'video'
|
126 | };
|
127 | let result = JSON.parse(element.getAttribute('result'));
|
128 | o = Object.assign(o, result);
|
129 | return o;
|
130 | };
|
131 |
|
132 | const divToJson = (element) => {
|
133 | if (element.classList.contains('huazhi-image')) {
|
134 | return imageToJson(element);
|
135 | } else if (element.classList.contains('huazhi-video')) {
|
136 | return videoToJson(element);
|
137 | }
|
138 | };
|
139 |
|
140 | const listToJson = (element) => {
|
141 | let o = {};
|
142 | let value = [];
|
143 | if (element.nodeName === 'UL') {
|
144 | o.type = 'ul'
|
145 | } else if (element.nodeName === 'OL') {
|
146 | o.type = 'ol'
|
147 | }
|
148 | let elementList = element.childNodes;
|
149 | let length = elementList.length;
|
150 | for (let i = 0; i < length; i++) {
|
151 | let element = elementList[i];
|
152 | let result = getValue(element);
|
153 | value.push(result);
|
154 | }
|
155 | o.value = value;
|
156 | return o;
|
157 | };
|
158 |
|
159 | const elementListToJsonMap = {
|
160 | '#text': textToJson,
|
161 | 'STRONG': strongToJson,
|
162 | 'A': aToJson,
|
163 | 'P': blockElementToJson,
|
164 | 'H2': blockElementToJson,
|
165 | 'BLOCKQUOTE': blockElementToJson,
|
166 | 'HR': hrToJson,
|
167 | 'DIV': divToJson,
|
168 | 'VIDEO': videoToJson,
|
169 | 'UL': listToJson,
|
170 | 'OL': listToJson
|
171 | };
|
172 |
|
173 | const removeSpace = (json) => {
|
174 |
|
175 | let length = json.length;
|
176 | let count1 = 0;
|
177 | let count2 = length;
|
178 | for (let i = 0; i < length; i++) {
|
179 | if (json[i].value && json[i].value.length === 0) {
|
180 | count1 += 1;
|
181 | } else {
|
182 | break;
|
183 | }
|
184 | }
|
185 | for (let i = length - 1; i >= 0; i--) {
|
186 | if (json[i].value && json[i].value.length === 0) {
|
187 | count2 -= 1;
|
188 | } else {
|
189 | break;
|
190 | }
|
191 | }
|
192 | return json.slice(count1, count2);
|
193 | };
|
194 |
|
195 |
|
196 | class WebRich extends Parse {
|
197 | constructor(option) {
|
198 | super(option);
|
199 | }
|
200 |
|
201 | renderImage(props) {
|
202 |
|
203 | let {format, height, width, size, url, desc = ''} = props;
|
204 | let o = {format, height, width, size, url};
|
205 | let value = desc.replace(/ /g," ");
|
206 | return `<div class="huazhi-image" image=${JSON.stringify(o)} value=${value}></div>`;
|
207 | }
|
208 |
|
209 | renderLink(props) {
|
210 |
|
211 | return `<a class="huazhi-link" target="_blank" href="${props.route.webUrl || props.route.webURL}">${props.content}</a>`;
|
212 | }
|
213 |
|
214 | renderVideo(props) {
|
215 | return `<video class="huazhi-video" src="${props.url}" controls="controls" result=${JSON.stringify(props)}></video>`;
|
216 | }
|
217 |
|
218 |
|
219 | |
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 | elementListToJson(elementList) {
|
226 | let length = elementList.length;
|
227 | let json = [];
|
228 | for (let i = 0; i < length; i++) {
|
229 | let element = elementList[i];
|
230 | let elementType = element.nodeName;
|
231 | let func = elementListToJsonMap[elementType];
|
232 | if (func) {
|
233 | let result = func(element);
|
234 | json.push(result);
|
235 | }
|
236 | }
|
237 | json = removeSpace(json);
|
238 | return json;
|
239 | };
|
240 |
|
241 | |
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 | opsToHTML(source, isJSonString = false) {
|
249 | let results = [];
|
250 |
|
251 | let tmp = null;
|
252 | for (let i = 0, l = source.length; i < l; i++) {
|
253 | let { insert, attributes = {} } = source[i];
|
254 |
|
255 | if (typeof insert === 'string') {
|
256 | const { bold, header, blockquote, link } = attributes;
|
257 | if (!tmp) {
|
258 | tmp = {
|
259 | type: 'text',
|
260 | value: []
|
261 | };
|
262 | }
|
263 |
|
264 |
|
265 | if (header === 2 || blockquote === true) {
|
266 | let lastLine = helperGetLastLIne(tmp.value);
|
267 |
|
268 | if (tmp.value.length) {
|
269 | results.push(tmp);
|
270 | }
|
271 |
|
272 | tmp = null;
|
273 | let block = {
|
274 | type: 'text',
|
275 | value: lastLine
|
276 | };
|
277 | if (header === 2) block.head = 1;
|
278 |
|
279 | if (blockquote === true) block.block = 1;
|
280 |
|
281 | results.push(block);
|
282 | } else if (bold) {
|
283 | tmp.value.push({ type: 'string', bold: 1, content: insert });
|
284 | } else if (link) {
|
285 |
|
286 | let type = getUrlType(link);
|
287 | let info = routes[type];
|
288 | let value = {
|
289 | type: 'link',
|
290 | content: insert,
|
291 | route: {
|
292 | route: info.route,
|
293 | webUrl: link,
|
294 | params: {
|
295 | [info.id]: getId(link)
|
296 | }
|
297 | }
|
298 | };
|
299 | tmp.value.push(value);
|
300 | } else {
|
301 | tmp.value.push({ type: 'string', content: insert });
|
302 | }
|
303 |
|
304 |
|
305 | } else if (isObject(insert)) {
|
306 |
|
307 | if (tmp && tmp.value.length) {
|
308 | results.push(tmp);
|
309 | tmp = null;
|
310 | }
|
311 |
|
312 |
|
313 | if (insert.image && this.isImage(insert.image)) {
|
314 | results.push({ ...insert.image, type: 'image' });
|
315 | }
|
316 |
|
317 |
|
318 | if (insert.hr === true) {
|
319 | results.push({
|
320 | type: 'line'
|
321 | });
|
322 | }
|
323 |
|
324 |
|
325 | if (insert.simpleVideo && insert.simpleVideo.url) {
|
326 | results.push({ ...insert.simpleVideo, type: 'video' });
|
327 | }
|
328 | }
|
329 |
|
330 |
|
331 | if (i === l - 1 && tmp) {
|
332 | results.push(tmp);
|
333 | }
|
334 | }
|
335 | return isJSonString ? JSON.stringify(results) : results;
|
336 | }
|
337 | }
|
338 |
|
339 | export default WebRich;
|