UNPKG

ractive

Version:

Next-generation DOM manipulation

87 lines (63 loc) 2.26 kB
import runloop from 'global/runloop'; import circular from 'circular'; var Fragment; circular.push( function () { Fragment = circular.Fragment; }); export default function Section$splice ( spliceSummary ) { var section = this, balance, start, insertStart, insertEnd, spliceArgs; balance = spliceSummary.balance; if ( !balance ) { // The array length hasn't changed - we don't need to add or remove anything return; } // Register with the runloop, so we can (un)render with the // next batch of DOM changes runloop.addView( section ); start = spliceSummary.rangeStart; section.length += balance; // If more items were removed from the array than added, we tear down // the excess fragments and remove them... if ( balance < 0 ) { section.fragmentsToUnrender = section.fragments.splice( start, -balance ); section.fragmentsToUnrender.forEach( unbind ); // Reassign fragments after the ones we've just removed rebindFragments( section, start, section.length, balance ); // Nothing more to do return; } // ...otherwise we need to add some things to the DOM. insertStart = start + spliceSummary.removed; insertEnd = start + spliceSummary.added; // Make room for the new fragments by doing a splice that simulates // what happened to the data array spliceArgs = [ insertStart, 0 ]; spliceArgs.length += balance; section.fragments.splice.apply( section.fragments, spliceArgs ); // Rebind existing fragments at the end of the array rebindFragments( section, insertEnd, section.length, balance ); // Schedule new fragments to be created section.fragmentsToCreate = range( insertStart, insertEnd ); } function unbind ( fragment ) { fragment.unbind(); } function range ( start, end ) { var array = [], i; for ( i = start; i < end; i += 1 ) { array.push( i ); } return array; } function rebindFragments ( section, start, end, by ) { var i, fragment, indexRef, oldKeypath, newKeypath; indexRef = section.template.i; for ( i = start; i < end; i += 1 ) { fragment = section.fragments[i]; oldKeypath = section.keypath + '.' + ( i - by ); newKeypath = section.keypath + '.' + i; // change the fragment index fragment.index = i; fragment.rebind( indexRef, i, oldKeypath, newKeypath ); } }