[260203] TIL

Today I Learned (2026-02-03)

iframe

  • ํ˜„์žฌ ์›น ํŽ˜์ด์ง€ ์•ˆ์— ๋‹ค๋ฅธ ์›น ํŽ˜์ด์ง€๋ฅผ ํ†ต์งธ๋กœ ๋ผ์›Œ ๋„ฃ๋Š” HTML ํƒœ๊ทธ

์ƒŒ๋“œ๋ฐ•์Šค

  • ์ฝ”๋“œ๊ฐ€ ์‚ฌ๊ณ  ์น˜์ง€ ๋ชปํ•˜๊ฒŒ ๊ฐ€๋‘ฌ๋†“์€ ์•ˆ์ „ ๊ตฌ์—ญ

ํ”ผ๊ทธ๋งˆ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ

  1. ํ”ผ๊ทธ๋งˆ์—์„œ ๋ณด๋‚ด์ฃผ๋Š” onmessage๋Š” data.pluginMessage ์•ˆ์— ์žˆ๋‹ค.
import type { SelectionPayload } from './types'

export type MessageType = 'SELECTION_CHANGED' | 'LOAD_SELECTION' | 'CANCEL'

export type MessagePayloadMap = {
  SELECTION_CHANGED: SelectionPayload
  LOAD_SELECTION: undefined
  CANCEL: undefined
}

export type MessagePayload = MessagePayloadMap[MessageType]

type Message = {
  type: MessageType
  payload?: MessagePayload
}

type EventHandler = (payload?: MessagePayload) => void

const eventHandlers = new Map<MessageType, EventHandler>()
let initialized = false

export function on(type: MessageType, handler: EventHandler): () => void {
  eventHandlers.set(type, handler)

  if (!initialized) {
    invokeEventHandler()
    initialized = true
  }

  return () => {
    eventHandlers.delete(type)
  }
}

export function send(type: MessageType, payload?: MessagePayload) {
  const message: Message = { type, payload }

  // UI Process
  if (typeof window !== 'undefined') {
    window.parent.postMessage({ pluginMessage: message }, '*')
    return
  }

  // Main Process
  figma.ui.postMessage(message)
}

function invokeEventHandler() {
  // UI Process
  if (typeof window !== 'undefined') {
    window.onmessage = (event: MessageEvent) => {
      const message = (event.data as { pluginMessage?: Message })?.pluginMessage
      if (!message) return

      const handler = eventHandlers.get(message.type)
      handler?.(message.payload)
    }
    return
  }

  // Main Process
  figma.ui.onmessage = (message: Message) => {
    const handler = eventHandlers.get(message.type)
    handler?.(message.payload)
  }
}

Categories:

Updated:

Leave a comment