docs: function ( range, frag ) {
      // Check if it's all inline content
      var allInline = true,
          children = frag.childNodes,
          l = children.length;
      while ( l-- ) {
          if ( !isInline( children[l] ) ) {
              allInline = false;
              break;
          }
      }
  
      // Delete any selected content
      if ( !range.collapsed ) {
          deleteContentsOfRange( range );
      }
  
      // Move range down into text nodes
      moveRangeBoundariesDownTree( range );
  
      if ( allInline ) {
          // If inline, just insert at the current position.
          insertNodeInRange( range, frag );
          range.collapse( false );
      } else {
          // Otherwise...
          // 1. Split up to blockquote (if a parent) or body
          var splitPoint = range.startContainer,
              nodeAfterSplit = split( splitPoint, range.startOffset,
                  getNearest( splitPoint.parentNode, 'BLOCKQUOTE' ) ||
                  splitPoint.ownerDocument.body ),
              nodeBeforeSplit = nodeAfterSplit.previousSibling,
              startContainer = nodeBeforeSplit,
              startOffset = startContainer.childNodes.length,
              endContainer = nodeAfterSplit,
              endOffset = 0,
              parent = nodeAfterSplit.parentNode,
              child, node, prev, next, startAnchor;
  
          // 2. Move down into edge either side of split and insert any inline
          // nodes at the beginning/end of the fragment
          while ( ( child = startContainer.lastChild ) &&
                  child.nodeType === ELEMENT_NODE ) {
              if ( child.nodeName === 'BR' ) {
                  startOffset -= 1;
                  break;
              }
              startContainer = child;
              startOffset = startContainer.childNodes.length;
          }
          while ( ( child = endContainer.firstChild ) &&
                  child.nodeType === ELEMENT_NODE &&
                  child.nodeName !== 'BR' ) {
              endContainer = child;
          }
          startAnchor = startContainer.childNodes[ startOffset ] || null;
          while ( ( child = frag.firstChild ) && isInline( child ) ) {
              startContainer.insertBefore( child, startAnchor );
          }
          while ( ( child = frag.lastChild ) && isInline( child ) ) {
              endContainer.insertBefore( child, endContainer.firstChild );
              endOffset += 1;
          }
  
          // 3. Fix cursor then insert block(s) in the fragment
          node = frag;
          while ( node = getNextBlock( node ) ) {
              fixCursor( node );
          }
          parent.insertBefore( frag, nodeAfterSplit );
  
          // 4. Remove empty nodes created either side of split, then
          // merge containers at the edges.
          next = nodeBeforeSplit.nextSibling;
          node = getPreviousBlock( next );
          if ( !/\S/.test( node.textContent ) ) {
              do {
                  parent = node.parentNode;
                  parent.removeChild( node );
                  node = parent;
              } while ( parent && !parent.lastChild &&
                  parent.nodeName !== 'BODY' );
          }
          if ( !nodeBeforeSplit.parentNode ) {
              nodeBeforeSplit = next.previousSibling;
          }
          if ( !startContainer.parentNode ) {
              startContainer = nodeBeforeSplit || next.parentNode;
              startOffset = nodeBeforeSplit ?
                  nodeBeforeSplit.childNodes.length : 0;
          }
          // Merge inserted containers with edges of split
          if ( isContainer( next ) ) {
              mergeContainers( next );
          }
  
          prev = nodeAfterSplit.previousSibling;
          node = isBlock( nodeAfterSplit ) ?
              nodeAfterSplit : getNextBlock( nodeAfterSplit );
          if ( !/\S/.test( node.textContent ) ) {
              do {
                  parent = node.parentNode;
                  parent.removeChild( node );
                  node = parent;
              } while ( parent && !parent.lastChild &&
                  parent.nodeName !== 'BODY' );
          }
          if ( !nodeAfterSplit.parentNode ) {
              nodeAfterSplit = prev.nextSibling;
          }
          if ( !endOffset ) {
              endContainer = prev;
              endOffset = prev.childNodes.length;
          }
          // Merge inserted containers with edges of split
          if ( nodeAfterSplit && isContainer( nodeAfterSplit ) ) {
              mergeContainers( nodeAfterSplit );
          }
  
          range.setStart( startContainer, startOffset );
          range.setEnd( endContainer, endOffset );
          moveRangeBoundariesDownTree( range );
      }
  }