@@ -131,7 +131,49 @@ suite('Scrolling into view', function () {
131131 const block = workspace . getBlocksByType (
132132 'controls_if' ,
133133 ) [ 0 ] as Blockly . BlockSvg ;
134- return [ block . getRelativeToSurfaceXY ( ) , getRelativeXY ( block . getSvgRoot ( ) ) ] ;
134+
135+ const XY_REGEX = / t r a n s l a t e \( \s * ( [ - + \d . e ] + ) ( [ , ] \s * ( [ - + \d . e ] + ) \s * ) ? / ;
136+ const XY_STYLE_REGEX =
137+ / t r a n s f o r m : \s * t r a n s l a t e (?: 3 d ) ? \( \s * ( [ - + \d . e ] + ) \s * p x ( [ , ] \s * ( [ - + \d . e ] + ) \s * p x ) ? / ;
138+ const element = block . getSvgRoot ( ) ;
139+ class Coordinate {
140+ constructor ( public x : number , public y : number ) { }
141+ } ;
142+ const xy = new Coordinate ( 0 , 0 ) ;
143+ // First, check for x and y attributes.
144+ // Checking for the existence of x/y properties is faster than getAttribute.
145+ // However, x/y contains an SVGAnimatedLength object, so rely on getAttribute
146+ // to get the number.
147+ const x = ( element as any ) . x && element . getAttribute ( 'x' ) ;
148+ const y = ( element as any ) . y && element . getAttribute ( 'y' ) ;
149+ if ( x ) {
150+ xy . x = parseInt ( x ) ;
151+ }
152+ if ( y ) {
153+ xy . y = parseInt ( y ) ;
154+ }
155+ // Second, check for transform="translate(...)" attribute.
156+ const transform = element . getAttribute ( 'transform' ) ;
157+ const r = transform && transform . match ( XY_REGEX ) ;
158+ if ( r ) {
159+ xy . x += Number ( r [ 1 ] ) ;
160+ if ( r [ 3 ] ) {
161+ xy . y += Number ( r [ 3 ] ) ;
162+ }
163+ }
164+
165+ // Then check for style = transform: translate(...) or translate3d(...)
166+ const style = element . getAttribute ( 'style' ) ;
167+ if ( style && style . includes ( 'translate' ) ) {
168+ const styleComponents = style . match ( XY_STYLE_REGEX ) ;
169+ if ( styleComponents ) {
170+ xy . x += Number ( styleComponents [ 1 ] ) ;
171+ if ( styleComponents [ 3 ] ) {
172+ xy . y += Number ( styleComponents [ 3 ] ) ;
173+ }
174+ }
175+ }
176+ return [ block . getRelativeToSurfaceXY ( ) , xy ] ;
135177 } ) ;
136178 console . log ( "block position:" , blockPosition , "relative:" , blockRelative ) ;
137179 const [ blockParentBounds , blockParentId ] = await this . browser . execute ( ( ) => {
@@ -173,99 +215,3 @@ suite('Scrolling into view', function () {
173215 chai . assert . isTrue ( inViewport ) ;
174216 } ) ;
175217} ) ;
176-
177- const XY_REGEX = / t r a n s l a t e \( \s * ( [ - + \d . e ] + ) ( [ , ] \s * ( [ - + \d . e ] + ) \s * ) ? / ;
178- const XY_STYLE_REGEX =
179- / t r a n s f o r m : \s * t r a n s l a t e (?: 3 d ) ? \( \s * ( [ - + \d . e ] + ) \s * p x ( [ , ] \s * ( [ - + \d . e ] + ) \s * p x ) ? / ;
180-
181- function getRelativeXY ( element : Element ) : Coordinate {
182- const xy = new Coordinate ( 0 , 0 ) ;
183- // First, check for x and y attributes.
184- // Checking for the existence of x/y properties is faster than getAttribute.
185- // However, x/y contains an SVGAnimatedLength object, so rely on getAttribute
186- // to get the number.
187- const x = ( element as any ) . x && element . getAttribute ( 'x' ) ;
188- const y = ( element as any ) . y && element . getAttribute ( 'y' ) ;
189- if ( x ) {
190- xy . x = parseInt ( x ) ;
191- }
192- if ( y ) {
193- xy . y = parseInt ( y ) ;
194- }
195- // Second, check for transform="translate(...)" attribute.
196- const transform = element . getAttribute ( 'transform' ) ;
197- const r = transform && transform . match ( XY_REGEX ) ;
198- if ( r ) {
199- xy . x += Number ( r [ 1 ] ) ;
200- if ( r [ 3 ] ) {
201- xy . y += Number ( r [ 3 ] ) ;
202- }
203- }
204-
205- // Then check for style = transform: translate(...) or translate3d(...)
206- const style = element . getAttribute ( 'style' ) ;
207- if ( style && style . includes ( 'translate' ) ) {
208- const styleComponents = style . match ( XY_STYLE_REGEX ) ;
209- if ( styleComponents ) {
210- xy . x += Number ( styleComponents [ 1 ] ) ;
211- if ( styleComponents [ 3 ] ) {
212- xy . y += Number ( styleComponents [ 3 ] ) ;
213- }
214- }
215- }
216- return xy ;
217- }
218-
219- class Coordinate {
220- constructor (
221- public x : number ,
222- public y : number ,
223- ) { }
224-
225- clone ( ) : Coordinate {
226- return new Coordinate ( this . x , this . y ) ;
227- }
228-
229- scale ( s : number ) : Coordinate {
230- this . x *= s ;
231- this . y *= s ;
232- return this ;
233- }
234-
235- translate ( tx : number , ty : number ) : Coordinate {
236- this . x += tx ;
237- this . y += ty ;
238- return this ;
239- }
240-
241- static equals ( a ?: Coordinate | null , b ?: Coordinate | null ) : boolean {
242- if ( a === b ) {
243- return true ;
244- }
245- if ( ! a || ! b ) {
246- return false ;
247- }
248- return a . x === b . x && a . y === b . y ;
249- }
250-
251- static distance ( a : Coordinate , b : Coordinate ) : number {
252- const dx = a . x - b . x ;
253- const dy = a . y - b . y ;
254- return Math . sqrt ( dx * dx + dy * dy ) ;
255- }
256-
257- static magnitude ( a : Coordinate ) : number {
258- return Math . sqrt ( a . x * a . x + a . y * a . y ) ;
259- }
260-
261- static difference (
262- a : Coordinate | SVGPoint ,
263- b : Coordinate | SVGPoint ,
264- ) : Coordinate {
265- return new Coordinate ( a . x - b . x , a . y - b . y ) ;
266- }
267-
268- static sum ( a : Coordinate | SVGPoint , b : Coordinate | SVGPoint ) : Coordinate {
269- return new Coordinate ( a . x + b . x , a . y + b . y ) ;
270- }
271- }
0 commit comments