@@ -14,7 +14,9 @@ import {
1414 SchedulerInterface ,
1515 ElementSchedulerInterface ,
1616 FrameInterface ,
17- QueueInterface
17+ QueueInterface ,
18+ MetaInterface ,
19+ SpanielClientRectInterface
1820} from './interfaces' ;
1921import W from './window-proxy' ;
2022
@@ -29,45 +31,85 @@ const TOKEN_SEED = 'xxxx'.replace(/[xy]/g, function(c) {
2931} ) ;
3032let tokenCounter = 0 ;
3133
32- function generateRandomToken ( ) {
33- return Math . floor ( Math . random ( ) * ( 9999999 - 0o0 ) ) . toString ( 16 ) ;
34- }
35-
3634export class Frame implements FrameInterface {
3735 constructor (
3836 public timestamp : number ,
3937 public scrollTop : number ,
4038 public scrollLeft : number ,
4139 public width : number ,
42- public height : number
40+ public height : number ,
41+ public x : number ,
42+ public y : number ,
43+ public top : number ,
44+ public left : number
4345 ) { }
44- static generate ( ) : Frame {
46+ static generate ( root : Element | Window = window ) : Frame {
47+ const rootMeta = this . revalidateRootMeta ( root ) ;
4548 return new Frame (
4649 Date . now ( ) ,
47- W . meta . scrollTop ,
48- W . meta . scrollLeft ,
49- W . meta . width ,
50- W . meta . height
50+ rootMeta . scrollTop ,
51+ rootMeta . scrollLeft ,
52+ rootMeta . width ,
53+ rootMeta . height ,
54+ rootMeta . x ,
55+ rootMeta . y ,
56+ rootMeta . top ,
57+ rootMeta . left
5158 ) ;
5259 }
60+ static revalidateRootMeta ( root : any = window ) : MetaInterface {
61+ let _rootMeta : MetaInterface = {
62+ width : 0 ,
63+ height : 0 ,
64+ scrollTop : 0 ,
65+ scrollLeft : 0 ,
66+ x : 0 ,
67+ y : 0 ,
68+ top : 0 ,
69+ left : 0
70+ } ;
71+
72+ if ( root === window ) {
73+ _rootMeta . scrollTop = W . getScrollTop ( ) ;
74+ _rootMeta . scrollLeft = W . getScrollLeft ( ) ;
75+ _rootMeta . width = W . getWidth ( ) ;
76+ _rootMeta . height = W . getHeight ( ) ;
77+ } else if ( root ) {
78+ let _clientRect = getBoundingClientRect ( root ) ;
79+ _rootMeta . scrollTop = root . scrollTop ;
80+ _rootMeta . scrollLeft = root . scrollLeft ;
81+ _rootMeta . width = _clientRect . width ;
82+ _rootMeta . height = _clientRect . height ;
83+ _rootMeta . x = _clientRect . x ;
84+ _rootMeta . y = _clientRect . y ;
85+ _rootMeta . top = _clientRect . top ;
86+ _rootMeta . left = _clientRect . left ;
87+ }
88+
89+ return _rootMeta ;
90+ }
5391}
5492
5593export function generateToken ( ) {
5694 return tokenCounter ++ + TOKEN_SEED ;
5795}
5896
5997export abstract class BaseScheduler {
98+ protected root : Element | Window ;
6099 protected engine : EngineInterface ;
61100 protected queue : QueueInterface ;
62101 protected isTicking : Boolean = false ;
63102 protected toRemove : Array < string | Element | Function > = [ ] ;
103+ protected id ?: string ;
64104
65- constructor ( customEngine ?: EngineInterface ) {
105+ constructor ( customEngine ?: EngineInterface , root : Element | Window = window ) {
66106 if ( customEngine ) {
67107 this . engine = customEngine ;
68108 } else {
69109 this . engine = getGlobalEngine ( ) ;
70110 }
111+
112+ this . root = root ;
71113 }
72114 protected abstract applyQueue ( frame : Frame ) : void ;
73115
@@ -81,8 +123,7 @@ export abstract class BaseScheduler {
81123 }
82124 this . toRemove = [ ] ;
83125 }
84-
85- this . applyQueue ( Frame . generate ( ) ) ;
126+ this . applyQueue ( Frame . generate ( this . root ) ) ;
86127 this . engine . scheduleRead ( this . tick . bind ( this ) ) ;
87128 }
88129 }
@@ -97,7 +138,7 @@ export abstract class BaseScheduler {
97138 let frame : Frame = null ;
98139 this . engine . scheduleRead ( ( ) => {
99140 clientRect = getBoundingClientRect ( el ) ;
100- frame = Frame . generate ( ) ;
141+ frame = Frame . generate ( this . root ) ;
101142 } ) ;
102143 this . engine . scheduleWork ( ( ) => {
103144 callback ( clientRect , frame ) ;
@@ -108,14 +149,20 @@ export abstract class BaseScheduler {
108149 }
109150 unwatchAll ( ) {
110151 this . queue . clear ( ) ;
111- W . __destroy__ ( ) ;
112152 }
113153 startTicking ( ) {
114154 if ( ! this . isTicking ) {
115155 this . isTicking = true ;
116156 this . engine . scheduleRead ( this . tick . bind ( this ) ) ;
117157 }
118158 }
159+ forceStateValidation ( ) {
160+ ++ W . version ;
161+ W . meta . height = W . getHeight ( ) ;
162+ W . meta . width = W . getWidth ( ) ;
163+ W . meta . scrollLeft = W . getScrollLeft ( ) ;
164+ W . meta . scrollTop = W . getScrollTop ( ) ;
165+ }
119166}
120167
121168export class Scheduler extends BaseScheduler implements SchedulerInterface {
@@ -140,7 +187,7 @@ export class Scheduler extends BaseScheduler implements SchedulerInterface {
140187export class PredicatedScheduler extends Scheduler implements SchedulerInterface {
141188 predicate : ( frame : Frame ) => Boolean ;
142189 constructor ( predicate : ( frame : Frame ) => Boolean ) {
143- super ( null ) ;
190+ super ( null , window ) ;
144191 this . predicate = predicate ;
145192 }
146193 applyQueue ( frame : Frame ) {
@@ -152,13 +199,15 @@ export class PredicatedScheduler extends Scheduler implements SchedulerInterface
152199
153200export class ElementScheduler extends BaseScheduler implements ElementSchedulerInterface {
154201 protected queue : DOMQueue ;
155- protected isDirty : boolean = false ;
156- protected id : string = '' ;
202+ protected lastVersion : number = W . version ;
157203
158- constructor ( customEngine ?: EngineInterface ) {
159- super ( customEngine ) ;
204+ constructor ( customEngine ?: EngineInterface , root ?: Element | Window ) {
205+ super ( customEngine , root ) ;
160206 this . queue = new DOMQueue ( ) ;
161- this . id = generateRandomToken ( ) ;
207+ }
208+
209+ get isDirty ( ) : boolean {
210+ return W . version !== this . lastVersion ;
162211 }
163212
164213 applyQueue ( frame : Frame ) {
@@ -172,11 +221,10 @@ export class ElementScheduler extends BaseScheduler implements ElementSchedulerI
172221 callback ( frame , id , clientRect ) ;
173222 }
174223
175- this . isDirty = false ;
224+ this . lastVersion = W . version ;
176225 }
177226
178227 watch ( el : Element , callback : ( frame : FrameInterface , id : string , clientRect ?: ClientRect | null ) => void , id ?: string ) : string {
179- this . initWindowIsDirtyListeners ( ) ;
180228 this . startTicking ( ) ;
181229 id = id || generateToken ( ) ;
182230 let clientRect = null ;
@@ -189,14 +237,6 @@ export class ElementScheduler extends BaseScheduler implements ElementSchedulerI
189237 } ) ;
190238 return id ;
191239 }
192-
193- initWindowIsDirtyListeners ( ) {
194- W . onWindowIsDirtyListeners . push ( { fn : this . windowIsDirtyHandler , scope : this , id : this . id } ) ;
195- }
196-
197- windowIsDirtyHandler ( ) {
198- this . isDirty = true ;
199- }
200240}
201241
202242let globalScheduler : Scheduler = null ;
0 commit comments