embed.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import Parchment from 'parchment';
  2. import TextBlot from './text';
  3. const GUARD_TEXT = "\uFEFF";
  4. class Embed extends Parchment.Embed {
  5. constructor(node) {
  6. super(node);
  7. this.contentNode = document.createElement('span');
  8. this.contentNode.setAttribute('contenteditable', false);
  9. [].slice.call(this.domNode.childNodes).forEach((childNode) => {
  10. this.contentNode.appendChild(childNode);
  11. });
  12. this.leftGuard = document.createTextNode(GUARD_TEXT);
  13. this.rightGuard = document.createTextNode(GUARD_TEXT);
  14. this.domNode.appendChild(this.leftGuard);
  15. this.domNode.appendChild(this.contentNode);
  16. this.domNode.appendChild(this.rightGuard);
  17. }
  18. index(node, offset) {
  19. if (node === this.leftGuard) return 0;
  20. if (node === this.rightGuard) return 1;
  21. return super.index(node, offset);
  22. }
  23. restore(node) {
  24. let range, textNode;
  25. let text = node.data.split(GUARD_TEXT).join('');
  26. if (node === this.leftGuard) {
  27. if (this.prev instanceof TextBlot) {
  28. let prevLength = this.prev.length();
  29. this.prev.insertAt(prevLength, text);
  30. range = {
  31. startNode: this.prev.domNode,
  32. startOffset: prevLength + text.length
  33. };
  34. } else {
  35. textNode = document.createTextNode(text);
  36. this.parent.insertBefore(Parchment.create(textNode), this);
  37. range = {
  38. startNode: textNode,
  39. startOffset: text.length
  40. };
  41. }
  42. } else if (node === this.rightGuard) {
  43. if (this.next instanceof TextBlot) {
  44. this.next.insertAt(0, text);
  45. range = {
  46. startNode: this.next.domNode,
  47. startOffset: text.length
  48. }
  49. } else {
  50. textNode = document.createTextNode(text);
  51. this.parent.insertBefore(Parchment.create(textNode), this.next);
  52. range = {
  53. startNode: textNode,
  54. startOffset: text.length
  55. };
  56. }
  57. }
  58. node.data = GUARD_TEXT;
  59. return range;
  60. }
  61. update(mutations, context) {
  62. mutations.forEach((mutation) => {
  63. if (mutation.type === 'characterData' &&
  64. (mutation.target === this.leftGuard || mutation.target === this.rightGuard)) {
  65. let range = this.restore(mutation.target);
  66. if (range) context.range = range;
  67. }
  68. });
  69. }
  70. }
  71. export default Embed;