Skip to content

4.6.1#619

Merged
MakinoharaShoko merged 43 commits into
mainfrom
dev
Jun 6, 2026
Merged

4.6.1#619
MakinoharaShoko merged 43 commits into
mainfrom
dev

Conversation

@MakinoharaShoko

Copy link
Copy Markdown
Member

No description provided.

A-kirami and others added 30 commits April 7, 2026 08:20
…e-path

feat: 接入编辑器预览同步协议 V1 核心链路
# Conflicts:
#	packages/origine2/src/pages/editor/TextEditor/TextEditor.tsx
Memoize debounced submit and add cleanup
添加了韩文翻译
- Specify main contributor of Korean translation
- Fix Korean typo: change '커그텀' to '커스텀'
fix: update Korean translations and contributor info

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new @webgal/editor-preview-protocol package and refactors the editor-preview communication to use a structured client-host model. It also adds Korean language support, introduces a debug variables panel, optimizes graphical editor performance in long scenes using virtualized rendering, and adds several new graphical editing options. The code review feedback highlights several important improvements: adding guard checks to prevent type errors when target is undefined, securing postMessage target origins to prevent sensitive data leakage, robustly handling typed arrays during raw message normalization, avoiding React uncontrolled input warnings by providing fallbacks for unlockOrder.value, and replacing risky non-null assertions with safe fallbacks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +71 to +74
export async function SetFtoChangeF(target: string, scenePath: string, lineNumber: number): Promise<string> {
const sceneTXT = await GetSceneTXT(scenePath);
const lines = sceneTXT.split('\n').slice(0, lineNumber - 1).reverse();
const direction = target.replace('fig-', '');

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.

high

If target is undefined (e.g., when -target is missing in setTransform), calling target.replace('fig-', '') will throw a TypeError. It is safer to add a guard check at the beginning of SetFtoChangeF.

export async function SetFtoChangeF(target: string, scenePath: string, lineNumber: number): Promise<string> {
  if (!target) throw new Error('Target is undefined');
  const sceneTXT = await GetSceneTXT(scenePath);
  const lines = sceneTXT.split('\\n').slice(0, lineNumber - 1).reverse();
  const direction = target.replace('fig-', '');

}

ifRef.current.onload = () => setTimeout(() => WsUtil.sendFontOptimizationCommand(isUseFontOptimization), 1000);
iframeWindow.postMessage(createPreviewBootstrapProvide(embeddedLaunchIdRef.current), '*');

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.

security-medium medium

Using * as the target origin in postMessage allows any origin to receive the message if the iframe is redirected. It is safer to specify the target origin (e.g., window.location.origin) instead of * to prevent sensitive data (like embeddedLaunchId) from leaking.

Suggested change
iframeWindow.postMessage(createPreviewBootstrapProvide(embeddedLaunchIdRef.current), '*');
iframeWindow.postMessage(createPreviewBootstrapProvide(embeddedLaunchIdRef.current), window.location.origin);

Comment on lines +73 to +87
private normalizeRawMessage(rawData: RawData): string {
if (typeof rawData === 'string') {
return rawData;
}

if (Array.isArray(rawData)) {
return Buffer.concat(rawData).toString();
}

if (rawData instanceof ArrayBuffer) {
return Buffer.from(rawData).toString();
}

return rawData.toString();
}

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.

medium

If rawData is a typed array (like Uint8Array but not a Buffer), rawData.toString() will return a comma-separated string of numbers (e.g., "104,101,108,108,111") instead of the decoded string. Explicitly checking Buffer.isBuffer(rawData) and handling ArrayBuffer.isView(rawData) makes the decoding much more robust.

  private normalizeRawMessage(rawData: RawData): string {
    if (typeof rawData === 'string') {
      return rawData;
    }

    if (Buffer.isBuffer(rawData)) {
      return rawData.toString();
    }

    if (Array.isArray(rawData)) {
      return Buffer.concat(rawData).toString();
    }

    if (rawData instanceof ArrayBuffer) {
      return Buffer.from(rawData).toString();
    }

    if (ArrayBuffer.isView(rawData)) {
      return Buffer.from(rawData.buffer, rawData.byteOffset, rawData.byteLength).toString();
    }

    return rawData.toString();
  }

{!isNoFile && <CommonOptions key="3.2" title={t`鉴赏排序`}>
<input
type="number"
value={unlockOrder.value}

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.

medium

If unlockOrder.value is undefined (when order is not specified), passing it directly to value of an <input> makes it uncontrolled, which can trigger a React warning ("A component is changing an uncontrolled input to be controlled") when it later becomes defined. Falling back to "" prevents this.

Suggested change
value={unlockOrder.value}
value={unlockOrder.value ?? ""}

{unlockType.value === "unlockCg" && <CommonOptions title={t`鉴赏排序`}>
<input
type="number"
value={unlockOrder.value}

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.

medium

If unlockOrder.value is undefined (when order is not specified), passing it directly to value of an <input> makes it uncontrolled, which can trigger a React warning ("A component is changing an uncontrolled input to be controlled") when it later becomes defined. Falling back to "" prevents this.

Suggested change
value={unlockOrder.value}
value={unlockOrder.value ?? ""}

setPanel({ ...panel, options: { ...panel.options, [key]: value } });
eventBus.emit('editor:global-effect-editor-event', { editorId: panel.editorId, action: 'option', key, value, submit });
};
const options = panel.options!;

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.

medium

Using non-null assertion panel.options! is risky if options is undefined. It is safer to fallback to an empty object panel.options ?? {} to prevent potential runtime errors when checking keys.

Suggested change
const options = panel.options!;
const options = panel.options ?? {};

@MakinoharaShoko MakinoharaShoko merged commit 6573547 into main Jun 6, 2026
7 checks passed
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.

5 participants