getschemavalidranges.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module core/command/helpers/getschemavalidranges
  7. */
  8. import TreeWalker from 'ckeditor5-engine/src/model/treewalker';
  9. import Range from 'ckeditor5-engine/src/model/range';
  10. import Position from 'ckeditor5-engine/src/model/position';
  11. /**
  12. * Walks through given array of ranges and removes parts of them that are not allowed by passed schema to have the
  13. * attribute set. This is done by breaking a range in two and omitting the not allowed part.
  14. *
  15. * @param {String} attribute Attribute key.
  16. * @param {Array.<module:engine/model/range~Range>} ranges Ranges to be validated.
  17. * @param {module:engine/model/schema~Schema} schema Document schema.
  18. * @returns {Array.<module:engine/model/range~Range>} Ranges without invalid parts.
  19. */
  20. export default function getSchemaValidRanges( attribute, ranges, schema ) {
  21. const validRanges = [];
  22. for ( let range of ranges ) {
  23. const walker = new TreeWalker( { boundaries: range, mergeCharacters: true } );
  24. let step = walker.next();
  25. let last = range.start;
  26. let from = range.start;
  27. let to = range.end;
  28. while ( !step.done ) {
  29. const name = step.value.item.name || '$text';
  30. const itemPosition = Position.createBefore( step.value.item );
  31. if ( !schema.check( { name: name, inside: itemPosition, attributes: attribute } ) ) {
  32. if ( !from.isEqual( last ) ) {
  33. validRanges.push( new Range( from, last ) );
  34. }
  35. from = walker.position;
  36. }
  37. last = walker.position;
  38. step = walker.next();
  39. }
  40. if ( from && !from.isEqual( to ) ) {
  41. validRanges.push( new Range( from, to ) );
  42. }
  43. }
  44. return validRanges;
  45. }