Skip to content

Commit 96ba4f8

Browse files
authored
ROAD-539 Fix debounce of inputs' preview (#302)
1 parent ec32eed commit 96ba4f8

2 files changed

Lines changed: 106 additions & 76 deletions

File tree

app/assets/javascripts/stories.js

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
document.addEventListener("input", (e) => {
2-
const updateMarkdown = () => {
3-
document.querySelectorAll("[data-has-preview]").forEach((element) => {
4-
const form = element.closest("form");
5-
const preview = form.querySelector(
6-
"." + element.dataset.previewTarget + " .content"
7-
);
8-
if (preview) {
9-
Rails.ajax({
10-
type: "POST",
11-
url: "/stories/render_markdown",
12-
data: `markdown=${encodeURIComponent(element.value)}`,
13-
dataType: "text",
14-
success: (response) => {
15-
preview.innerHTML = response;
16-
},
17-
});
18-
}
19-
});
20-
};
1+
document.addEventListener("DOMContentLoaded", () => {
2+
document.querySelectorAll("[data-has-preview]").forEach((element) => {
3+
let debounceTimer;
4+
5+
element.addEventListener("input", (e) => {
6+
const updateMarkdown = () => {
7+
const form = element.closest("form");
8+
const preview = form.querySelector(
9+
"." + element.dataset.previewTarget + " .content"
10+
);
11+
if (preview) {
12+
Rails.ajax({
13+
type: "POST",
14+
url: "/stories/render_markdown",
15+
data: `markdown=${encodeURIComponent(element.value)}`,
16+
dataType: "text",
17+
success: (response) => {
18+
preview.innerHTML = response;
19+
},
20+
});
21+
}
22+
};
2123

22-
var debounceTimer;
23-
window.clearTimeout(debounceTimer);
24-
debounceTimer = window.setTimeout(updateMarkdown, 300);
24+
window.clearTimeout(debounceTimer);
25+
debounceTimer = window.setTimeout(updateMarkdown, 300);
26+
});
27+
});
2528
});

spec/features/stories_manage_spec.rb

Lines changed: 80 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -101,82 +101,109 @@
101101
expect(Story.count).to eq 1
102102
end
103103

104-
it "shows a preview of the description while typing", js: true do
105-
visit project_path(id: project.id)
106-
click_link "Add a Story"
107-
fill_in "story[title]", with: "As a user, I want to add stories"
104+
context "previews" do
105+
it "shows a preview of the description while typing", js: true do
106+
visit project_path(id: project.id)
107+
click_link "Add a Story"
108+
fill_in "story[title]", with: "As a user, I want to add stories"
108109

109-
desc = <<~DESC
110-
This story allows users to add stories.
110+
desc = <<~DESC
111+
This story allows users to add stories.
111112
112-
some
113-
code
113+
some
114+
code
114115
115-
DESC
116+
DESC
116117

117-
expect(page).to have_text("Description Preview")
118-
fill_in "story[description]", with: desc
119-
expect(find("#story_description").value).to have_text("This story allows users to add stories.\n\n some\n code\n\n")
118+
expect(page).to have_text("Description Preview")
119+
fill_in "story[description]", with: desc
120+
expect(find("#story_description").value).to have_text("This story allows users to add stories.\n\n some\n code\n\n")
120121

121-
within(".story_preview .content") do
122-
expect(page).to have_text("This story allows users to add stories.")
123-
expect(page).to have_selector("pre", text: "some\ncode")
124-
end
122+
within(".story_preview .content") do
123+
expect(page).to have_text("This story allows users to add stories.")
124+
expect(page).to have_selector("pre", text: "some\ncode")
125+
end
125126

126-
click_button "Create"
127+
click_button "Create"
127128

128-
expect(page).to have_text(project.title)
129+
expect(page).to have_text(project.title)
129130

130-
story = Story.last
131-
within_story_row(story) do
132-
click_button "More actions"
133-
click_link "Edit"
134-
end
131+
story = Story.last
132+
within_story_row(story) do
133+
click_button "More actions"
134+
click_link "Edit"
135+
end
135136

136-
expect(page).to have_text("Edit Story")
137+
expect(page).to have_text("Edit Story")
137138

138-
within(".story_preview .content") do
139-
expect(page).to have_text("This story allows users to add stories.")
140-
expect(page).to have_selector("pre", text: "some\ncode")
139+
within(".story_preview .content") do
140+
expect(page).to have_text("This story allows users to add stories.")
141+
expect(page).to have_selector("pre", text: "some\ncode")
142+
end
141143
end
142-
end
143144

144-
it "shows a preview of the extra information while typing" do
145-
visit project_path(id: project.id)
146-
click_link "Add a Story"
147-
fill_in "story[title]", with: "As a user, I want to add stories"
145+
it "shows a preview of the extra information while typing" do
146+
visit project_path(id: project.id)
147+
click_link "Add a Story"
148+
fill_in "story[title]", with: "As a user, I want to add stories"
148149

149-
desc = <<~DESC
150-
This story allows users to add extra information.
150+
desc = <<~DESC
151+
This story allows users to add extra information.
151152
152-
some
153-
codes
153+
some
154+
codes
154155
155-
DESC
156+
DESC
156157

157-
expect(page).to have_text("Extra Info Preview")
158-
fill_in "story[extra_info]", with: desc
158+
expect(page).to have_text("Extra Info Preview")
159+
fill_in "story[extra_info]", with: desc
159160

160-
within(".extra_info_preview .content") do
161-
expect(page).to have_selector("p", text: "This story allows users to add extra information.")
162-
expect(page).to have_selector("pre", text: "some\ncodes")
163-
end
161+
within(".extra_info_preview .content") do
162+
expect(page).to have_selector("p", text: "This story allows users to add extra information.")
163+
expect(page).to have_selector("pre", text: "some\ncodes")
164+
end
164165

165-
click_button "Create"
166+
click_button "Create"
166167

167-
expect(page).to have_text(project.title)
168+
expect(page).to have_text(project.title)
168169

169-
story = Story.last
170-
within_story_row(story) do
171-
click_button "More actions"
172-
click_link "Edit"
170+
story = Story.last
171+
within_story_row(story) do
172+
click_button "More actions"
173+
click_link "Edit"
174+
end
175+
176+
expect(page).to have_text("Edit Story")
177+
178+
within(".extra_info_preview .content") do
179+
expect(page).to have_selector("p", text: "This story allows users to add extra information.")
180+
expect(page).to have_selector("pre", text: "some\ncodes")
181+
end
173182
end
174183

175-
expect(page).to have_text("Edit Story")
184+
it "debounces the requests to update the preview to not flood the server" do
185+
renderer = double(:markdown_renderer)
186+
allow(renderer).to receive(:render).and_return("<span>preview</span>")
187+
allow(Redcarpet::Markdown).to receive(:new).and_return(renderer)
188+
189+
visit project_path(id: project.id)
190+
click_link "Add a Story"
191+
fill_in "story[title]", with: "As a user, I want to add stories"
192+
193+
fill_in "story[description]", with: "desc 1"
194+
fill_in "story[description]", with: "desc 2"
195+
fill_in "story[description]", with: "desc 3"
196+
197+
# wait until requests are triggered
198+
sleep(0.5)
199+
200+
fill_in "story[description]", with: "desc 4"
201+
sleep(0.5)
176202

177-
within(".extra_info_preview .content") do
178-
expect(page).to have_selector("p", text: "This story allows users to add extra information.")
179-
expect(page).to have_selector("pre", text: "some\ncodes")
203+
# twice for the initial render of the page (description and extra info)
204+
# once for the preview of the 3 consecutive inputs
205+
# once for the preview of the 4th input
206+
expect(renderer).to have_received(:render).exactly(4).times
180207
end
181208
end
182209

0 commit comments

Comments
 (0)