22*
33* ModelView.js
44* @version : 5.0.0
5- * @built on 2022-03-28 20:00:42
5+ * @built on 2022-03-30 11:03:44
66*
77* A simple, light-weight, versatile and fast isomorphic MVVM JavaScript framework (Browser and Server)
88* https://github.com/foo123/modelview.js
1111*
1212* ModelView.js
1313* @version : 5.0.0
14- * @built on 2022-03-28 20:00:42
14+ * @built on 2022-03-30 11:03:44
1515*
1616* A simple, light-weight, versatile and fast isomorphic MVVM JavaScript framework (Browser and Server)
1717* https://github.com/foo123/modelview.js
@@ -196,13 +196,53 @@ function is_array_index(n)
196196 }
197197 return false
198198}
199+ function nextNode ( node , m , NEXT )
200+ {
201+ for ( var i = 0 ; node && ( i < m ) ; ++ i )
202+ node = node [ NEXT ] ;
203+ return node ;
204+ }
205+ function moveNodes ( dom , node , m , edge )
206+ {
207+ var i , next ;
208+ if ( edge )
209+ {
210+ for ( next = node [ NEXT ] , i = 0 ; node && ( i < m ) ; ++ i )
211+ {
212+ dom . insertBefore ( node , edge ) ;
213+ node = next ; next = node ? node [ NEXT ] : null ;
214+ }
215+ }
216+ else
217+ {
218+ for ( next = node [ NEXT ] , i = 0 ; node && ( i < m ) ; ++ i )
219+ {
220+ dom . appendChild ( node ) ;
221+ node = next ; next = node ? node [ NEXT ] : null ;
222+ }
223+ }
224+ }
225+ function swap ( array , i1 , i2 )
226+ {
227+ var t = array [ i1 ] ;
228+ array [ i1 ] = array [ i2 ] ;
229+ array [ i2 ] = t ;
230+ return array ;
231+ }
232+ function swapNodes ( dom , node1 , node2 , m )
233+ {
234+ var last = nextNode ( node2 , m , NEXT ) ;
235+ moveNodes ( dom , node2 , m , node1 ) ;
236+ moveNodes ( dom , node1 , m , last ) ;
237+ }
199238function permute ( list , perm )
200239{
201240 for ( var copy = slice . call ( list ) , i = 0 , l = list . length ; i < l ; ++ i ) list [ i ] = copy [ perm [ i ] ] ;
202241 return list ;
203242}
204243function permuteNodes ( dom , start , perm , m )
205244{
245+ // not necessarily min DOM ops
206246 var i , j , len = perm . length , tlen = len * m ,
207247 frag = Fragment ( ) ,
208248 edge = dom . childNodes [ start + tlen ] ,
@@ -213,6 +253,92 @@ function permuteNodes(dom, start, perm, m)
213253 frag . appendChild ( nodes [ perm [ i ] * m + j ] ) ;
214254 if ( edge ) dom . insertBefore ( frag , edge ) ;
215255 else dom . appendChild ( frag ) ;
256+ /*
257+ // permute DOM tree using minimum DOM operations
258+ var rNodes = dom.childNodes, cNodes,
259+ rnode, rnodef, rnode2, left,
260+ i1, i2, i, j, x, z, pos,
261+ places, lis, needsReorder, loop = true;
262+
263+ i1 = 0; i2 = perm.length-1;
264+ rnode = rNodes[start+m*i1];
265+ rnodef = rNodes[start+m*i2];
266+ x = nextNode(rnodef, m, NEXT);
267+
268+ while (loop)
269+ {
270+ loop = false;
271+ // start
272+ while ((i1 <= i2) && (i1 === perm[i1]))
273+ {
274+ ++i1;
275+ if (i1 > i2) {loop = false; break;}
276+ rnode = nextNode(rnode, m, NEXT);
277+ }
278+ // end
279+ while ((i1 <= i2) && (i2 === perm[i2]))
280+ {
281+ x = rnodef;
282+ --i2;
283+ if (i1 > i2) {loop = false; break;}
284+ rnodef = nextNode(rnodef, m, PREV);
285+ }
286+ // swap
287+ while ((i1 <= i2) && (i1 === perm[i2]) && (i2 === perm[i1]))
288+ {
289+ loop = true;
290+ rnode2 = nextNode(rnodef, m, PREV);
291+ moveNodes(dom, rnodef, m, rnode);
292+ rnodef = rnode2;
293+ rnode2 = nextNode(rnode, m, NEXT);
294+ moveNodes(dom, rnode, m, x);
295+ x = rnode;
296+ rnode = rnode2;
297+ ++i1; --i2;
298+ if (i1 > i2) {loop = false; break;}
299+ }
300+ }
301+
302+ if (i1 <= i2)
303+ {
304+ left = i2-i1+1;
305+ places = new A32I(left);
306+ needsReorder = false;
307+ pos = 0;
308+ for (i=i1; i<=i2; ++i)
309+ {
310+ j = perm[i];
311+ places[j - i1] = i + 1;
312+ if (pos > j) needsReorder = true;
313+ else pos = j;
314+ }
315+ if (needsReorder)
316+ {
317+ // matched entries are not in increasing order
318+ // compute longest increasing subsequence
319+ lis = longest_incr_subseq(places); // O(n log n) !!
320+ j = lis.length - 1;
321+ cNodes = slice.call(rNodes, start+m*i1, start+m*i2+1); // store as immutable
322+ for (i=left-1; i>=0; --i)
323+ {
324+ pos = places[i];
325+ if ((0 > j) || (i !== lis[j]))
326+ {
327+ // move existing entry in correct place
328+ z = cNodes[m*(pos-1-i1)];
329+ moveNodes(dom, z, m, x);
330+ x = z;
331+ }
332+ else
333+ {
334+ // new place for entry
335+ x = cNodes[m*(pos-1-i1)];
336+ --j;
337+ }
338+ }
339+ }
340+ }
341+ */
216342}
217343function flatten ( array )
218344{
@@ -2366,6 +2492,9 @@ function morphCollection(view, r, v, start, end, end2, startv, count, forced)
23662492 count = 0 ;
23672493 return count ; // break from diff loop completely, this should be only diff
23682494 break ;
2495+ case 'swap' :
2496+ swapNodes ( r , rNodes [ start + d . from * m ] , rNodes [ start + d . to * m ] , m ) ;
2497+ break ;
23692498 case 'add' :
23702499 len = ( d . to - d . from + 1 ) * m ;
23712500 items = collection . mapped ( d . from , d . to ) ;
@@ -2377,14 +2506,6 @@ function morphCollection(view, r, v, start, end, end2, startv, count, forced)
23772506 delNodes ( view , r , start + d . from * m , len ) ;
23782507 if ( 0 < count ) count -= len ;
23792508 break ;
2380- case 'swap' :
2381- i = slice . call ( rNodes , start + d . from * m , start + d . from * m + m ) ;
2382- j = slice . call ( rNodes , start + d . to * m , start + d . to * m + m ) ;
2383- k = j [ j . length - 1 ] [ NEXT ] ;
2384- for ( l = 0 ; l < m ; ++ l ) r . replaceChild ( j [ l ] , i [ l ] ) ;
2385- if ( k ) for ( l = 0 ; l < m ; ++ l ) r . insertBefore ( i [ l ] , k ) ;
2386- else for ( l = 0 ; l < m ; ++ l ) r . appendChild ( i [ l ] ) ;
2387- break ;
23882509 case 'change' :
23892510 len = ( d . to - d . from + 1 ) * m ;
23902511 z = new Array ( len ) ;
@@ -3408,15 +3529,8 @@ function morphCollectionSimple(view, list, key, collection, isDirty, model, only
34083529 permute ( list . map , d . from ) ;
34093530 return ;
34103531 case 'swap' :
3411- x = list . map [ d . from ] ;
3412- list . map [ d . from ] = list . map [ d . to ] ;
3413- list . map [ d . to ] = x ;
3414- i = slice . call ( parentNode . childNodes , startIndex + 1 + d . from * m , startIndex + 1 + d . from * m + m ) ;
3415- j = slice . call ( parentNode . childNodes , startIndex + 1 + d . to * m , startIndex + 1 + d . to * m + m ) ;
3416- k = j [ j . length - 1 ] [ NEXT ] ;
3417- for ( l = 0 ; l < m ; ++ l ) parentNode . replaceChild ( j [ l ] , i [ l ] ) ;
3418- if ( k ) for ( l = 0 ; l < m ; ++ l ) parentNode . insertBefore ( i [ l ] , k ) ;
3419- else for ( l = 0 ; l < m ; ++ l ) parentNode . appendChild ( i [ l ] ) ;
3532+ swapNodes ( parentNode , parentNode . childNodes [ startIndex + 1 + d . from * m ] , parentNode . childNodes [ startIndex + 1 + d . to * m ] , m ) ;
3533+ swap ( list . map , d . from , d . to ) ;
34203534 break ;
34213535 case 'del' :
34223536 list . map . splice ( d . from , d . to - d . from + 1 ) ;
@@ -8001,6 +8115,7 @@ view.components( Object components );
80018115 out = c . out . call ( component , data , children || [ ] , htmlNode ) ;
80028116 out . component = component ;
80038117 out . changed = changed ;
8118+ out . simple = false ; // components are not simple nodes
80048119 return out ;
80058120 }
80068121 }
0 commit comments