Skip to content

Conversation

@nickpagz
Copy link
Contributor

@nickpagz nickpagz commented Aug 1, 2025

This PR adds the Marquee block as used on the a8c/timeline site.

marquee.zip

Summary by CodeRabbit

  • New Features

    • Introduced the "Marquee" WordPress block, allowing users to add customizable scrolling marquee effects to content with options for direction, speed, pause on hover, gap, and fade edges.
    • Added live preview and configuration controls in the block editor for real-time adjustments.
    • Enabled automatic plugin updates and provided initial plugin documentation and changelog.
  • Documentation

    • Added comprehensive plugin documentation, installation instructions, FAQ, and changelog.
  • Chores

    • Included configuration files for coding standards, version control, and development scripts.

@coderabbitai
Copy link

coderabbitai bot commented Aug 1, 2025

Walkthrough

This change introduces a new WordPress plugin named "Marquee" designed to provide a customizable marquee effect for content using the block editor. The update includes all foundational files and configuration for the plugin, such as .editorconfig, .gitignore, package.json, and CHANGELOG.md. The plugin's main PHP file sets up block registration, self-update functionality via a custom class interfacing with a remote version manager, and block metadata. The block itself is defined with a JSON configuration, React-based editor and save components, SCSS styles for both editor and frontend, and a JavaScript frontend script to handle animation and interactivity. Documentation and readme files are also included. No existing exported or public entities were altered; all additions are new.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 579df6a and 733b0d2.

📒 Files selected for processing (7)
  • marquee/.editorconfig (1 hunks)
  • marquee/classes/class-wpcomsp-blocks-self-update.php (1 hunks)
  • marquee/src/marquee/edit.js (1 hunks)
  • marquee/src/marquee/editor.scss (1 hunks)
  • marquee/src/marquee/save.js (1 hunks)
  • marquee/src/marquee/style.scss (1 hunks)
  • marquee/src/marquee/view.js (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • marquee/src/marquee/view.js
  • marquee/src/marquee/editor.scss
🚧 Files skipped from review as they are similar to previous changes (5)
  • marquee/src/marquee/save.js
  • marquee/.editorconfig
  • marquee/classes/class-wpcomsp-blocks-self-update.php
  • marquee/src/marquee/edit.js
  • marquee/src/marquee/style.scss
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

🔭 Outside diff range comments (2)
marquee/readme.txt (1)

9-56: Update readme content to reflect actual marquee functionality

The readme.txt contains boilerplate content from the Create Block tool. For a production release, update:

  • Line 9: Replace "Example block scaffolded with Create Block tool" with actual marquee block description
  • Lines 13-16: Replace generic description with marquee-specific features and usage
  • Lines 30-36: Replace placeholder FAQ with relevant marquee questions
  • Lines 40-44: Update screenshot descriptions to reflect marquee functionality
-Example block scaffolded with Create Block tool.
+A customizable marquee block that creates smooth scrolling text and content animations.

== Description ==

-This is the long description. No limit, and you can use Markdown (as well as in the following sections).
-
-For backwards compatibility, if this section is missing, the full length of the short description will be used, and
-Markdown parsed.
+Create eye-catching scrolling content with the Marquee block. Features include:
+
+* Customizable scroll direction (left, right, up, down)
+* Adjustable speed settings
+* Pause on hover functionality
+* Fade edges effect
+* Responsive design
+* Support for any inner block content
marquee/marquee copy.php (1)

1-61: Remove duplicate plugin file or clarify its purpose.

This file is nearly identical to marquee.php with only a path difference in the block registration (line 58: /build vs /build/marquee). Having duplicate plugin files can cause:

  1. Plugin conflicts if both are activated
  2. Maintenance confusion requiring changes in multiple places
  3. Inconsistent behavior due to path differences

Please clarify the purpose of this file and consider removing it if it's not needed.

If this is a development/testing version, consider:

  • Moving it outside the main plugin directory
  • Adding clear comments explaining its purpose
  • Using a different approach like environment-based configuration
🧹 Nitpick comments (8)
marquee/classes/class-wpcomsp-blocks-self-update.php (2)

54-56: Fix comment mismatch with actual URL

The comment mentions "opsoasis.mystagingwebsite.com" but the actual URL is "opsoasis.wpspecialprojects.com".

-		// Ask opsoasis.mystagingwebsite.com if there's an update.
+		// Ask opsoasis.wpspecialprojects.com if there's an update.

65-68: Fix comment mismatch and improve clarity

The comment references the wrong domain again.

-		// Bail if this plugin wasn't found on opsoasis.mystagingwebsite.com.
+		// Bail if this plugin wasn't found on the update server.
marquee/CHANGELOG.md (1)

1-2: Consider expanding changelog with feature details

For better documentation, consider adding more details about the initial release features and any known issues.

-0.1.0
-Initial release
+## 0.1.0
+Initial release
+
+### Features
+- Marquee block with customizable direction (left, right, up, down)
+- Adjustable scroll speed
+- Pause on hover functionality
+- Fade edges effect
+- Gap control for spacing
+
+### Known Issues
+- Fade edges option may prevent scrolling in some cases
marquee/src/marquee/save.js (1)

18-36: Consider extracting className construction for better maintainability

The className construction could be more readable and maintainable.

 export default function save({ attributes }) {
 	const { direction, speed, pauseOnHover, gap, fadeEdges } = attributes;
+	
+	const classNames = [
+		'wp-block-a8csp-marquee',
+		`direction-${direction}`,
+		`speed-${speed}`,
+		fadeEdges && 'has-fade',
+		pauseOnHover && 'has-pause-on-hover'
+	].filter(Boolean).join(' ');
+	
 	const blockProps = useBlockProps.save({
-		className: `wp-block-a8csp-marquee direction-${direction} speed-${speed}${fadeEdges ? ' has-fade' : ''}${pauseOnHover ? ' has-pause-on-hover' : ''}`,
+		className: classNames,
 		style: {
 			'--marquee-gap': `${gap}px`
 		}
 	});
marquee/src/marquee/edit.js (1)

78-80: Consider adding speed unit indication.

The speed range control doesn't indicate what the units represent, which could confuse users about the expected behavior.

Apply this diff to add help text:

 					<RangeControl
 						label={__('Speed', 'marquee')}
+						help={__('Higher values = faster scrolling', 'marquee')}
 						value={speed}
 						onChange={(value) => setAttributes({ speed: value })}
 						min={10}
 						max={200}
 					/>
marquee/src/marquee/editor.scss (1)

19-26: Excessive use of !important may cause maintenance issues.

While the !important declarations ensure layout consistency, they make the styles harder to override and maintain. Consider using more specific selectors instead.

Consider this alternative approach with higher specificity:

-	.marquee-items {
-		// Force horizontal layout
-		display: flex !important;
-		flex-direction: row !important;
-		flex-wrap: nowrap !important;
-		gap: var(--marquee-gap, 20px) !important;
+	.marquee-items,
+	.marquee-items.block-editor-block-list__layout {
+		display: flex;
+		flex-direction: row;
+		flex-wrap: nowrap;
+		gap: var(--marquee-gap, 20px);
 		padding: 10px 0;
 
-		// Explicitly disable animation in editor
-		animation: none !important;
+		animation: none;
marquee/src/marquee/style.scss (1)

27-30: Complex selector may cause specificity issues.

The nested negation selector :not(.block-editor-block-list__layout *) is complex and may cause maintenance challenges or unexpected behavior.

Consider using a more explicit approach with CSS classes:

-		// Only apply animation on frontend by excluding the block editor
-		&:not(.block-editor-block-list__layout *) {
-			animation: marquee var(--duration, 12s) linear infinite;
-			animation-play-state: var(--play-state, running);
-		}
+		// Animation controlled by body class or data attribute
+		body:not(.block-editor-page) & {
+			animation: marquee var(--duration, 12s) linear infinite;
+			animation-play-state: var(--play-state, running);
+		}
marquee/src/marquee/view.js (1)

102-104: Unnecessary cleanup on beforeunload.

The beforeunload event cleanup is unnecessary since the page is being unloaded anyway, and it could potentially interfere with the browser's cleanup process.

Consider removing this cleanup:

-		// Cleanup on page leave
-		window.addEventListener('beforeunload', () => {
-			itemsContainer.style.setProperty('--play-state', 'running');
-		});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdab409 and 579df6a.

⛔ Files ignored due to path filters (1)
  • marquee/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • marquee/.editorconfig (1 hunks)
  • marquee/.gitignore (1 hunks)
  • marquee/CHANGELOG.md (1 hunks)
  • marquee/classes/class-wpcomsp-blocks-self-update.php (1 hunks)
  • marquee/marquee copy.php (1 hunks)
  • marquee/marquee.php (1 hunks)
  • marquee/package.json (1 hunks)
  • marquee/readme.txt (1 hunks)
  • marquee/src/marquee/block.json (1 hunks)
  • marquee/src/marquee/edit.js (1 hunks)
  • marquee/src/marquee/editor.scss (1 hunks)
  • marquee/src/marquee/index.js (1 hunks)
  • marquee/src/marquee/save.js (1 hunks)
  • marquee/src/marquee/style.scss (1 hunks)
  • marquee/src/marquee/view.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
marquee/src/marquee/save.js (2)
marquee/src/marquee/edit.js (2)
  • attributes (36-36)
  • blockProps (43-50)
marquee/src/marquee/view.js (2)
  • speed (39-39)
  • pauseOnHover (48-48)
marquee/marquee.php (2)
marquee/classes/class-wpcomsp-blocks-self-update.php (3)
  • WPCOMSP_Blocks_Self_Update (13-80)
  • get_instance (22-28)
  • hooks (33-35)
marquee/marquee copy.php (1)
  • a8csp_marquee_block_init (57-59)
marquee/src/marquee/edit.js (2)
marquee/src/marquee/save.js (2)
  • attributes (19-19)
  • blockProps (20-25)
marquee/src/marquee/view.js (3)
  • itemsContainer (32-32)
  • speed (39-39)
  • pauseOnHover (48-48)
marquee/src/marquee/index.js (1)
marquee/src/marquee/edit.js (1)
  • Edit (35-112)
🔇 Additional comments (23)
marquee/.editorconfig (1)

16-18: YAML override looks good

YAML files correctly switch to 2-space indentation, matching common tooling expectations.

marquee/.gitignore (1)

1-31: LGTM - Standard .gitignore configuration

The .gitignore file properly excludes common development artifacts, build outputs, and sensitive files. All patterns are appropriate for a WordPress plugin with Node.js build tooling.

marquee/src/marquee/save.js (2)

21-21: Fix className construction and spacing issues

The className construction has spacing issues that could affect CSS targeting.

-		className: `wp-block-a8csp-marquee direction-${direction}${fadeEdges ? ' has-fade' : ''} speed-${speed} ${pauseOnHover ? ' has-pause-on-hover' : ''}`,
+		className: `wp-block-a8csp-marquee direction-${direction} speed-${speed}${fadeEdges ? ' has-fade' : ''}${pauseOnHover ? ' has-pause-on-hover' : ''}`,

The original code had:

  1. Missing space before speed-${speed}
  2. Extra space before the pauseOnHover conditional

This could cause CSS selectors to fail or create malformed class names.

Likely an incorrect or invalid review comment.


19-25: No CSS interference from .has-fade mask

I’ve confirmed that the .has-fade rule in marquee/src/marquee/style.scss only applies a CSS mask (via mask-image/-webkit-mask-image) to the existing .marquee-content container. It doesn’t alter overflow, positioning, or animation properties, so it shouldn’t interrupt the marquee’s scrolling behavior.

marquee/package.json (3)

1-7: LGTM!

The package metadata is well-structured and follows WordPress block development standards. The version "0.1.0" appropriately reflects the WIP status mentioned in the PR objectives.


8-16: Scripts configuration supports development workflow.

The npm scripts are well-configured for WordPress block development and include the linting scripts mentioned as needed in the PR objectives.


17-19: @wordpress/scripts is current at ^30.20.0

The devDependency is already using the latest published version (30.20.0 as of July 23, 2025). No update is required.

marquee/src/marquee/index.js (5)

6-6: LGTM!

Proper import of the WordPress block registration function.


15-15: LGTM!

Correct import of SCSS styles for webpack processing, ensuring styles are applied in both editor and frontend.


20-22: LGTM!

Proper imports of the block components and metadata following WordPress standards.


29-39: LGTM!

Standard WordPress block registration pattern using metadata.name and properly structured edit/save components.


1-28: Excellent documentation.

The comments are comprehensive and follow WordPress coding standards, providing helpful context and links to relevant documentation.

marquee/marquee.php (3)

1-16: LGTM!

Plugin headers are well-structured and consistent with package.json. Version requirements are appropriate for modern WordPress block development.


18-20: LGTM!

Proper security check to prevent direct file access, following WordPress best practices.


22-46: Well-implemented self-update mechanism.

The conditional loading prevents conflicts between multiple plugins using the same update class, and the filter setup correctly enables auto-updates for this plugin.

marquee/src/marquee/block.json (4)

1-10: LGTM!

Block metadata is properly configured with correct schema, current API version, and appropriate namespace following WordPress standards.


11-23: Well-configured block supports.

The supports configuration provides good customization options while maintaining security by disabling raw HTML. The alignment restrictions to "wide" and "full" are appropriate for a marquee effect.


24-46: Attributes are well-defined.

The attribute configuration is comprehensive and appropriate for a marquee block. Note that the fadeEdges attribute relates to the issue mentioned in the PR objectives where enabling "Fade Edges" prevents scrolling.


47-47: LGTM!

Textdomain is consistent with the plugin configuration.

marquee/marquee copy.php (4)

3-16: Plugin metadata looks well-structured.

The plugin header follows WordPress standards with appropriate metadata including version, requirements, author information, and licensing details. The Update URI pointing to the special projects domain is consistent with the self-update mechanism.


18-20: Security check is properly implemented.

The ABSPATH check correctly prevents direct file access, which is a WordPress security best practice.


38-46: Auto-update registration follows the expected pattern.

The filter hook implementation correctly adds the plugin slug to enable auto-updates from the monorepo system. The anonymous function approach is clean and self-contained.


22-28: Self-update class security review completed

I’ve reviewed marquee/classes/class-wpcomsp-blocks-self-update.php and found no security concerns in its auto-update implementation:

  • Uses WordPress HTTP API (wp_remote_get) over HTTPS. By default SSL verification is enabled, and there’s no override disabling it.
  • No direct file operations (e.g. file_put_contents, ZipArchive, WP_Filesystem, etc.) are performed in the class; it only hooks into the core update transients.
  • The singleton pattern and hook registration are correctly scoped to prevent duplicate loading.

No changes are required.

@nickpagz nickpagz changed the title Add Marquee block - WIP Add Marquee block - a8c timeline version Aug 5, 2025
@tommusrhodus
Copy link
Contributor

Hey @nickpagz - do you need a review here?

@nickpagz
Copy link
Contributor Author

@tommusrhodus Not yet I don't think. There's still some testing to do and a laundry list of previous issues I was made aware of/noticed after creating the PR.
I updated that list of sub issues to things I know/think are now fixed. I also suggested the block could be very useable in it's current form, but highlighted issues that would be nice to fix, and some that may not be worth chasing (ref p1754646305206359/1754492721.889129-slack-C02C4GXMY).

@pixel21
Copy link
Collaborator

pixel21 commented Sep 29, 2025

Hi @nickpagz , we had a request in Linear to add two enhancements to this plugin so I created a PR that does that. If you have some time to review my PR, I would really appreciate it.

marquee.zip <-- updated plugin

@nickpagz
Copy link
Contributor Author

@pixel21 Apologies, finally got around to this. I approved the PR but did leave a comment wrt the fade, maybe there's an easy way to fix it. If not, we should still merge this change but track it as a separate issue.

@davewhitley davewhitley mentioned this pull request Oct 29, 2025
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