tinymce.full.js
function (rng) {
      var bookmark = {};

      var setupEndPoint = function (start) {
        var offsetNode, container, offset;

        container = rng[start ? 'startContainer' : 'endContainer'];
        offset = rng[start ? 'startOffset' : 'endOffset'];

        if (container.nodeType === 1) {
          offsetNode = DOM.create('span', { 'data-mce-type': 'bookmark' });

          if (container.hasChildNodes()) {
            offset = Math.min(offset, container.childNodes.length - 1);

            if (start) {
              container.insertBefore(offsetNode, container.childNodes[offset]);
            } else {
              DOM.insertAfter(offsetNode, container.childNodes[offset]);
            }
          } else {
            container.appendChild(offsetNode);
          }

          container = offsetNode;
          offset = 0;
        }

        bookmark[start ? 'startContainer' : 'endContainer'] = container;
        bookmark[start ? 'startOffset' : 'endOffset'] = offset;
      };

      setupEndPoint(true);

      if (!rng.collapsed) {
        setupEndPoint();
      }

      return bookmark;
    }
function (rng) {
      var bookmark = {};

      var setupEndPoint = function (start) {
        var offsetNode, container, offset;

        container = rng[start ? 'startContainer' : 'endContainer'];
        offset = rng[start ? 'startOffset' : 'endOffset'];

        if (container.nodeType === 1) {
          offsetNode = DOM.create('span', { 'data-mce-type': 'bookmark' });

          if (container.hasChildNodes()) {
            offset = Math.min(offset, container.childNodes.length - 1);

            if (start) {
              container.insertBefore(offsetNode, container.childNodes[offset]);
            } else {
              DOM.insertAfter(offsetNode, container.childNodes[offset]);
            }
          } else {
            container.appendChild(offsetNode);
          }

          container = offsetNode;
          offset = 0;
        }

        bookmark[start ? 'startContainer' : 'endContainer'] = container;
        bookmark[start ? 'startOffset' : 'endOffset'] = offset;
      };

      setupEndPoint(true);

      if (!rng.collapsed) {
        setupEndPoint();
      }

      return bookmark;
    }
function ( rng ) { var bookmark = { } ; var setupEndPoint = function ( start ) { var offsetNode , container , offset ; container = rng [ start ? 'startContainer' : 'endContainer' ] ; offset = rng [ start ? 'startOffset' : 'endOffset' ] ; if ( container . nodeType === 1 ) { offsetNode = DOM . create ( 'span' , { 'data-mce-type' : 'bookmark' } ) ; if ( container . hasChildNodes ( ) ) { offset = Math . min ( offset , container . childNodes . length - 1 ) ; if ( start ) { container . insertBefore ( offsetNode , container . childNodes [ offset ] ) ; } else { DOM . insertAfter ( offsetNode , container . childNodes [ offset ] ) ; } } else { container . appendChild ( offsetNode ) ; } container = offsetNode ; offset = 0 ; } bookmark [ start ? 'startContainer' : 'endContainer' ] = container ; bookmark [ start ? 'startOffset' : 'endOffset' ] = offset ; } ; setupEndPoint ( true ) ; if ( ! rng . collapsed ) { setupEndPoint ( ) ; } return bookmark ; }
Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
added to them since they can be restored after a dom operation.

So this: <p><b>|</b><b>|</b></p>
becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>

@param  {DOMRange} rng DOM Range to get bookmark on.
@return {Object} Bookmark object.
Returns a range bookmark . This will convert indexed bookmarks into temporary span elements with index 0 so that they can be restored properly after the DOM has been modified . Text bookmarks will not have spans added to them since they can be restored after a dom operation .