Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PE-80] fix: escape markdown content for images #6096

Merged
merged 1 commit into from
Dec 2, 2024

Conversation

aaryan610
Copy link
Collaborator

@aaryan610 aaryan610 commented Nov 26, 2024

Bug fix:

Escape image components when copying/exporting editor content as markdown.

Summary by CodeRabbit

  • New Features

    • Enhanced image insertion functionality with file validation to ensure only appropriate files are processed.
  • Bug Fixes

    • Removed outdated markdown serialization for images, streamlining image handling.
  • Refactor

    • Updated method signatures to simplify the image serialization process.

@aaryan610 aaryan610 added 🐛bug Something isn't working 🌐frontend pages labels Nov 26, 2024
@aaryan610 aaryan610 added this to the v0.24.0 milestone Nov 26, 2024
Copy link
Contributor

coderabbitai bot commented Nov 26, 2024

Walkthrough

The pull request introduces significant modifications to the CustomImageExtension and CustomReadOnlyImageExtension within the custom image handling functionality. Key changes include the removal of markdown serialization logic, which has been replaced with an empty serialize function. Additionally, the handling of image attributes has been adjusted, and the commands related to image insertion now include validation for file types. These changes affect how images are processed and represented in markdown documents.

Changes

File Path Change Summary
packages/editor/src/core/extensions/custom-image/custom-image.ts - Removed ImageAttributes import.
- Updated serialize method to an empty function.
- Modified addStorage to initialize markdown with an empty serialize function.
- Enhanced addCommands to validate files before image insertion.
packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts - Removed imports of MarkdownSerializerState and Node.
- Updated serialize method to an empty function in addStorage.
- Retained overall structure and functionality of the extension.

Possibly related PRs

Suggested labels

✍️editor

Suggested reviewers

  • SatishGandham

🐰 In the land of code, where images play,
A change has come, brightening the way.
No more markdown, just a simple tune,
Images dance beneath the coding moon.
With checks in place, they leap and glide,
A joyful hop, with attributes as their guide! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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 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
Contributor

@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: 1

🧹 Outside diff range and nitpick comments (3)
packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (3)

Line range hint 13-39: Consider adding accessibility attributes

The image component could benefit from accessibility improvements. Consider adding support for alt text and role attributes in the configuration.

 addAttributes() {
   return {
     ...this.parent?.(),
+    alt: {
+      default: null,
+    },
+    role: {
+      default: 'img',
+    },
     width: {
       default: "35%",
     },

Line range hint 61-65: Add error handling for image source retrieval

The getImageSource command should include error handling to gracefully handle failed image retrievals.

 addCommands() {
   return {
-    getImageSource: (path: string) => async () => await getAssetSrc(path),
+    getImageSource: (path: string) => async () => {
+      try {
+        return await getAssetSrc(path);
+      } catch (error) {
+        console.error('Failed to load image:', error);
+        return null;
+      }
+    },
   };
 },

Line range hint 1-71: Verify integration with markdown export system

The removal of markdown serialization in this component might affect the broader markdown export system. Please ensure:

  1. The change aligns with the overall markdown processing pipeline
  2. Other components that might depend on image markdown serialization are updated
  3. The export functionality still works as expected with this change

Consider documenting the new markdown handling approach in the component's documentation or README to help other developers understand the intended behavior.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7469e67 and 0f6fb1e.

📒 Files selected for processing (2)
  • packages/editor/src/core/extensions/custom-image/custom-image.ts (2 hunks)
  • packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (2 hunks)
🔇 Additional comments (2)
packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (1)

55-59: Verify the empty serializer's impact on markdown escaping

While removing the serialization logic might prevent incorrect markdown generation, an empty serializer might not properly handle all image-related markdown scenarios. Please clarify:

  1. How are images represented when copying content?
  2. What happens when exporting content with images?
  3. How are existing markdown images handled?

Let's check for any related test cases or usage patterns:

✅ Verification successful

Empty serializer is the correct approach for read-only image handling

The empty serialize() method in the markdown storage is intentional and correct for the following reasons:

  1. The read-only extension (CustomReadOnlyImageExtension) is specifically designed to display images without editing capabilities (note selectable: false, draggable: false).
  2. The parent extension configuration shows that markdown transformation is handled at the editor level with Markdown.configure({ html: true, transformCopiedText: true }).
  3. The empty serializer prevents any markdown generation for images in read-only mode, which is the desired behavior as these images should not be editable or exportable.
  4. The editable version (CustomImageExtension) has the same empty serializer, maintaining consistency in how images are handled during markdown operations.

The implementation aligns with the PR's goal of fixing markdown content escaping for images by explicitly preventing markdown serialization in both read-only and editable contexts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for related test cases and usage patterns
echo "Searching for test files related to image handling..."
fd -e test.ts -e spec.ts | xargs rg -l "imageComponent|CustomReadOnlyImageExtension"

echo "Searching for markdown export/copy implementations..."
rg -g '!*.test.ts' -g '!*.spec.ts' "markdown.*export|markdown.*copy|markdown.*serialize" 

Length of output: 1171


Script:

#!/bin/bash
# Let's check the implementation details of the custom image extensions and related markdown handling

# Check the custom image implementation
echo "=== Custom Image Implementation ==="
rg -A 10 "markdown.*serialize" packages/editor/src/core/extensions/custom-image/custom-image.ts

# Check if there are any other markdown serializers in the codebase
echo -e "\n=== Other Markdown Serializers ==="
rg -A 5 "markdown.*serialize"

# Check how images are handled in exports
echo -e "\n=== Image Export Handling ==="
rg -A 10 "export.*image|copy.*image"

# Check the parent extension configuration
echo -e "\n=== Parent Extension Configuration ==="
cat packages/editor/src/core/extensions/read-only-extensions.tsx

Length of output: 10189


Script:

#!/bin/bash
# Let's examine the markdown configuration and image handling in both custom and read-only image extensions

echo "=== Markdown Configuration in Extensions ==="
ast-grep --pattern 'Markdown.configure({
  $$$
})'

echo -e "\n=== Custom Image Extension Implementation ==="
cat packages/editor/src/core/extensions/custom-image/custom-image.ts

echo -e "\n=== Read-only Image Extension Implementation ==="
cat packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts

echo -e "\n=== Base Image Extension Implementation ==="
cat packages/editor/src/core/extensions/image/image-extension-without-props.ts

Length of output: 8710

packages/editor/src/core/extensions/custom-image/custom-image.ts (1)

127-130: Verify the impact of removing markdown serialization

While removing the serialization logic aligns with the goal of escaping markdown content for images, we should verify that this change doesn't break existing functionality.

Let's check for any dependencies on markdown serialization:

✅ Verification successful

Empty markdown serialization is intentional and safe

The empty markdown serialization in custom-image.ts is correct and aligns with the codebase's image handling strategy. Here's why:

  • The markdown export functionality is handled separately in editor.helper.ts through replaceCustomComponentsFromMarkdownContent(), which properly converts image components to markdown format.
  • Both read-only and editable image extensions have the same empty serialization, indicating this is the intended design.
  • The export functionality in export-page-modal.tsx uses the editor's built-in getMarkDown() method combined with the helper functions, bypassing the need for individual extension serialization.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for code that might depend on image markdown serialization
rg -l "markdown" | xargs rg -l "serialize|export|copy" 

# Search for tests related to image serialization
rg -l "test|spec" | xargs rg -l "image.*markdown|markdown.*image"

Length of output: 1019


Script:

#!/bin/bash
# Check the implementation of read-only-custom-image.ts to understand the relationship
cat packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts

# Check export-page-modal.tsx to understand if it depends on markdown serialization
cat web/core/components/pages/modals/export-page-modal.tsx

# Check markdown-to-component.tsx to understand markdown processing
cat web/core/components/ui/markdown-to-component.tsx

Length of output: 12633


Script:

#!/bin/bash
# Check the editor helper to understand markdown content handling
cat web/helpers/editor.helper.ts

# Check if there are any tests for image export functionality
rg -l "test" packages/editor/src/core/extensions/custom-image/ | xargs cat

Length of output: 10075

Comment on lines +127 to 130
// escape markdown for images
markdown: {
serialize(state: MarkdownSerializerState, node: Node) {
const attrs = node.attrs as ImageAttributes;
const imageSource = state.esc(this?.editor?.commands?.getImageSource?.(attrs.src) || attrs.src);
const imageWidth = state.esc(attrs.width?.toString());
state.write(`<img src="${state.esc(imageSource)}" width="${imageWidth}" />`);
state.closeBlock(node);
},
serialize() {},
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add tests to validate the fix

To ensure the fix works as intended and prevent regressions, consider adding tests that verify:

  1. Images are correctly handled when copying content
  2. Images are properly preserved when exporting to markdown
  3. The editor correctly displays images after import/export operations

Here's a suggested test structure:

describe('CustomImageExtension markdown handling', () => {
  it('should preserve images when copying content', () => {
    // Test implementation
  });
  
  it('should correctly export images to markdown', () => {
    // Test implementation
  });
  
  it('should properly display images after import/export', () => {
    // Test implementation
  });
});

@SatishGandham
Copy link
Contributor

Why are we not trying to translate it to markdown? Is it because of presigned urls?

@pushya22 pushya22 merged commit fc52936 into preview Dec 2, 2024
14 of 15 checks passed
@pushya22 pushya22 deleted the fix/image-markdown branch December 2, 2024 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛bug Something isn't working 🌐frontend pages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants