@@ -44,16 +44,18 @@ class SeekBar extends Slider {
4444// Avoid mutating the prototype's `children` array by creating a copy
4545options . children = [ ...options . children ] ;
4646
47- const shouldDisableSeekWhileScrubbingOnMobile = player . options_ . disableSeekWhileScrubbingOnMobile && ( IS_IOS || IS_ANDROID ) ;
47+ const shouldDisableSeekWhileScrubbing =
48+ ( player . options_ . disableSeekWhileScrubbingOnMobile && ( IS_IOS || IS_ANDROID ) ) ||
49+ ( player . options_ . disableSeekWhileScrubbingOnSTV ) ;
4850
4951// Add the TimeTooltip as a child if we are on desktop, or on mobile with `disableSeekWhileScrubbingOnMobile: true`
50- if ( ( ! IS_IOS && ! IS_ANDROID ) || shouldDisableSeekWhileScrubbingOnMobile ) {
52+ if ( ( ! IS_IOS && ! IS_ANDROID ) || shouldDisableSeekWhileScrubbing ) {
5153options . children . splice ( 1 , 0 , 'mouseTimeDisplay' ) ;
5254}
5355
5456super ( player , options ) ;
5557
56- this . shouldDisableSeekWhileScrubbingOnMobile_ = shouldDisableSeekWhileScrubbingOnMobile ;
58+ this . shouldDisableSeekWhileScrubbing_ = shouldDisableSeekWhileScrubbing ;
5759this . pendingSeekTime_ = null ;
5860
5961this . setEventHandlers_ ( ) ;
@@ -196,7 +198,7 @@ class SeekBar extends Slider {
196198
197199// update the progress bar time tooltip with the current time
198200if ( this . bar ) {
199- this . bar . update ( Dom . getBoundingClientRect ( this . el ( ) ) , this . getProgress ( ) ) ;
201+ this . bar . update ( Dom . getBoundingClientRect ( this . el ( ) ) , this . getProgress ( ) , event ) ;
200202}
201203} ) ;
202204
@@ -233,6 +235,26 @@ class SeekBar extends Slider {
233235this . player_ . currentTime ( ) ;
234236}
235237
238+ /**
239+ * Getter and setter for pendingSeekTime.
240+ * Ensures the value is clamped between 0 and duration.
241+ *
242+ *@param {number|null } [time] - Optional. The new pending seek time, can be a number or null.
243+ *@return {number|null } - The current pending seek time.
244+ */
245+ pendingSeekTime ( time ) {
246+ if ( time !== undefined ) {
247+ if ( time !== null ) {
248+ const duration = this . player_ . duration ( ) ;
249+
250+ this . pendingSeekTime_ = Math . max ( 0 , Math . min ( time , duration ) ) ;
251+ } else {
252+ this . pendingSeekTime_ = null ;
253+ }
254+ }
255+ return this . pendingSeekTime_ ;
256+ }
257+
236258/**
237259 * Get the percentage of media played so far.
238260 *
@@ -242,8 +264,8 @@ class SeekBar extends Slider {
242264getPercent ( ) {
243265// If we have a pending seek time, we are scrubbing on mobile and should set the slider percent
244266// to reflect the current scrub location.
245- if ( this . pendingSeekTime_ ) {
246- return this . pendingSeekTime_ / this . player_ . duration ( ) ;
267+ if ( this . pendingSeekTime ( ) !== null ) {
268+ return this . pendingSeekTime ( ) / this . player_ . duration ( ) ;
247269}
248270
249271const currentTime = this . getCurrentTime_ ( ) ;
@@ -284,7 +306,7 @@ class SeekBar extends Slider {
284306
285307// Don't pause if we are on mobile and `disableSeekWhileScrubbingOnMobile: true`.
286308// In that case, playback should continue while the player scrubs to a new location.
287- if ( ! this . shouldDisableSeekWhileScrubbingOnMobile_ ) {
309+ if ( ! this . shouldDisableSeekWhileScrubbing_ ) {
288310this . player_ . pause ( ) ;
289311}
290312
@@ -351,8 +373,8 @@ class SeekBar extends Slider {
351373}
352374
353375// if on mobile and `disableSeekWhileScrubbingOnMobile: true`, keep track of the desired seek point but we won't initiate the seek until 'touchend'
354- if ( this . shouldDisableSeekWhileScrubbingOnMobile_ ) {
355- this . pendingSeekTime_ = newTime ;
376+ if ( this . shouldDisableSeekWhileScrubbing_ ) {
377+ this . pendingSeekTime ( newTime ) ;
356378} else {
357379this . userSeek_ ( newTime ) ;
358380}
@@ -402,10 +424,10 @@ class SeekBar extends Slider {
402424this . player_ . scrubbing ( false ) ;
403425
404426// If we have a pending seek time, then we have finished scrubbing on mobile and should initiate a seek.
405- if ( this . pendingSeekTime_ ) {
406- this . userSeek_ ( this . pendingSeekTime_ ) ;
427+ if ( this . pendingSeekTime ( ) !== null ) {
428+ this . userSeek_ ( this . pendingSeekTime ( ) ) ;
407429
408- this . pendingSeekTime_ = null ;
430+ this . pendingSeekTime ( null ) ;
409431}
410432
411433/**
@@ -425,18 +447,46 @@ class SeekBar extends Slider {
425447}
426448}
427449
450+ /**
451+ * Handles pending seek time when `disableSeekWhileScrubbingOnSTV` is enabled.
452+ *
453+ *@param {number } stepAmount - The number of seconds to step (positive for forward, negative for backward).
454+ */
455+ handlePendingSeek_ ( stepAmount ) {
456+ if ( ! this . player_ . paused ( ) ) {
457+ this . player_ . pause ( ) ;
458+ }
459+
460+ const currentPos = this . pendingSeekTime ( ) !== null ?
461+ this . pendingSeekTime ( ) :
462+ this . player_ . currentTime ( ) ;
463+
464+ this . pendingSeekTime ( currentPos + stepAmount ) ;
465+ this . player_ . trigger ( { type :'timeupdate' , target :this , manuallyTriggered :true } ) ;
466+ }
467+
428468/**
429469 * Move more quickly fast forward for keyboard-only users
430470 */
431471stepForward ( ) {
432- this . userSeek_ ( this . player_ . currentTime ( ) + this . options ( ) . stepSeconds ) ;
472+ // if `disableSeekWhileScrubbingOnSTV: true`, keep track of the desired seek point but we won't initiate the seek
473+ if ( this . shouldDisableSeekWhileScrubbing_ ) {
474+ this . handlePendingSeek_ ( this . options ( ) . stepSeconds ) ;
475+ } else {
476+ this . userSeek_ ( this . player_ . currentTime ( ) + this . options ( ) . stepSeconds ) ;
477+ }
433478}
434479
435480/**
436481 * Move more quickly rewind for keyboard-only users
437482 */
438483stepBack ( ) {
439- this . userSeek_ ( this . player_ . currentTime ( ) - this . options ( ) . stepSeconds ) ;
484+ // if `disableSeekWhileScrubbingOnSTV: true`, keep track of the desired seek point but we won't initiate the seek
485+ if ( this . shouldDisableSeekWhileScrubbing_ ) {
486+ this . handlePendingSeek_ ( - this . options ( ) . stepSeconds ) ;
487+ } else {
488+ this . userSeek_ ( this . player_ . currentTime ( ) - this . options ( ) . stepSeconds ) ;
489+ }
440490}
441491
442492/**
@@ -448,6 +498,10 @@ class SeekBar extends Slider {
448498 *
449499 */
450500handleAction ( event ) {
501+ if ( this . pendingSeekTime ( ) !== null ) {
502+ this . userSeek_ ( this . pendingSeekTime ( ) ) ;
503+ this . pendingSeekTime ( null ) ;
504+ }
451505if ( this . player_ . paused ( ) ) {
452506this . player_ . play ( ) ;
453507} else {