1+ import { inject , Container } from 'aurelia-dependency-injection' ;
12import { DOM } from 'aurelia-pal' ;
23import { View } from 'aurelia-templating' ;
34import { insertBeforeNode } from './utilities' ;
5+ import { DomHelper } from './dom-helper' ;
46
57interface TemplateStrategy {
68 getScrollContainer ( element : Element ) : Element ;
@@ -11,17 +13,25 @@ interface TemplateStrategy {
1113 removeBufferElements ( element : Element , topBuffer : Element , bottomBuffer : Element ) : void ;
1214 getFirstElement ( topBuffer : Element ) : Element ;
1315 getLastView ( bottomBuffer : Element ) : Element ;
16+ getTopBufferDistance ( topBuffer : Element ) : number ;
1417}
1518
19+ @inject ( Container )
1620export class TemplateStrategyLocator {
21+
22+ constructor ( container : Container ) {
23+ this . container = container ;
24+ }
25+
1726 getStrategy ( element : Element ) : TemplateStrategy {
1827 if ( element . parentNode && element . parentNode . localName === 'tbody' ) {
19- return new TableStrategy ( ) ;
28+ return this . container . get ( TableStrategy ) ;
2029 }
21- return new DefaultTemplateStrategy ( ) ;
30+ return this . container . get ( DefaultTemplateStrategy ) ;
2231 }
2332}
2433
34+ @inject ( DomHelper )
2535export class TableStrategy {
2636 tableCssReset = '\
2737 display: block;\
@@ -36,52 +46,76 @@ export class TableStrategy {
3646 -webkit-border-horizontal-spacing: 0;\
3747 -webkit-border-vertical-spacing: 0;' ;
3848
49+ constructor ( domHelper ) {
50+ this . domHelper = domHelper ;
51+ }
52+
3953 getScrollContainer ( element : Element ) : Element {
4054 return element . parentNode ;
4155 }
4256
4357 moveViewFirst ( view : View , topBuffer : Element ) : void {
44- insertBeforeNode ( view , DOM . nextElementSibling ( topBuffer . parentNode ) ) ;
58+ const tbody = this . _getTbodyElement ( topBuffer . nextSibling ) ;
59+ const tr = tbody . firstChild ;
60+ const firstElement = DOM . nextElementSibling ( tr ) ;
61+ insertBeforeNode ( view , firstElement ) ;
4562 }
4663
4764 moveViewLast ( view : View , bottomBuffer : Element ) : void {
48- let previousSibling = bottomBuffer . parentNode . previousSibling ;
49- let referenceNode = previousSibling . nodeType === 8 && previousSibling . data === 'anchor' ? previousSibling : bottomBuffer . parentNode ;
65+ const lastElement = this . getLastElement ( bottomBuffer ) . nextSibling ;
66+ const referenceNode = lastElement . nodeType === 8 && lastElement . data === 'anchor' ? lastElement : lastElement ;
5067 insertBeforeNode ( view , referenceNode ) ;
5168 }
5269
5370 createTopBufferElement ( element : Element ) : Element {
54- let tr = DOM . createElement ( 'tr' ) ;
55- tr . setAttribute ( 'style' , this . tableCssReset ) ;
56- let buffer = DOM . createElement ( 'td' ) ;
57- buffer . setAttribute ( 'style' , this . tableCssReset ) ;
58- tr . appendChild ( buffer ) ;
59- element . parentNode . insertBefore ( tr , element ) ;
71+ const elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
72+ const buffer = DOM . createElement ( elementName ) ;
73+ const tableElement = element . parentNode . parentNode ;
74+ tableElement . parentNode . insertBefore ( buffer , tableElement ) ;
75+ buffer . innerHTML = ' ' ;
6076 return buffer ;
6177 }
6278
6379 createBottomBufferElement ( element : Element ) : Element {
64- let tr = DOM . createElement ( 'tr' ) ;
65- tr . setAttribute ( 'style' , this . tableCssReset ) ;
66- let buffer = DOM . createElement ( 'td' ) ;
67- buffer . setAttribute ( 'style' , this . tableCssReset ) ;
68- tr . appendChild ( buffer ) ;
69- element . parentNode . insertBefore ( tr , element . nextSibling ) ;
80+ const elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
81+ const buffer = DOM . createElement ( elementName ) ;
82+ const tableElement = element . parentNode . parentNode ;
83+ tableElement . parentNode . insertBefore ( buffer , tableElement . nextSibling ) ;
7084 return buffer ;
7185 }
7286
7387 removeBufferElements ( element : Element , topBuffer : Element , bottomBuffer : Element ) : void {
74- element . parentNode . removeChild ( topBuffer . parentNode ) ;
75- element . parentNode . removeChild ( bottomBuffer . parentNode ) ;
88+ topBuffer . parentNode . removeChild ( topBuffer ) ;
89+ bottomBuffer . parentNode . removeChild ( bottomBuffer ) ;
7690 }
7791
7892 getFirstElement ( topBuffer : Element ) : Element {
79- let tr = topBuffer . parentNode ;
93+ const tbody = this . _getTbodyElement ( DOM . nextElementSibling ( topBuffer ) ) ;
94+ const tr = tbody . firstChild ;
8095 return DOM . nextElementSibling ( tr ) ;
8196 }
8297
8398 getLastElement ( bottomBuffer : Element ) : Element {
84- return bottomBuffer . parentNode . previousElementSibling ;
99+ const tbody = this . _getTbodyElement ( bottomBuffer . previousSibling ) ;
100+ const trs = tbody . children ;
101+ return trs [ trs . length - 1 ] ;
102+ }
103+
104+ getTopBufferDistance ( topBuffer : Element ) : number {
105+ const tbody = this . _getTbodyElement ( topBuffer . nextSibling ) ;
106+ return this . domHelper . getElementDistanceToTopOfDocument ( tbody ) - this . domHelper . getElementDistanceToTopOfDocument ( topBuffer ) ;
107+ }
108+
109+ _getTbodyElement ( tableElement : Element ) : Element {
110+ let tbodyElement ;
111+ const children = tableElement . children ;
112+ for ( let i = 0 , ii = children . length ; i < ii ; ++ i ) {
113+ if ( children [ i ] . localName === 'tbody' ) {
114+ tbodyElement = children [ i ] ;
115+ break ;
116+ }
117+ }
118+ return tbodyElement ;
85119 }
86120}
87121
@@ -95,21 +129,21 @@ export class DefaultTemplateStrategy {
95129 }
96130
97131 moveViewLast ( view : View , bottomBuffer : Element ) : void {
98- let previousSibling = bottomBuffer . previousSibling ;
99- let referenceNode = previousSibling . nodeType === 8 && previousSibling . data === 'anchor' ? previousSibling : bottomBuffer ;
132+ const previousSibling = bottomBuffer . previousSibling ;
133+ const referenceNode = previousSibling . nodeType === 8 && previousSibling . data === 'anchor' ? previousSibling : bottomBuffer ;
100134 insertBeforeNode ( view , referenceNode ) ;
101135 }
102136
103137 createTopBufferElement ( element : Element ) : Element {
104- let elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
105- let buffer = DOM . createElement ( elementName ) ;
138+ const elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
139+ const buffer = DOM . createElement ( elementName ) ;
106140 element . parentNode . insertBefore ( buffer , element ) ;
107141 return buffer ;
108142 }
109143
110144 createBottomBufferElement ( element : Element ) : Element {
111- let elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
112- let buffer = DOM . createElement ( elementName ) ;
145+ const elementName = element . parentNode . localName === 'ul' ? 'li' : 'div' ;
146+ const buffer = DOM . createElement ( elementName ) ;
113147 element . parentNode . insertBefore ( buffer , element . nextSibling ) ;
114148 return buffer ;
115149 }
@@ -126,4 +160,8 @@ export class DefaultTemplateStrategy {
126160 getLastElement ( bottomBuffer : Element ) : Element {
127161 return bottomBuffer . previousElementSibling ;
128162 }
163+
164+ getTopBufferDistance ( topBuffer : Element ) : number {
165+ return 0 ;
166+ }
129167}
0 commit comments