8
0

utils.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module typing/utils/utils
  7. */
  8. import diff from '@ckeditor/ckeditor5-utils/src/diff';
  9. import diffToChanges from '@ckeditor/ckeditor5-utils/src/difftochanges';
  10. /**
  11. * Returns true if container children have mutated or more than a single text node was changed.
  12. *
  13. * @private
  14. * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|
  15. * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations
  16. * @returns {Boolean}
  17. */
  18. export function containerChildrenMutated( mutations ) {
  19. if ( mutations.length == 0 ) {
  20. return false;
  21. }
  22. // Check if there is any mutation of `children` type or any mutation that changes more than one text node.
  23. for ( const mutation of mutations ) {
  24. if ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {
  25. return true;
  26. }
  27. }
  28. return false;
  29. }
  30. /**
  31. * Returns change made to a single text node.
  32. *
  33. * @private
  34. * @param {module:engine/view/observer/mutationobserver~MutatedText|
  35. * module:engine/view/observer/mutationobserver~MutatedChildren} mutation
  36. * @returns {Object|undefined} Change object (see {@link module:utils/difftochanges~diffToChanges} output)
  37. * or undefined if more than a single text node was changed.
  38. */
  39. export function getSingleTextNodeChange( mutation ) {
  40. // One new node.
  41. if ( mutation.newChildren.length - mutation.oldChildren.length != 1 ) {
  42. return;
  43. }
  44. // Which is text.
  45. const diffResult = diff( mutation.oldChildren, mutation.newChildren, compareChildNodes );
  46. const changes = diffToChanges( diffResult, mutation.newChildren );
  47. // In case of [ delete, insert, insert ] the previous check will not exit.
  48. if ( changes.length > 1 ) {
  49. return;
  50. }
  51. const change = changes[ 0 ];
  52. // Which is text.
  53. if ( !( !!change.values[ 0 ] && change.values[ 0 ].is( 'text' ) ) ) {
  54. return;
  55. }
  56. return change;
  57. }
  58. /**
  59. * Checks whether two view nodes are identical, which means they are the same object
  60. * or contain exactly same data (in case of text nodes).
  61. *
  62. * @private
  63. * @param {module:engine/view/node~Node} oldChild
  64. * @param {module:engine/view/node~Node} newChild
  65. * @returns {Boolean}
  66. */
  67. export function compareChildNodes( oldChild, newChild ) {
  68. if ( !!oldChild && oldChild.is( 'text' ) && !!newChild && newChild.is( 'text' ) ) {
  69. return oldChild.data === newChild.data;
  70. } else {
  71. return oldChild === newChild;
  72. }
  73. }