Skip to content

Add Schema registry, Mark types, and declarative parent builders - #54

Open
chadwilken wants to merge 10 commits into
CompanyCam:masterfrom
chadwilken:schema-core
Open

chadwilken wants to merge 10 commits into
CompanyCam:masterfrom
chadwilken:schema-core

Conversation

@chadwilken

Copy link
Copy Markdown
Contributor

Description

Introduces a schema-centric registry while keeping the familiar Document.from_json / builder / to_* API.

  • TipTap::Schema — canonical store for node and mark type names → classes; Registry is a thin façade over TipTap.default_schema
  • First-class marks — built-in marks extracted from Text into TipTap::Mark subclasses registered on the default schema; custom marks via type_name= / register_mark
  • Declarative parent_builder — child nodes declare which parents get builder methods (no Document monkey-patches); adds hard_break / horizontal_rule builders
  • Unknown-node passthrough — opt-in via unknown_node: :passthrough on from_json (default still raises)
  • Heading TOC ids — preserve id / data-toc-id on parse; generate only when missing; opt out with generate_toc_ids: false
  • Docs — README custom-node guide and docs/schema.md updated for the default-schema extension path

Everything uses TipTap.default_schema (no per-document / isolated schemas). Custom nodes: set type_name= + parent_builder, require the file, then Document.from_json works as before.

Reason/Reference

Evolve the gem’s internals so extending TipTap with custom node and mark types is a first-class, documented path—without monkey-patching parents or editing Text—while preserving the public façade apps already depend on.

Phase 1 of a schema-centric redesign: Schema holds name→class
registrations; Registry becomes a thin façade over
TipTap.default_schema. Document/Node.from_json accept an optional
schema: keyword while preserving existing behavior for built-ins.
Phase 2: introduce TipTap::Mark and TipTap::Marks::* for bold, italic,
underline, strike, code, link, textStyle, superscript, subscript, and
highlight. Schema gains register_mark/mark_for; Text renders via the
node schema's mark registry. Builder API and built-in HTML/Markdown
output are unchanged.
Phase 3: node classes declare parent_builder to install builder methods
on allowed parents at registration time. Migrate Document, ListItem,
lists, tables, and related parents off duplicated hand-written builders.
Text#text / Codeblock#code remain special-cased.
Default remains MissingNodeError. Schema#unknown_node and
from_json(..., unknown_node:) accept :passthrough to preserve
unregistered types as TipTap::Nodes::Unknown for to_h round-trips,
recursively parsing nested known and unknown children.
Expose paragraph/heading#hard_break and document#horizontal_rule as
declarative leaf builders so registered types match the rest of the
parent_builder migration.
id and data-toc-id from JSON/attrs are no longer overwritten.
Missing values are still filled with a UUID by default; pass
generate_toc_ids: false on Heading.new or Document.from_json to skip.
Replace the Document monkey-patch extension guide with type_name,
parent_builder, and isolated schema examples; point to docs/schema.md
for marks and related options.
Schema no longer supports dup/clone. Docs, README, and specs now build
isolated schemas via TipTap::Schema.new.use(TipTap.default_schema).
Remove schema: from from_json/Text initialize. Custom nodes and marks
register on the default schema via type_name= (or register). Docs and
specs no longer describe Schema.new.use isolation.
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.

1 participant