1 import { Editor, Plain, Raw } from 'slate' |
1 import { Editor, Plain, Raw } from 'slate' |
2 import React from 'react' |
2 import React from 'react' |
3 import Portal from 'react-portal' |
3 import Portal from 'react-portal' |
4 import moment from 'moment' |
4 import moment from 'moment' |
|
5 import Immutable from 'immutable' |
5 import HtmlSerializer from '../HtmlSerializer' |
6 import HtmlSerializer from '../HtmlSerializer' |
6 import AnnotationPlugin from '../AnnotationPlugin' |
7 import AnnotationPlugin from '../AnnotationPlugin' |
7 import CategoriesTooltip from './CategoriesTooltip' |
8 import CategoriesTooltip from './CategoriesTooltip' |
8 |
9 |
9 const plugins = []; |
10 const plugins = []; |
162 return Raw.serialize(this.state.state); |
164 return Raw.serialize(this.state.state); |
163 } |
165 } |
164 |
166 |
165 asHtml = () => { |
167 asHtml = () => { |
166 return HtmlSerializer.serialize(this.state.state); |
168 return HtmlSerializer.serialize(this.state.state); |
|
169 } |
|
170 |
|
171 asCategories = () => { |
|
172 return this.state.categories |
|
173 } |
|
174 |
|
175 removeCategory = (categories, key, text) => { |
|
176 const categoryIndex = categories.findIndex(category => category.key === key && category.text === text) |
|
177 return categories.delete(categoryIndex) |
167 } |
178 } |
168 |
179 |
169 clear = () => { |
180 clear = () => { |
170 const state = Plain.deserialize(''); |
181 const state = Plain.deserialize(''); |
171 this.onChange(state); |
182 this.onChange(state); |
219 */ |
230 */ |
220 |
231 |
221 onClickMark = (e, type) => { |
232 onClickMark = (e, type) => { |
222 e.preventDefault() |
233 e.preventDefault() |
223 const { state } = this.state |
234 const { state } = this.state |
|
235 let { categories } = this.state |
224 const transform = state.transform() |
236 const transform = state.transform() |
225 |
237 |
226 let isPortalOpen = false; |
238 let isPortalOpen = false; |
227 |
239 |
228 if (type === 'category') { |
240 if (type === 'category') { |
229 // Can't use toggleMark here, because it expects the same object |
241 // Can't use toggleMark here, because it expects the same object |
230 // @see https://github.com/ianstormtaylor/slate/issues/873 |
242 // @see https://github.com/ianstormtaylor/slate/issues/873 |
231 if (this.hasMark('category')) { |
243 if (this.hasMark('category')) { |
232 state.marks.forEach(mark => transform.removeMark(mark)); |
244 const categoryMarks = state.marks.filter(mark => mark.type === 'category') |
|
245 categoryMarks.forEach(mark => { |
|
246 const key = mark.data.get('key'); |
|
247 const text = mark.data.get('text'); |
|
248 |
|
249 categories = this.removeCategory(categories, key, text) |
|
250 transform.removeMark(mark) |
|
251 }) |
|
252 |
233 } else { |
253 } else { |
234 isPortalOpen = !this.state.isPortalOpen; |
254 isPortalOpen = !this.state.isPortalOpen; |
235 } |
255 } |
236 } else { |
256 } else { |
237 transform.toggleMark(type) |
257 transform.toggleMark(type) |
238 } |
258 } |
239 |
259 |
240 this.setState({ |
260 this.setState({ |
241 state: transform.apply(), |
261 state: transform.apply(), |
242 isPortalOpen: isPortalOpen |
262 isPortalOpen: isPortalOpen, |
|
263 categories: categories |
243 }) |
264 }) |
244 } |
265 } |
245 |
266 |
246 /** |
267 /** |
247 * When a block button is clicked, toggle the block type. |
268 * When a block button is clicked, toggle the block type. |
316 }) |
337 }) |
317 } |
338 } |
318 |
339 |
319 onCategoryClick = (category) => { |
340 onCategoryClick = (category) => { |
320 |
341 |
321 const { state } = this.state; |
342 const { state, currentSelectionText } = this.state; |
|
343 let { categories } = this.state; |
322 const transform = state.transform(); |
344 const transform = state.transform(); |
323 |
345 |
324 state.marks.forEach(mark => transform.removeMark(mark)); |
346 const categoryMarks = state.marks.filter(mark => mark.type === 'category') |
|
347 categoryMarks.forEach(mark => transform.removeMark(mark)); |
|
348 |
325 transform.addMark({ |
349 transform.addMark({ |
326 type: 'category', |
350 type: 'category', |
327 data: { |
351 data: { |
328 text: this.state.currentSelectionText, |
352 text: currentSelectionText, |
329 color: category.color, |
353 color: category.color, |
330 key: category.key |
354 key: category.key |
331 } |
355 } |
332 }) |
356 }) |
333 |
357 |
|
358 Object.assign(category, { |
|
359 text: currentSelectionText |
|
360 }); |
|
361 categories = categories.push(category); |
|
362 |
334 this.setState({ |
363 this.setState({ |
335 state: transform.apply(), |
364 state: transform.apply(), |
336 isPortalOpen: false |
365 isPortalOpen: false, |
|
366 categories: categories |
337 }); |
367 }); |
338 } |
368 } |
339 |
369 |
340 /** |
370 /** |
341 * Render. |
371 * Render. |