カスタムタグを含むHTMLの読み込みエラーを修正

basecamp/lexxy

LexxyでAction Textのアタッチメントタグ名をカスタマイズした際、HTMLが正しく読み込まれない問題が解消されました。これにより、Lexxy.configure でタグ名を変更しても、エディタの初期化が正常に動作するようになります。

背景

Lexxyは Lexxy.configure を通じて attachmentTagName などのグローバル設定をカスタマイズできる仕組みを提供しています。しかし、カスタム要素の登録とグローバル設定の適用の間に競合状態が存在し、設定が初期化より後に適用されてしまう問題がありました。

#564 で報告されたように、attachmentTagNameaction-text-attachment から bc-attachment に変更しても、エディタが古いタグ名で初期化されてしまい、カスタムタグを含むHTMLの読み込みに失敗していました。これは、インポート時に即座にカスタム要素が登録されるため、その後の Lexxy.configure 呼び出しが間に合わないという問題でした。

技術的な変更

カスタム要素の登録タイミングを遅延させることで、設定の適用を確実に先行させる実装に変更されました。

変更前:

各要素ファイルの末尾で即座に customElements.define を実行:

export default class LexicalEditorElement extends HTMLElement {
  // ...
}

customElements.define("lexxy-editor", LexicalEditorElement)

変更後:

要素定義を src/elements/index.js に集約し、setTimeout で遅延実行:

export function defineElements() {
  const elements = {
    "lexxy-toolbar": Toolbar,
    "lexxy-editor": Editor,
    "lexxy-link-dropdown": DropdownLink,
    "lexxy-highlight-dropdown": DropdownHighlight,
    "lexxy-prompt": Prompt,
    "lexxy-code-language-picker": CodeLanguagePicker,
    "lexxy-table-tools": TableTools,
  }

  Object.entries(elements).forEach(([name, element]) => {
    customElements.define(name, element)
  })
}
import { defineElements } from "./elements/index"
import Lexxy from "./config/lexxy"

// Pushing elements definition to after the current call stack to allow global configuration to take place first
setTimeout(defineElements, 0)

setTimeout(defineElements, 0) により、現在のコールスタックが完了した後にカスタム要素が登録されます。これにより、ユーザーコードで Lexxy.configure を同期的に呼び出せば、要素の初期化前に確実に設定が反映されます。

テストでは、カスタムタグ bc-attachment を含むHTMLの読み込みが正常に動作することが確認されています:

test "load attachment with custom tag" do
  visit new_post_path(attachment_tag_name: "bc-attachment")

  person = people(:james)

  find_editor.value = <<~HTML
  <div>Hello World <bc-attachment sgid="#{person.attachable_sgid}" content-type="#{person.content_type}" content="&quot;#{person.name}&quot;"></bc-attachment></div>
  HTML

  assert_editor_html do
    assert_selector "bc-attachment"
  end
end

設計判断

setTimeout による遅延実行 が採用されました。JavaScriptのイベントループの仕組みを活用し、マクロタスクキューに要素登録を配置することで、同期的なコールスタック(インポート文とその直後の Lexxy.configure 呼び出し)が完了してから初期化が実行されます。

この判断により、ユーザーは以下のような直感的な記述で設定をカスタマイズできます:

import Lexxy from "lexxy"

Lexxy.configure({
  attachmentTagName: "bc-attachment"
})

docs/configuration.md には、この制約が明記されました。Lexxy.configure はインポート文の直後に呼び出す必要があることが強調されています。遅延時間を0msに設定することで、実用上の影響を最小限に抑えながら、確実な初期化順序を保証しています。

本PRは、JavaScriptモジュールのロードタイミングとカスタム要素の登録タイミングの競合を、イベントループの制御によって解決した変更です。setTimeout による遅延実行という最小限の変更で、設定のカスタマイズ性と後方互換性の両立を実現しています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細(各論)→まとめ(結論)の3部構成が明確に守られており、非常に分かりやすい記事構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```言語:ファイルパス)や、PR・Issue番号のリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

JavaScriptのイベントループやカスタム要素に関する内容であり、専門知識を持つエンジニアという対象読者に適切です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているコード(`index.js`の追加、`editor.js`の変更、`load_html_test.rb`の追加など)は、提供されたDiff情報と正確に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「競合状態(race condition)」「イベントループ」「コールスタック」など、技術用語が正確かつ適切な文脈で使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

`setTimeout(..., 0)`がなぜ競合状態の解決策になるのか、イベントループの仕組みを用いて技術的に正確に説明できています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事で述べられている問題の背景、解決策、関連Issue(#564)は、すべてPRのDescriptionやDiff情報で裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#563)やIssue番号(#564)などの数値や固有名詞は正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「カスタムタグを含むHTMLの読み込みエラーを修正」は、PRのタイトル「Fix Loading HTML with Custom Tags」と一致しており、内容を的確に表しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容は提供されたPR情報に完全に準拠しており、バージョンサポート状況などの外部知識の追記はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

記事内には時間表現に関する記述は少なく、事実の前後関係に誤りはありません。