Skip to content

[WIKI-345] chore: pass disabled and flagged extensions to block menu#7152

Merged
sriramveeraghanta merged 32 commits intopreviewfrom
chore-refactor_editor
Aug 25, 2025
Merged

[WIKI-345] chore: pass disabled and flagged extensions to block menu#7152
sriramveeraghanta merged 32 commits intopreviewfrom
chore-refactor_editor

Conversation

@iam-vipin
Copy link
Member

@iam-vipin iam-vipin commented Jun 2, 2025

Description

This PR pass disabled and flagged extension in block menu in editor

Type of Change

  • Code refactoring

Screenshots and Media (if applicable)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 2, 2025

Walkthrough

This update introduces support for a new "external-embed" editor extension, propagates a disabledExtensions prop through several editor components, and adds new embed handler components. It also includes type updates, safer extension storage access, CSS adjustments for embed nodes, and a 20-second timeout for API requests.

Changes

File(s) Change Summary
live/src/core/services/api.service.ts Added a 20-second timeout to the axios instance in APIService.
.../editors/document/collaborative-editor.tsx
.../document/read-only-editor.tsx
Passed disabledExtensions prop down to PageRenderer.
.../editors/document/page-renderer.tsx Added disabledExtensions prop to PageRenderer and forwarded it to BlockMenu.
.../menus/block-menu.tsx Changed disabledExtensions prop in BlockMenuProps to required and typed as IEditorProps["disabledExtensions"].
.../editors/editor-container.tsx Reformatted import order and expression; no logic change.
.../editors/link-view-container.tsx Replaced direct extension storage access with generic utility; added optional chaining for safety.
.../extensions/custom-link/extension.tsx Added isBubbleMenuOpen property to CustomLinkStorage and initialized it in storage.
.../plugins/drag-handle.ts Filtered out elements inside .editor-embed-component containers unless they themselves match.
.../types/editor.ts Added optional embedHandler prop to editor types; adjusted related interfaces for embedHandler.
.../types/extensions.ts Added "external-embed" to TExtensions type.
.../types/hook.ts Added embedHandler to editor and read-only hook prop types.
.../styles/drag-drop.css Updated CSS selectors to include .node-externalEmbedComponent for selection and styling.
space/ce/components/editor/external-embed/embed-handler.tsx
web/ce/components/pages/editor/external-embed/embed-handler.tsx
Added new exported EmbedHandler React components for external embeds.
space/helpers/string.helper.ts Updated isCommentEmpty to treat "embed-component" tags as ignorable content.
.../core/components/editors/editor-wrapper.tsx Added embedHandler prop and passed it to useEditor hook.
.../core/components/editors/read-only-editor-wrapper.tsx Added embedHandler prop and passed it to useReadOnlyEditor hook.
.../core/extensions/core/extensions.ts Added embedHandler to TCoreAdditionalExtensionsProps and passed it in CoreEditorAdditionalExtensions.
.../core/extensions/extensions.ts Added embedHandler to TArguments and passed it to CoreEditorAdditionalExtensions.
.../core/extensions/read-only-extensions.ts Added embedHandler to Props type for CoreReadOnlyEditorExtensions.
.../core/hooks/use-collaborative-editor.ts Passed embedHandler to useEditor hook inside useCollaborativeEditor.
.../core/hooks/use-editor.ts Added embedHandler prop and passed it to CoreEditorExtensions.
.../core/hooks/use-read-only-editor.ts Added embedHandler prop and passed it to CoreReadOnlyEditorExtensions.
space/core/components/editor/lite-text-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to LiteTextEditorWithRef.
space/core/components/editor/lite-text-read-only-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to LiteTextReadOnlyEditorWithRef.
space/core/components/editor/rich-text-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to RichTextEditorWithRef.
space/core/components/editor/rich-text-read-only-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to RichTextReadOnlyEditorWithRef.
packages/editor/src/core/types/issue-embed.ts Added externalEmbedComponent to TEmbedConfig and new type TExternalEmbedConfig.
web/ce/components/pages/version/editor.tsx Added external embed support to embedHandler prop in DocumentReadOnlyEditorWithRef.
web/next.config.js Changed HTTP header "X-Frame-Options" from "SAMEORIGIN" to "DENY".
web/core/components/editor/lite-text-editor/lite-text-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to LiteTextEditorWithRef.
web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to LiteTextReadOnlyEditorWithRef.
web/core/components/editor/rich-text-editor/rich-text-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to RichTextEditorWithRef.
web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx Added embedHandler support with EmbedHandler widget callback passed to RichTextReadOnlyEditor.

Sequence Diagram(s)

sequenceDiagram
    participant EditorContainer
    participant CollaborativeEditor
    participant ReadOnlyEditor
    participant PageRenderer
    participant BlockMenu

    EditorContainer->>CollaborativeEditor: Pass disabledExtensions
    EditorContainer->>ReadOnlyEditor: Pass disabledExtensions
    CollaborativeEditor->>PageRenderer: Pass disabledExtensions
    ReadOnlyEditor->>PageRenderer: Pass disabledExtensions
    PageRenderer->>BlockMenu: Pass disabledExtensions
Loading
sequenceDiagram
    participant Editor
    participant getExtensionStorage
    participant CustomLinkStorage

    Editor->>getExtensionStorage: Request storage for CORE_EXTENSIONS.CUSTOM_LINK
    getExtensionStorage-->>Editor: Return storage (may be undefined)
    Editor->>CustomLinkStorage: Access isBubbleMenuOpen (safely)
Loading

Suggested labels

🛠️refactor, 🌐frontend, ✍️editor, ready to merge

Suggested reviewers

  • Palanikannan1437
  • aaryan610

Poem

🐇 A hop, a skip, the editor grows,
With embeds and extensions in tidy rows.
Disabled or active, each plays a part,
Handlers and timeouts, a work of art.
CSS shines, types align,
In code’s green meadow, all things fine! 🌿✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • 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.
    • @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 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.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

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

@iam-vipin iam-vipin marked this pull request as ready for review June 20, 2025 11:17
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

🧹 Nitpick comments (3)
live/src/core/services/api.service.ts (1)

17-17: Good addition of request timeout, consider documenting the value choice.

Adding a timeout to prevent hanging requests is a solid improvement for the API service. The 20-second timeout is reasonable for most API operations.

Consider adding a comment explaining why 20 seconds was chosen, or potentially making this configurable via environment variables for different deployment scenarios.

+ // 20 second timeout to prevent hanging requests
  timeout: 20000,
web/ce/components/pages/editor/external-embed/embed-handler.tsx (1)

1-3: Add TODO comment for placeholder implementation.

The EmbedHandler component is currently a placeholder that accepts NodeViewProps but renders an empty <div>. Consider adding a TODO comment to clarify this is intentional and needs future implementation.

+// TODO: Implement embed handling logic
 export const EmbedHandler: React.FC<NodeViewProps> = () => <div />;
packages/editor/src/core/components/menus/block-menu.tsx (1)

11-11: Consider using the disabledExtensions prop or add TODO.

The disabledExtensions prop is added to the interface but not used in the component implementation. Either implement the logic to handle disabled extensions or add a TODO comment indicating future implementation plans.

 interface BlockMenuProps {
   editor: Editor;
+  // TODO: Implement logic to handle disabled extensions in menu items
   disabledExtensions?: TExtensions[];
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f26b4d3 and a435baa.

📒 Files selected for processing (16)
  • live/src/core/services/api.service.ts (1 hunks)
  • packages/editor/src/core/components/editors/document/collaborative-editor.tsx (1 hunks)
  • packages/editor/src/core/components/editors/document/page-renderer.tsx (3 hunks)
  • packages/editor/src/core/components/editors/document/read-only-editor.tsx (1 hunks)
  • packages/editor/src/core/components/editors/editor-container.tsx (1 hunks)
  • packages/editor/src/core/components/editors/link-view-container.tsx (4 hunks)
  • packages/editor/src/core/components/menus/block-menu.tsx (1 hunks)
  • packages/editor/src/core/extensions/custom-link/extension.tsx (1 hunks)
  • packages/editor/src/core/plugins/drag-handle.ts (1 hunks)
  • packages/editor/src/core/types/editor.ts (3 hunks)
  • packages/editor/src/core/types/extensions.ts (1 hunks)
  • packages/editor/src/core/types/hook.ts (2 hunks)
  • packages/editor/src/styles/drag-drop.css (2 hunks)
  • space/ce/components/editor/external-embed/embed-handler.tsx (1 hunks)
  • space/helpers/string.helper.ts (1 hunks)
  • web/ce/components/pages/editor/external-embed/embed-handler.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (16)
packages/editor/src/core/extensions/custom-link/extension.tsx (2)

82-82: LGTM: Clean addition of bubble menu state tracking.

The new isBubbleMenuOpen property follows consistent naming conventions and provides proper type safety for bubble menu state management.


258-258: LGTM: Proper initialization of new state property.

The initialization of isBubbleMenuOpen to false is appropriate and maintains consistency with the existing storage pattern.

packages/editor/src/core/components/editors/editor-container.tsx (1)

6-6: LGTM: Import path standardization.

The change from relative to absolute alias path improves consistency and maintainability of import statements across the codebase.

packages/editor/src/core/components/editors/document/collaborative-editor.tsx (1)

98-98: LGTM: Proper prop forwarding for extension control.

The disabledExtensions prop is correctly passed down to PageRenderer, maintaining the prop propagation chain for extension awareness across editor components.

packages/editor/src/core/components/menus/block-menu.tsx (1)

7-7: LGTM: Proper type import addition.

The import of TExtensions type supports the new disabledExtensions prop and follows proper import organization.

packages/editor/src/core/plugins/drag-handle.ts (1)

106-109: LGTM! Consistent filtering logic for embed elements.

The new filtering condition correctly prevents selection of child elements within .data-embed containers while allowing selection of the .data-embed elements themselves. This follows the same pattern as the existing table wrapper filtering and maintains consistent drag handle behavior.

packages/editor/src/core/types/extensions.ts (1)

1-8: LGTM! Clean type extension for external embed support.

The addition of "external-embed" to the TExtensions type union correctly enables type safety for the new extension throughout the codebase.

packages/editor/src/core/components/editors/document/read-only-editor.tsx (1)

67-67: LGTM! Consistent prop forwarding for extension management.

The addition of disabledExtensions={disabledExtensions} prop forwarding to PageRenderer maintains consistency with similar changes in other editor components and enables proper extension management throughout the component hierarchy.

packages/editor/src/core/components/editors/link-view-container.tsx (2)

23-23: LGTM! Safer extension storage access.

Replacing direct editor.storage.link access with getExtensionStorage(editor, CORE_EXTENSIONS.CUSTOM_LINK) utility function provides safer access to extension storage and follows defensive programming practices.


52-52: LGTM! Proper null safety with optional chaining.

The addition of optional chaining (?.) when accessing isBubbleMenuOpen prevents potential runtime errors if the extension storage is undefined, improving the robustness of the component.

Also applies to: 115-115

packages/editor/src/core/types/hook.ts (1)

26-26: LGTM! Consistent type extension for embed support.

The addition of "embedHandler" to both TEditorHookProps and TReadOnlyEditorHookProps maintains consistency with the editor interface changes and follows the existing pattern of picking properties from the respective editor interfaces.

Also applies to: 51-51

packages/editor/src/core/components/editors/document/page-renderer.tsx (1)

6-6: LGTM! Proper prop propagation for disabled extensions.

The implementation correctly:

  • Imports the required TExtensions type
  • Adds the disabledExtensions prop to the component interface
  • Destructures the prop in the component
  • Passes it down to the BlockMenu component

This follows React best practices for prop drilling and maintains type safety.

Also applies to: 16-16, 28-28, 43-43

space/helpers/string.helper.ts (1)

74-80: LGTM! Logical extension for embed content support.

The addition of "embed-component" and "div[data-embed]" to the allowed HTML tags appropriately extends the function to recognize embed content as valid non-empty content. The changes maintain backward compatibility while supporting the new embed functionality.

packages/editor/src/core/types/editor.ts (2)

49-51: LGTM! Proper extension of editor commands.

The addition of "external-embed" and "rich-card" to the TEditorCommands union type correctly extends the available editor commands while maintaining the existing structure.


132-132: LGTM! Consistent embedHandler property integration.

The embedHandler property is properly added as optional to IEditorProps and correctly included in the picked properties for IReadOnlyEditorProps. This maintains consistency across the editor interface hierarchy.

Also applies to: 163-163

packages/editor/src/styles/drag-drop.css (1)

39-39: LGTM! Consistent CSS integration for external embed components.

The addition of .node-externalEmbedComponent to both the exclusion selector (line 39) and the specific styling rules (line 66) maintains visual consistency with existing image node components. This ensures that external embed components receive the same drag-and-drop styling treatment as other media content.

Also applies to: 66-66

editorContainerClassName: string;
id: string;
tabIndex?: number;
disabledExtensions: TExtensions[];
Copy link
Member

Choose a reason for hiding this comment

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

Extend this from IEditorProps


interface BlockMenuProps {
editor: Editor;
disabledExtensions?: TExtensions[];
Copy link
Member

Choose a reason for hiding this comment

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

Extend the type here as well.

}

// Skip elements inside .data-embed
if (elem.closest(".data-embed") && !elem.matches(".data-embed")) {
Copy link
Member

Choose a reason for hiding this comment

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

Update the class name.

id: string;
initialValue: string;
mentionHandler: TMentionHandler;
embedHandler?: TEmbedConfig;
Copy link
Member

Choose a reason for hiding this comment

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

Update the types to define the embedHandler only once and extend for all other use cases.

interface EmbedHandlerProps extends NodeViewProps {
anchor?: string;
}
export const EmbedHandler: React.FC<EmbedHandlerProps> = () => <div />;
Copy link
Member

Choose a reason for hiding this comment

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

This component should return null.

"mention-component",
"image-component",
"embed-component",
`div[data-embed]`,
Copy link
Member

Choose a reason for hiding this comment

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

This is not needed, embed-component should be enough.

@@ -0,0 +1,3 @@
import { NodeViewProps } from "@tiptap/react";

export const EmbedHandler: React.FC<NodeViewProps> = () => <div />;
Copy link
Member

Choose a reason for hiding this comment

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

Make this component return null.

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: 2

🧹 Nitpick comments (4)
packages/editor/src/core/extensions/extensions.ts (1)

44-50: Consider removing redundant embedHandler declaration.

The embedHandler appears to be declared twice - once in the Pick type (line 50) and once in the extended object (line 54). This redundancy could be confusing.

Consider this approach to avoid duplication:

type TArguments = Pick<
  IEditorProps,
  | "disabledExtensions"
  | "flaggedExtensions"
  | "fileHandler"
  | "mentionHandler"
  | "placeholder"
  | "tabIndex"
  | "embedHandler"
> & {
  enableHistory: boolean;
  editable: boolean;
-  embedHandler?: TEmbedConfig;
};

The embedHandler from IEditorProps should already be optional, making the second declaration unnecessary.

Also applies to: 54-54

space/core/components/editor/rich-text-editor.tsx (1)

44-48: Consider extracting embed handler configuration for performance.

The inline object creation will cause the embedHandler prop to have a new reference on every render, potentially causing unnecessary re-renders of the underlying editor component.

Consider extracting the configuration using useMemo:

+import React, { forwardRef, useMemo } from "react";

export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProps>((props, ref) => {
  const { anchor, containerClassName, uploadFile, workspaceId, disabledExtensions, flaggedExtensions, ...rest } = props;
  const { getMemberById } = useMember();
+  
+  const embedHandler = useMemo(
+    () => ({
+      externalEmbedComponent: {
+        widgetCallback: (props: NodeViewProps) => <EmbedHandler anchor={anchor} {...props} />,
+      },
+    }),
+    [anchor]
+  );

  return (
    <RichTextEditorWithRef
      // ... other props
-      embedHandler={{
-        externalEmbedComponent: {
-          widgetCallback: (props: NodeViewProps) => <EmbedHandler anchor={anchor} {...props} />,
-        },
-      }}
+      embedHandler={embedHandler}
      // ... rest of props
    />
  );
});
space/core/components/editor/lite-text-read-only-editor.tsx (1)

26-28: Consider memoizing embed handler configuration.

The embedHandlerConfig is recreated on every render, which could cause unnecessary re-renders of the underlying editor component.

Apply this optimization using useMemo:

-import React from "react";
+import React, { useMemo } from "react";

export const LiteTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, LiteTextReadOnlyEditorWrapperProps>(
  ({ anchor, workspaceId, disabledExtensions, flaggedExtensions, ...props }, ref) => {
    const { getMemberById } = useMember();
-    const embedHandlerConfig = {
-      externalEmbedComponent: { widgetCallback: (props: NodeViewProps) => <EmbedHandler {...props} anchor={anchor} /> },
-    };
+    
+    const embedHandlerConfig = useMemo(
+      () => ({
+        externalEmbedComponent: { widgetCallback: (props: NodeViewProps) => <EmbedHandler {...props} anchor={anchor} /> },
+      }),
+      [anchor]
+    );
space/core/components/editor/rich-text-read-only-editor.tsx (1)

43-47: Consider memoizing embed handler for performance consistency.

Similar to the other components, the inline object creation causes a new reference on every render.

For consistency with the suggested optimization in other components:

+import React, { useMemo } from "react";

export const RichTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, RichTextReadOnlyEditorWrapperProps>(
  ({ anchor, workspaceId, disabledExtensions, flaggedExtensions, ...props }, ref) => {
    const { getMemberById } = useMember();
+
+    const embedHandler = useMemo(
+      () => ({
+        externalEmbedComponent: {
+          widgetCallback: (props: NodeViewProps) => <EmbedHandler anchor={anchor} {...props} />,
+        },
+      }),
+      [anchor]
+    );

    return (
      <RichTextReadOnlyEditorWithRef
        // ... other props
-        embedHandler={{
-          externalEmbedComponent: {
-            widgetCallback: (props: NodeViewProps) => <EmbedHandler anchor={anchor} {...props} />,
-          },
-        }}
+        embedHandler={embedHandler}
        // ... rest of props
      />
    );
  }
);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4e87603 and c2df565.

📒 Files selected for processing (16)
  • packages/editor/src/ce/extensions/core/extensions.ts (1 hunks)
  • packages/editor/src/ce/types/issue-embed.ts (1 hunks)
  • packages/editor/src/core/components/editors/editor-container.tsx (2 hunks)
  • packages/editor/src/core/components/editors/editor-wrapper.tsx (2 hunks)
  • packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx (2 hunks)
  • packages/editor/src/core/extensions/extensions.ts (3 hunks)
  • packages/editor/src/core/extensions/read-only-extensions.ts (1 hunks)
  • packages/editor/src/core/hooks/use-collaborative-editor.ts (1 hunks)
  • packages/editor/src/core/hooks/use-editor.ts (2 hunks)
  • packages/editor/src/core/hooks/use-read-only-editor.ts (2 hunks)
  • packages/editor/src/core/plugins/drag-handle.ts (2 hunks)
  • packages/editor/src/core/types/editor.ts (3 hunks)
  • space/core/components/editor/lite-text-editor.tsx (4 hunks)
  • space/core/components/editor/lite-text-read-only-editor.tsx (4 hunks)
  • space/core/components/editor/rich-text-editor.tsx (3 hunks)
  • space/core/components/editor/rich-text-read-only-editor.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/editor/src/core/components/editors/editor-container.tsx
  • packages/editor/src/core/plugins/drag-handle.ts
  • packages/editor/src/core/types/editor.ts
🔇 Additional comments (23)
packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx (1)

25-25: Clean prop propagation for embed handler support.

The addition of embedHandler prop follows the established pattern used by other handler props like mentionHandler and fileHandler. The implementation is clean and maintains backward compatibility.

Also applies to: 37-37

packages/editor/src/core/hooks/use-read-only-editor.ts (1)

28-28: Consistent integration of embed handler in read-only editor hook.

The embedHandler prop is properly integrated following the same pattern as existing handler props (mentionHandler, fileHandler). The implementation maintains consistency with the hook's established architecture.

Also applies to: 53-53

packages/editor/src/ce/extensions/core/extensions.ts (1)

7-7: Type-safe extension of core additional extensions props.

Adding "embedHandler" to the TCoreAdditionalExtensionsProps type ensures proper TypeScript support for the new prop while maintaining type safety throughout the extension system.

packages/editor/src/core/hooks/use-collaborative-editor.ts (1)

78-78: Completes embed handler integration in collaborative editor.

This change fixes the missing embedHandler prop forwarding to useEditor. The prop was already being destructured from the function parameters but wasn't being passed down, which this change properly addresses.

packages/editor/src/core/components/editors/editor-wrapper.tsx (1)

39-39: Consistent embed handler support across editor variants.

The embedHandler prop integration follows the same clean pattern established in other editor components, ensuring feature parity between editable and read-only editor variants.

Also applies to: 61-61

packages/editor/src/core/hooks/use-editor.ts (2)

39-39: LGTM: embedHandler prop added consistently.

The embedHandler prop is properly destructured and follows the same pattern as other handler props in the hook.


70-70: LGTM: embedHandler properly forwarded to extensions.

The embedHandler is correctly passed to CoreEditorExtensions, maintaining consistency with the existing prop forwarding pattern.

packages/editor/src/ce/types/issue-embed.ts (2)

1-2: LGTM: Proper import for NodeViewProps.

The import is correctly added to support the new type definition.


5-5: LGTM: Well-structured type definitions for external embed support.

The TExternalEmbedConfig type properly defines the interface for external embed components with a widgetCallback that follows Tiptap's NodeView pattern. The optional nature of externalEmbedComponent in TEmbedConfig is appropriate.

Also applies to: 8-9

packages/editor/src/core/extensions/extensions.ts (2)

40-40: LGTM: Proper import for TEmbedConfig type.

The import correctly adds the TEmbedConfig type needed for the embedHandler functionality.


66-66: LGTM: Proper implementation of embedHandler forwarding.

The embedHandler is correctly destructured and passed to CoreEditorAdditionalExtensions, following the established pattern for other handler props.

Also applies to: 196-197

space/core/components/editor/lite-text-editor.tsx (3)

3-3: LGTM: Proper imports for embed functionality.

The imports for NodeViewProps and EmbedHandler are correctly added to support the new embed functionality.

Also applies to: 12-12


16-16: LGTM: Proper interface design.

Correctly omitting embedHandler from the props interface since it's handled internally by the component. This maintains a clean API surface.


44-46: LGTM: Well-structured embed handler configuration.

The embedHandlerConfig is properly structured following the TExternalEmbedConfig interface. The widgetCallback correctly passes through NodeViewProps and includes the anchor prop for context. The configuration is appropriately passed to the editor component.

Also applies to: 62-62

space/core/components/editor/rich-text-editor.tsx (3)

3-3: LGTM: Proper import added for type safety.

The NodeViewProps import is correctly added to support the embed handler widget callback typing.


12-12: LGTM: EmbedHandler component import looks good.

The import path appears consistent with the overall architecture and the component is used appropriately in the embed handler configuration.


16-16: LGTM: Proper props interface refinement.

Adding embedHandler to the omitted props list is correct since it's now handled internally by the wrapper component.

space/core/components/editor/lite-text-read-only-editor.tsx (3)

3-3: LGTM: Consistent import pattern.

The NodeViewProps import is correctly added, maintaining consistency with other editor components.


13-13: LGTM: EmbedHandler import follows established pattern.

The import is consistent with the other editor components in this refactoring.


16-16: LGTM: Props interface properly updated.

Correctly omitting embedHandler from inherited props since it's handled internally.

space/core/components/editor/rich-text-read-only-editor.tsx (3)

3-3: LGTM: Import consistency maintained.

The NodeViewProps import maintains consistency across all refactored editor components.


13-13: LGTM: Consistent EmbedHandler integration.

The import follows the established pattern from the other editor components in this refactoring.


16-16: LGTM: Proper interface refinement.

Correctly omitting embedHandler from inherited props maintains the established pattern.

Comment on lines 36 to 39
type Props = Pick<
IReadOnlyEditorProps,
"disabledExtensions" | "flaggedExtensions" | "fileHandler" | "mentionHandler" | "embedHandler"
>;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Type update looks correct but implementation is incomplete.

The Props type correctly includes embedHandler, but the parameter is not being destructured or used in the CoreReadOnlyEditorExtensions function.

🤖 Prompt for AI Agents
In packages/editor/src/core/extensions/read-only-extensions.ts around lines 36
to 39, the Props type includes embedHandler but the CoreReadOnlyEditorExtensions
function does not destructure or use embedHandler from its parameters. Update
the function signature to destructure embedHandler from Props and ensure it is
properly utilized within the function implementation.

>;

export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler } = props;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add embedHandler to destructuring and pass it to extensions.

The embedHandler should be destructured from props and likely passed to CoreReadOnlyEditorAdditionalExtensions similar to how it's done in the main extensions file.

Apply this diff to fix the implementation:

-  const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler } = props;
+  const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler, embedHandler } = props;

And update the CoreReadOnlyEditorAdditionalExtensions call to include embedHandler:

    ...CoreReadOnlyEditorAdditionalExtensions({
      disabledExtensions,
      flaggedExtensions,
+     embedHandler,
    }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler } = props;
// Destructure embedHandler along with the other props
const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler, embedHandler } = props;
return createEditorExtensions([
// …other extensions…
...CoreReadOnlyEditorAdditionalExtensions({
disabledExtensions,
flaggedExtensions,
embedHandler,
}),
]);
🤖 Prompt for AI Agents
In packages/editor/src/core/extensions/read-only-extensions.ts at line 42, the
embedHandler is missing from the destructuring of props. Add embedHandler to the
destructuring assignment alongside disabledExtensions, fileHandler,
flaggedExtensions, and mentionHandler. Then, pass embedHandler as an argument to
the CoreReadOnlyEditorAdditionalExtensions call to ensure it is properly
included in the extensions.

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: 0

🧹 Nitpick comments (2)
web/core/components/pages/version/editor.tsx (1)

3-3: LGTM! Consistent implementation of external embed support.

The external embed handler integration follows a consistent pattern across the codebase. The imports and configuration are properly implemented.

Consider creating a shared utility function to reduce code duplication across editor components:

// utils/editor-embed-handler.ts
import { NodeViewProps } from "@tiptap/react";
import { EmbedHandler } from "@/plane-web/components/pages/editor/external-embed/embed-handler";

export const createEmbedHandlerConfig = () => ({
  externalEmbedComponent: { widgetCallback: (props: NodeViewProps) => <EmbedHandler {...props} /> },
});

This could be reused across all editor components to maintain consistency and reduce duplication.

Also applies to: 17-17, 121-121

web/core/components/editor/rich-text-editor/rich-text-editor.tsx (1)

3-3: LGTM! Completes consistent external embed integration across all editor types.

The rich text editor properly integrates the external embed handler, maintaining consistency with the refactoring pattern applied across all editor components. The embedHandler is correctly omitted from the wrapper props and configured appropriately.

This completes the external embed integration across all editor variants. Consider the shared utility function suggestion from the first file to reduce the code duplication across all these editor components.

Also applies to: 16-16, 20-20, 72-72

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c2df565 and 96071bf.

📒 Files selected for processing (6)
  • web/core/components/editor/lite-text-editor/lite-text-editor.tsx (4 hunks)
  • web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx (4 hunks)
  • web/core/components/editor/rich-text-editor/rich-text-editor.tsx (3 hunks)
  • web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx (2 hunks)
  • web/core/components/pages/version/editor.tsx (3 hunks)
  • web/next.config.js (1 hunks)
🔇 Additional comments (4)
web/next.config.js (1)

15-15: Good security hardening, but verify no breaking changes.

Changing X-Frame-Options from "SAMEORIGIN" to "DENY" strengthens security by preventing clickjacking attacks. This complements the editor embedding enhancements mentioned in the PR summary by allowing internal content embedding while preventing external framing of the entire application.

However, ensure this doesn't break any existing functionality where the application might have been embedded in same-origin iframes.

#!/bin/bash
# Description: Search for potential iframe usage or embedding references in the codebase
# Expected: Find any references to iframe embedding or frame-related functionality

echo "Searching for iframe usage and frame-related code..."
rg -i "iframe|frame|embed" --type js --type jsx --type ts --type tsx -A 2 -B 2

echo -e "\nSearching for X-Frame-Options references..."
rg -i "x-frame-options|frameOptions" -A 2 -B 2

echo -e "\nSearching for embedding-related documentation..."
fd -e md | xargs rg -i "embed|iframe|frame" -A 2 -B 2
web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx (1)

15-15: LGTM! Proper integration of embed handler in read-only editor.

The external embed handler is correctly integrated following the established pattern. The implementation maintains consistency with other editor components.

Also applies to: 18-18, 54-54

web/core/components/editor/lite-text-editor/lite-text-editor.tsx (1)

3-3: LGTM! Clean implementation with separate config object.

The implementation properly integrates the external embed handler. The approach of creating a separate embedHandlerConfig object improves readability compared to inline configuration.

Also applies to: 22-22, 27-27, 89-91, 120-120

web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx (1)

3-3: LGTM! Consistent implementation with clean config object pattern.

The read-only lite text editor properly integrates the external embed handler using the same clean config object approach as its editable counterpart. Good consistency across related components.

Also applies to: 16-16, 19-19, 36-38, 54-54

@@ -0,0 +1,6 @@
import { NodeViewProps } from "@tiptap/react";
Copy link
Member

Choose a reason for hiding this comment

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

please import it as { type NodeViewProps }

@iam-vipin iam-vipin changed the title chore: refactor editor chore: pass disabled and flagged extensions to block menu Aug 22, 2025
@iam-vipin iam-vipin changed the title chore: pass disabled and flagged extensions to block menu [WIKI-345] chore: pass disabled and flagged extensions to block menu Aug 22, 2025
@sriramveeraghanta sriramveeraghanta merged commit 0fe7da6 into preview Aug 25, 2025
5 of 7 checks passed
@sriramveeraghanta sriramveeraghanta deleted the chore-refactor_editor branch August 25, 2025 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants