model/annotationHelpers.js
function transferAnnotations (doc, path, offset, newPath, newOffset) {
  var index = doc.getIndex('annotations')
  var annotations = index.get(path, offset)
  for (let i = 0; i < annotations.length; i++) {
    let a = annotations[i]
    var isInside = (offset > a.start.offset && offset < a.end.offset)
    var start = a.start.offset
    var end = a.end.offset
    // 1. if the cursor is inside an annotation it gets either split or truncated
    if (isInside) {
      // create a new annotation if the annotation is splittable
      if (a.canSplit()) {
        let newAnno = a.toJSON()
        newAnno.id = uuid(a.type + '_')
        newAnno.start.path = newPath
        newAnno.start.offset = newOffset
        newAnno.end.path = newPath
        newAnno.end.offset = newOffset + a.end.offset - offset
        doc.create(newAnno)
      }
      // in either cases truncate the first part
      let newStartOffset = a.start.offset
      let newEndOffset = offset
      // if after truncate the anno is empty, delete it
      if (newEndOffset === newStartOffset) {
        doc.delete(a.id)
      // ... otherwise update the range
      } else {
        // TODO: Use coordintate ops!
        if (newStartOffset !== start) {
          doc.set([a.id, 'start', 'offset'], newStartOffset)
        }
        if (newEndOffset !== end) {
          doc.set([a.id, 'end', 'offset'], newEndOffset)
        }
      }
    // 2. if the cursor is before an annotation then simply transfer the annotation to the new node
    } else if (a.start.offset >= offset) {
      // TODO: Use coordintate ops!
      // Note: we are preserving the annotation so that anything which is connected to the annotation
      // remains valid.
      doc.set([a.id, 'start', 'path'], newPath)
      doc.set([a.id, 'start', 'offset'], newOffset + a.start.offset - offset)
      doc.set([a.id, 'end', 'path'], newPath)
      doc.set([a.id, 'end', 'offset'], newOffset + a.end.offset - offset)
    }
  }

  // TODO: fix support for container annotations
  // // same for container annotation anchors
  // index = doc.getIndex('container-annotation-anchors');
  // var anchors = index.get(path);
  // var containerAnnoIds = [];
  // forEach(anchors, function(anchor) {
  //   containerAnnoIds.push(anchor.id);
  //   var start = anchor.offset;
  //   if (offset <= start) {
  //     // TODO: Use coordintate ops!
  //     let coor = anchor.isStart?'start':'end'
  //     doc.set([anchor.id, coor, 'path'], newPath);
  //     doc.set([anchor.id, coor, 'offset'], newOffset + anchor.offset - offset);
  //   }
  // });
  // // check all anchors after that if they have collapsed and remove the annotation in that case
  // forEach(uniq(containerAnnoIds), function(id) {
  //   var anno = doc.get(id);
  //   var annoSel = anno.getSelection();
  //   if(annoSel.isCollapsed()) {
  //     // console.log("...deleting container annotation because it has collapsed" + id);
  //     doc.delete(id);
  //   }
  // });
}
function transferAnnotations (doc, path, offset, newPath, newOffset) {
  var index = doc.getIndex('annotations')
  var annotations = index.get(path, offset)
  for (let i = 0; i < annotations.length; i++) {
    let a = annotations[i]
    var isInside = (offset > a.start.offset && offset < a.end.offset)
    var start = a.start.offset
    var end = a.end.offset
    // 1. if the cursor is inside an annotation it gets either split or truncated
    if (isInside) {
      // create a new annotation if the annotation is splittable
      if (a.canSplit()) {
        let newAnno = a.toJSON()
        newAnno.id = uuid(a.type + '_')
        newAnno.start.path = newPath
        newAnno.start.offset = newOffset
        newAnno.end.path = newPath
        newAnno.end.offset = newOffset + a.end.offset - offset
        doc.create(newAnno)
      }
      // in either cases truncate the first part
      let newStartOffset = a.start.offset
      let newEndOffset = offset
      // if after truncate the anno is empty, delete it
      if (newEndOffset === newStartOffset) {
        doc.delete(a.id)
      // ... otherwise update the range
      } else {
        // TODO: Use coordintate ops!
        if (newStartOffset !== start) {
          doc.set([a.id, 'start', 'offset'], newStartOffset)
        }
        if (newEndOffset !== end) {
          doc.set([a.id, 'end', 'offset'], newEndOffset)
        }
      }
    // 2. if the cursor is before an annotation then simply transfer the annotation to the new node
    } else if (a.start.offset >= offset) {
      // TODO: Use coordintate ops!
      // Note: we are preserving the annotation so that anything which is connected to the annotation
      // remains valid.
      doc.set([a.id, 'start', 'path'], newPath)
      doc.set([a.id, 'start', 'offset'], newOffset + a.start.offset - offset)
      doc.set([a.id, 'end', 'path'], newPath)
      doc.set([a.id, 'end', 'offset'], newOffset + a.end.offset - offset)
    }
  }

  // TODO: fix support for container annotations
  // // same for container annotation anchors
  // index = doc.getIndex('container-annotation-anchors');
  // var anchors = index.get(path);
  // var containerAnnoIds = [];
  // forEach(anchors, function(anchor) {
  //   containerAnnoIds.push(anchor.id);
  //   var start = anchor.offset;
  //   if (offset <= start) {
  //     // TODO: Use coordintate ops!
  //     let coor = anchor.isStart?'start':'end'
  //     doc.set([anchor.id, coor, 'path'], newPath);
  //     doc.set([anchor.id, coor, 'offset'], newOffset + anchor.offset - offset);
  //   }
  // });
  // // check all anchors after that if they have collapsed and remove the annotation in that case
  // forEach(uniq(containerAnnoIds), function(id) {
  //   var anno = doc.get(id);
  //   var annoSel = anno.getSelection();
  //   if(annoSel.isCollapsed()) {
  //     // console.log("...deleting container annotation because it has collapsed" + id);
  //     doc.delete(id);
  //   }
  // });
}
function transferAnnotations ( doc , path , offset , newPath , newOffset ) { var index = doc . getIndex ( 'annotations' ) var annotations = index . get ( path , offset ) for ( let i = 0 ; i < annotations . length ; i ++ ) { let a = annotations [ i ] var isInside = ( offset > a . start . offset && offset < a . end . offset ) var start = a . start . offset var end = a . end . offset // 1. if the cursor is inside an annotation it gets either split or truncated if ( isInside ) { // create a new annotation if the annotation is splittable if ( a . canSplit ( ) ) { let newAnno = a . toJSON ( ) newAnno . id = uuid ( a . type + '_' ) newAnno . start . path = newPath newAnno . start . offset = newOffset newAnno . end . path = newPath newAnno . end . offset = newOffset + a . end . offset - offset doc . create ( newAnno ) } // in either cases truncate the first part let newStartOffset = a . start . offset let newEndOffset = offset // if after truncate the anno is empty, delete it if ( newEndOffset === newStartOffset ) { doc . delete ( a . id ) // ... otherwise update the range } else { // TODO: Use coordintate ops! if ( newStartOffset !== start ) { doc . set ( [ a . id , 'start' , 'offset' ] , newStartOffset ) } if ( newEndOffset !== end ) { doc . set ( [ a . id , 'end' , 'offset' ] , newEndOffset ) } } // 2. if the cursor is before an annotation then simply transfer the annotation to the new node } else if ( a . start . offset >= offset ) { // TODO: Use coordintate ops! // Note: we are preserving the annotation so that anything which is connected to the annotation // remains valid. doc . set ( [ a . id , 'start' , 'path' ] , newPath ) doc . set ( [ a . id , 'start' , 'offset' ] , newOffset + a . start . offset - offset ) doc . set ( [ a . id , 'end' , 'path' ] , newPath ) doc . set ( [ a . id , 'end' , 'offset' ] , newOffset + a . end . offset - offset ) } } // TODO: fix support for container annotations // // same for container annotation anchors // index = doc.getIndex('container-annotation-anchors'); // var anchors = index.get(path); // var containerAnnoIds = []; // forEach(anchors, function(anchor) { //   containerAnnoIds.push(anchor.id); //   var start = anchor.offset; //   if (offset <= start) { //     // TODO: Use coordintate ops! //     let coor = anchor.isStart?'start':'end' //     doc.set([anchor.id, coor, 'path'], newPath); //     doc.set([anchor.id, coor, 'offset'], newOffset + anchor.offset - offset); //   } // }); // // check all anchors after that if they have collapsed and remove the annotation in that case // forEach(uniq(containerAnnoIds), function(id) { //   var anno = doc.get(id); //   var annoSel = anno.getSelection(); //   if(annoSel.isCollapsed()) { //     // console.log("...deleting container annotation because it has collapsed" + id); //     doc.delete(id); //   } // }); }
used when breaking a node to transfer annotations to the new property
used when breaking a node to transfer annotations to the new property