sort( fragments, grouped = false ) {

		fragments = Array.from( fragments );

		let ordered = [],
			unordered = [],
			sorted = [];

		// Group ordered and unordered elements
		fragments.forEach( fragment => {
			if( fragment.hasAttribute( 'data-fragment-index' ) ) {
				let index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );

				if( !ordered[index] ) {
					ordered[index] = [];
				}

				ordered[index].push( fragment );
			}
			else {
				unordered.push( [ fragment ] );
			}
		} );

		// Append fragments without explicit indices in their
		// DOM order
		ordered = ordered.concat( unordered );

		// Manually count the index up per group to ensure there
		// are no gaps
		let index = 0;

		// Push all fragments in their sorted order to an array,
		// this flattens the groups
		ordered.forEach( group => {
			group.forEach( fragment => {
				sorted.push( fragment );
				fragment.setAttribute( 'data-fragment-index', index );
			} );

			index ++;
		} );

		return grouped === true ? ordered : sorted;

	}
Return a sorted fragments list, ordered by an increasing
"data-fragment-index" attribute.

Fragments will be revealed in the order that they are returned by
this function, so you can use the index attributes to control the
order of fragment appearance.

To maintain a sensible default fragment order, fragments are presumed
to be passed in document order. This function adds a "fragment-index"
attribute to each node if such an attribute is not already present,
and sets that attribute to an integer value which is the position of
the fragment within the fragments list.

@param {object[]|*} fragments
@param {boolean} grouped If true the returned array will contain
nested arrays for all fragments with the same index
@return {object[]} sorted Sorted array of fragments