Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/tip_tap/nodes/heading.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ class Heading < Node
self.type_name = "heading"
self.html_tag = proc { "h#{level}" }

def initialize(content = [], **attributes)
super(content, **attributes)
uuid = SecureRandom.uuid
@attrs["id"] = uuid
@attrs["data-toc-id"] = uuid
end

def text(text, marks: [])
add_content(Text.new(text, marks: marks))
end
Expand All @@ -16,6 +23,17 @@ def level
attrs["level"]
end

def html_attributes
# doc-toc-id comes from TipTap and Ruby symbols do not support -
# so we use string keys here instead.
{
"style" => inline_styles,
"class" => html_class_name,
"id" => attrs["id"],
"data-toc-id" => attrs["data-toc-id"]
}.reject { |key, value| value.blank? }
end

def to_markdown(context = Markdown::Context.root)
heading_level = [level.to_i, 1].max
prefix = "#" * heading_level
Expand Down
23 changes: 18 additions & 5 deletions spec/tip_tap/nodes/heading_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
require "tip_tap"

RSpec.describe TipTap::Nodes::Heading do
before do
allow(SecureRandom).to receive(:uuid).and_return("auto-uuid-999")
end

describe "to_html" do
it "returns a tag corresponding to the level attribute" do
it "returns a tag corresponding to the level attribute with auto-generated UUID" do
node = TipTap::Nodes::Heading.from_json({content: [], attrs: {level: 2}})
html = node.to_html

expect(html).to be_a(String)
expect(html).to eq("<h2></h2>")
expect(html).to eq('<h2 id="auto-uuid-999" data-toc-id="auto-uuid-999"></h2>')
end

context "when the textAlign attribute is present" do
Expand All @@ -18,18 +22,27 @@
html = node.to_html

expect(html).to be_a(String)
expect(html).to eq('<h2 style="text-align: center;"></h2>')
expect(html).to eq('<h2 style="text-align: center;" id="auto-uuid-999" data-toc-id="auto-uuid-999"></h2>')
end
end
end

describe "level" do
it "returns a the level attribute" do
it "returns the level attribute" do
node = TipTap::Nodes::Heading.from_json({content: [], attrs: {level: 2}})
expect(node.level).to eq(2)
end
end

describe "table of contents key" do
it "automatically generates and sets UUID in attrs" do
heading = TipTap::Nodes::Heading.new(level: 1)

expect(heading.attrs["id"]).to eq("auto-uuid-999")
expect(heading.attrs["data-toc-id"]).to eq("auto-uuid-999")
end
end

describe "text" do
it "adds a text node to the node" do
heading = TipTap::Nodes::Heading.new(level: 1)
Expand All @@ -44,7 +57,7 @@
node = TipTap::Nodes::Heading.new(level: 1)
json = node.to_h

expect(json).to eq({type: "heading", attrs: {level: 1}, content: []})
expect(json).to eq({type: "heading", attrs: {level: 1, id: "auto-uuid-999", "data-toc-id": "auto-uuid-999"}, content: []})
end
end
end
6 changes: 5 additions & 1 deletion spec/tip_tap_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
let(:json) { JSON.parse(File.read("spec/support/files/tiptap-state.json")) }
let(:document) { TipTap::Document.from_json(json) }

before do
allow(SecureRandom).to receive(:uuid).and_return("auto-uuid-999")
end

it "parses the json and returns the html" do
expect(document.to_html).to eq(
'<div class="tiptap-document"><h1>Site Summary Overview - <em>May 2nd 2023</em></h1><img src="https://img.companycam.com/5zVdNKWQ1hqPOD-IspzX3kMsodTPlv6n39kgerOGjc4/rs:fit:4032:4032/q:100/aHR0cHM6Ly9jb21w/YW55Y2FtLXBlbmRp/bmcuczMuYW1hem9u/YXdzLmNvbS82OTc5/YmFlZS03MzU5LTQy/OWYtYmFhYS0yMmVl/NDY1NWZhODUuanBn.jpg" /><p>This is a site visit summary that is being <strong>synthesized</strong> by <strong><em>Chad Wilken.</em></strong></p><p></p><ul class="task-list"><li class="task-item checked"><p>Todo 1</p></li><li class="task-item"><p><strong>Todo 2</strong></p></li><li class="task-item"><p><strong><em>Todo 3</em></strong></p></li></ul><p></p><h2>This is a heading 2</h2><h3>This is a heading 3</h3><p></p><ul class="bullet-list"><li class="list-item"><p>This is a bullet item</p></li><li class="list-item"><p><strong>This is </strong><em>another item</em></p></li></ul><p>Final paragraph.</p></div>'
"<div class=\"tiptap-document\"><h1 id=\"auto-uuid-999\" data-toc-id=\"auto-uuid-999\">Site Summary Overview - <em>May 2nd 2023</em></h1><img src=\"https://img.companycam.com/5zVdNKWQ1hqPOD-IspzX3kMsodTPlv6n39kgerOGjc4/rs:fit:4032:4032/q:100/aHR0cHM6Ly9jb21w/YW55Y2FtLXBlbmRp/bmcuczMuYW1hem9u/YXdzLmNvbS82OTc5/YmFlZS03MzU5LTQy/OWYtYmFhYS0yMmVl/NDY1NWZhODUuanBn.jpg\" /><p>This is a site visit summary that is being <strong>synthesized</strong> by <strong><em>Chad Wilken.</em></strong></p><p></p><ul class=\"task-list\"><li class=\"task-item checked\"><p>Todo 1</p></li><li class=\"task-item\"><p><strong>Todo 2</strong></p></li><li class=\"task-item\"><p><strong><em>Todo 3</em></strong></p></li></ul><p></p><h2 id=\"auto-uuid-999\" data-toc-id=\"auto-uuid-999\">This is a heading 2</h2><h3 id=\"auto-uuid-999\" data-toc-id=\"auto-uuid-999\">This is a heading 3</h3><p></p><ul class=\"bullet-list\"><li class=\"list-item\"><p>This is a bullet item</p></li><li class=\"list-item\"><p><strong>This is </strong><em>another item</em></p></li></ul><p>Final paragraph.</p></div>"
)
end

Expand Down
Loading