Skip to content

GoDAM - VideoJet Support - #2051

Open
KMchaudhary wants to merge 3 commits into
developfrom
feat/videojet-support
Open

GoDAM - VideoJet Support#2051
KMchaudhary wants to merge 3 commits into
developfrom
feat/videojet-support

Conversation

@KMchaudhary

@KMchaudhary KMchaudhary commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

This pull request introduces a new "Play on modal" feature for the GoDAM video player, allowing videos to open in a lightbox modal when clicked, and improves the media library's transcoding UI logic for better compatibility with other plugins. It also adds guide message support to the thumbnail panel and refines related UI styling.

GoDAM Player: "Play on modal" feature

  • Added a new playOnModal block attribute and toggle control in the editor, enabling videos to open in a centered modal/lightbox overlay when clicked (block.json, edit-common-settings.js, godam-player.scss, playerManager.js, modalManager.js). [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
  • Implemented modal overlay, close button, and keyboard accessibility; the inline player is moved into the modal and restored on close. [1] [2]

UI Improvements: Thumbnail panel guide message

  • Added support for an optional, sanitized guide message (with markup) in the video thumbnail panel, styled for clarity in both the block editor and media library. [1] [2] [3] [4]

Media Library: Transcoding UI logic

  • Refactored logic to ensure GoDAM's transcoding status badges and retranscode bulk action remain available on the media grid page (upload.php), even when folder organization is disabled (additive mode), while keeping other custom UI minimal for compatibility with other DAM plugins. [1] [2] [3] [4] [5] [6]

Styling and Accessibility

  • Added and updated CSS for the modal overlay, close button, and guide messages to ensure a consistent and accessible user experience. [1] [2] [3]

Other minor improvements

  • Added stylelint comments to clarify and suppress linter warnings for intentional CSS selector usage. [1] [2]

1. Custom thumbnail guide message
Screenshot 2026-07-29 at 4 07 02 PM

Screenshot 2026-07-29 at 4 11 38 PM

2. Re-add the support transcoding status and re-transcode media action

Screen.Recording.2026-07-29.at.7.31.23.PM.mov

3. Add Lightbox support for GoDAM Video block, shortcode, as well as elementor and wpbakery blocks

Screen.Recording.2026-07-29.at.5.33.39.PM.mp4

KMchaudhary added 3 commits July 29, 2026 16:13
Add a 'Play on modal' toggle (default false) to the godam/video block,
[godam_video] shortcode, Elementor widget, and WPBakery element. When
enabled, clicking the inline player opens it in a lightbox modal
(inspired by the shoppable video modal) and plays it there.
@KMchaudhary
KMchaudhary marked this pull request as ready for review July 29, 2026 15:10
Copilot AI review requested due to automatic review settings July 29, 2026 15:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds “Play on modal” lightbox playback to the GoDAM video player across block/shortcode/page-builders, introduces extensible guide messages in thumbnail panels, and refines media-library transcoding UI gating for better plugin compatibility.

Changes:

  • Added a playOnModal attribute/control and wired it into frontend player initialization with a new modal manager + styles.
  • Added optional (sanitized) guide-message support for thumbnail panels in both the block editor and media-library attachment details.
  • Updated media-library UI gating so transcoding status/bulk action remain available on upload.php even in additive mode.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
inc/templates/godam-player.php Emits modal-related class + data-play-on-modal attribute for frontend behavior.
inc/classes/wpbakery-elements/class-wpb-godam-video.php Adds WPBakery control for play-on-modal.
inc/classes/shortcodes/class-godam-player.php Adds shortcode attributes + boolean parsing/mapping for play-on-modal.
inc/classes/elementor-widgets/class-godam-video.php Adds Elementor switcher and passes play-on-modal into render attributes.
inc/classes/class-assets.php Localizes new guide-message strings via filters for editor and media library.
assets/src/js/media-library/views/attachment-detail-two-column.js Renders optional sanitized guide message in attachment details “Video Thumbnails” panel.
assets/src/js/media-library/views/attachment-browser.js Adjusts additive-mode gating to keep retranscode bulk action available on upload.php.
assets/src/js/media-library/utility.js Introduces isMediaTranscodingUIEnabled() helper and exports it.
assets/src/js/media-library/index.js Uses isMediaTranscodingUIEnabled() to decide when to override media-library views.
assets/src/js/godam-player/managers/playerManager.js Registers play-on-modal videos with the new modal manager.
assets/src/js/godam-player/managers/modalManager.js New: implements shared lightbox modal that moves/restores the inline player.
assets/src/css/media-library.scss Styles the new media-library thumbnail guide message.
assets/src/css/godam-player.scss Adds modal overlay/wrapper/close styles and play-on-modal cursor affordance.
assets/src/blocks/godam-player/editor.scss Styles the block-editor thumbnail guide message.
assets/src/blocks/godam-player/edit-common-settings.js Adds play-on-modal toggle control to block inspector playback settings.
assets/src/blocks/godam-player/components/ThumbnailPanel.js Renders optional sanitized guide message in block thumbnail panel.
assets/src/blocks/godam-player/block.json Adds the new playOnModal block attribute.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +58
register( video ) {
const figure = video.closest( 'figure' );
// Move the outer wrapper (parent of <figure>) because it carries the
// aspect-ratio / brand-color CSS custom properties.
const playerRoot = figure?.parentElement || video.closest( '.godam-video-wrapper' );
if ( ! playerRoot || playerRoot.dataset.godamModalBound === '1' ) {
return;
}
playerRoot.dataset.godamModalBound = '1';

// Intercept clicks in the capture phase — before Video.js handles them —
// so an inline click opens the modal instead of playing inline.
playerRoot.addEventListener(
'click',
( event ) => {
// Once the player is live inside the modal, let clicks through to
// the Video.js controls.
if ( this.activeEntry && this.activeEntry.video === video ) {
return;
}
event.preventDefault();
event.stopPropagation();
this.open( video, playerRoot );
},
true,
);
}
Comment on lines +113 to +116
// Leave an anchor so the player returns to its exact inline position.
const anchor = document.createComment( 'godam-modal-anchor' );
playerRoot.parentNode.insertBefore( anchor, playerRoot );
modal.content.appendChild( playerRoot );
Comment on lines +2565 to +2569
&:hover,
&:focus-visible {
background: rgba(255, 255, 255, 0.2);
outline: none;
}
Comment on lines +2579 to +2581
width: min(1000px, 92vw);
max-height: 90dvh;
opacity: 0;
Comment on lines +199 to +201
* @since n.e.x.t
*
* @param string $message Guide message HTML. Default empty string.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disregard this one: @since n.e.x.t is the intended state during development in this repo. It is a WordPress-standard placeholder that gets resolved to the real version at release time (step 7 of the release checklist), which is exactly what stops a wrong version number from leaking into the docs. Please leave both occurrences as n.e.x.t.

@subodhr258 subodhr258 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Nice, well-commented PR. The "Play on modal" approach (move the already-initialised inline player into a shared lightbox, move it back on close) is a good call: it avoids a second player instance and keeps analytics/layers/engagement on one object. The additive-mode carve-out for transcoding UI is correctly scoped, and the guide-message filters are cleanly documented.

Two issues I would want resolved before merge, plus some accessibility and scoping points.

Verification I ran

  • Run PHPCS inspection passes. Run JS unit tests and Run Plugin Check are red, but both die at npm ci with lockfile drift, which is the known repo-wide breakage on develop, not this PR.
  • ESLint and Stylelint are clean on every file this PR touches (the handful of errors I hit locally all sit on pre-existing lines).
  • DOMPurify is already imported in attachment-detail-two-column.js, isomorphic-dompurify matches the repo convention, and videojs.getPlayer( element ) matches existing usage in videoPlayer.js / analytics.js / playerManager.js. All good.
  • I checked the additive-mode claim in the isMediaTranscodingUIEnabled() comment: attachment.js:39 does gate drag-to-folder on isFolderOrgDisabled(), so opening up wp.media.view.Attachments on upload.php does not leak folder behaviour. Claim holds.

1. Modal overflows the viewport for anything taller than ~4:3 (blocking)

.godam-player-modal-item forces max-width: 100% !important, which discards the height-derived max-width the template computes for Player Height. The player's height then comes only from aspect-ratio on .easydam-player.video-js. max-height: 90dvh on .godam-player-modal-wrapper does nothing here, because the wrapper's overflow is visible and the child is never height-constrained, so the video just overflows past it.

Measured in Chrome at 1470x836, using the PR's CSS verbatim:

Aspect ratio Rendered in modal Overflows viewport by
16:9 1000 x 563 0
4:3 1000 x 750 0
1:1 1000 x 1000 164px
9:16 1000 x 1778 942px

At 9:16 the control bar lands at y ≈ 1780, entirely below the fold, so the video is unplayable and uncloseable except via Escape. Vertical/reel video is a first-class GoDAM use case, so this will get hit.

The fix is to let the height cap drive the width instead of pinning width to 100%:

.godam-player-modal-item {
	width: auto !important;
	max-width: 100% !important;
	max-height: 90dvh;
	margin: 0 auto !important;
	aspect-ratio: var(--rtgodam-video-aspect-ratio, 16 / 9);
}

The custom property is already on the moved root, so aspect-ratio plus max-height plus width: auto will size the box off the height cap for tall videos and off the wrapper width for wide ones. Worth a quick check at 9:16, 1:1 and 16:9 on both a tall and a short viewport.

2. Share modal renders behind the player modal (blocking, if global share is on)

.share-modal-container is z-index: 9999 (godam-player.scss:663) and shareManager.getModalParent() appends it to document.body outside fullscreen. The new overlay is z-index: 100000 and the wrapper 100001, also on document.body, so they compare directly in the root stacking context.

Once the player is live inside the lightbox, clicks pass through to the Video.js controls, so the share button is reachable. Pressing it puts the share UI underneath the lightbox backdrop: the user sees the dark overlay and nothing else, with body scroll locked by both. Reproducible whenever enableGlobalVideoShare is on and the video has the share button.

Either raise .share-modal-container above the lightbox, or have getModalParent() return the modal wrapper when the player is inside it.

3. Close button is unreachable for screen readers

wrapper gets role="dialog" and aria-modal="true", but closeBtn is appended to document.body as a sibling of the wrapper, not inside it (modalManager.js:92). aria-modal="true" hides everything outside the dialog from the accessibility tree, so AT users have no Close control at all; Escape is the only way out.

Move the button inside wrapper and position it with CSS. While you are there, the dialog has no accessible name: aria-label={ __( 'Video player', 'godam' ) } or aria-labelledby pointing at the video title would fix it.

4. No focus trap

Focus is moved into the wrapper on open and restored on close, which is the right shape, but Tab still walks straight out of the dialog into the page behind it. Given aria-modal="true" is already claiming the dialog is modal, a Tab/Shift+Tab cycle in handleKeydown would make that true.


Worth discussing

Overlay inner blocks get swallowed. The capture-phase preventDefault() / stopPropagation() is bound to the whole player root, which contains .godam-video-overlay-container and its author-placed inner blocks. With Play on modal enabled, a "Buy now" button or link in the video overlay silently stops working and opens the lightbox instead. If that is intended, it is worth saying so in the toggle's help text. If not, skip the intercept when event.target.closest( '.godam-video-overlay-container' ) matches.

Autoplay + Play on modal is unresolved. With both on, the video autoplays inline (muted) and a click then re-plays it in the lightbox. The template already resolves the analogous conflict one line up (if ( $godam_autoplay ) { $godam_hover_select = 'none'; }), so there is a precedent for picking a winner here rather than leaving both active.

No tests. modalManager.js is 184 lines of DOM move-and-restore with an obvious failure mode: the player not landing back in its original position. The repo already runs JS unit tests next door (assets/src/js/godam-player/analytics-helpers.test.js, utils/layerActions.test.js), so an open then close then "DOM is byte-identical to before" assertion in jsdom would be cheap insurance.

Missing E2E hooks. The toggle correctly got data-test-id="godam-video-control-play-on-modal", but the modal DOM it drives (overlay, wrapper, close button) has none, so there is nothing stable to assert against.

iOS QA. Re-parenting a live <video> can reset playback state in Safari/iOS. The open path orders the move before play() and the close path pauses before moving, which is the right order, but this is worth an explicit check on a real device.

Nits

  • isMediaTranscodingUIEnabled() also gates wp.media.view.Attachments (column-width logic and the custom AttachmentView), which is wider than "transcoding UI". The behaviour is right, the name just undersells the scope.
  • rtgodam_video_block_video_thumbnails_guide_message and rtgodam_media_library_video_thumbnails_guide_message are near-identical. One filter with a $context argument would be easier to document, though two is defensible if you expect the copy to diverge.
  • The guide message's only sanitisation is client-side. A wp_kses_post() on the filter output would mean the trust boundary does not rest entirely on JS. Low risk since only code can set it, but it is one line.
  • The two stylelint-disable-next-line comments are reasonable, but no-duplicate-selectors firing on .godam-video-wrapper (three separate blocks now, at 1747, 2324 and 2515) reads more like the file wanting a consolidation pass than a rule wanting a silence.

/* The moved player root carries its own inline max-width (from Player Height);
* neutralise it so the player fills the modal width instead. The class is added
* to the player root by modalManager.js while it lives inside the modal. */
.godam-player-modal-item {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: max-width: 100% !important here discards the height-derived max-width the template computes, so the player's height comes only from aspect-ratio on .easydam-player.video-js. The max-height: 90dvh on the wrapper cannot rein it in, because the wrapper is overflow: visible and the child is never height-constrained.

Measured in Chrome at 1470x836 with this CSS verbatim: 16:9 renders 1000x563 (fine), 4:3 renders 1000x750 (fine), 1:1 renders 1000x1000 and overflows the viewport by 164px, 9:16 renders 1000x1778 and overflows by 942px with the control bar at y ~1780, entirely below the fold.

Letting the height cap drive the width fixes it:

.godam-player-modal-item {
	width: auto !important;
	max-width: 100% !important;
	max-height: 90dvh;
	margin: 0 auto !important;
	aspect-ratio: var(--rtgodam-video-aspect-ratio, 16 / 9);
}

The custom property is already on the moved root, so tall videos size off max-height and wide ones off the wrapper width.

.godam-player-modal-overlay {
position: fixed;
inset: 0;
z-index: 100000;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking (when global share is on): .share-modal-container is z-index: 9999 (line 663) and shareManager.getModalParent() appends it to document.body outside fullscreen, same as this overlay. At 100000 the lightbox backdrop sits on top of it.

Once the player is live in the modal, clicks pass through to the Video.js controls, so the share button is reachable. Pressing it shows the user a dark overlay and nothing else, with body scroll locked twice over.

Either raise .share-modal-container above the lightbox, or have getModalParent() return the modal wrapper when the player is inside it.

wrapper.appendChild( content );

document.body.appendChild( overlay );
document.body.appendChild( closeBtn );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The close button is appended to document.body as a sibling of wrapper, but wrapper carries aria-modal="true" (line 84). That attribute hides everything outside the dialog from the accessibility tree, so screen reader users have no Close control at all and Escape becomes the only exit.

Moving closeBtn inside wrapper and positioning it with CSS keeps the same visual result and puts it back in the a11y tree. The dialog is also unnamed, so aria-label={ __( 'Video player', 'godam' ) } (or aria-labelledby pointing at the video title) would be worth adding on the same line.

if ( this.activeEntry && this.activeEntry.video === video ) {
return;
}
event.preventDefault();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This intercepts every click anywhere in the player root, which includes .godam-video-overlay-container and its author-placed inner blocks. With Play on modal enabled, a link or button an author dropped into the video overlay silently stops working and opens the lightbox instead.

If that is the intended behaviour it is worth stating in the toggle's help text. If not, an early bail on event.target.closest( '.godam-video-overlay-container' ) would keep the overlay interactive.

*
* @param {KeyboardEvent} event - Keydown event.
*/
handleKeydown( event ) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Escape closes and focus is restored on close, which is the right shape, but Tab still walks straight out of the dialog into the page behind it. Since aria-modal="true" is already asserting the dialog is modal, a Tab / Shift+Tab cycle here would make that assertion true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants