Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Commit 225353f

Browse files
authored
Refactor: don't depend on underscore.js (#116)
This uses the DOM API to crate the elements instead of using templates from underscorejs. The html structure is exactly the same.
1 parent 5880a64 commit 225353f

File tree

3 files changed

+106
-96
lines changed

3 files changed

+106
-96
lines changed

docs/customization.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,14 @@ is given below for reference:
106106
<a href="/api-v2?highlight=api#section-1-sphinx-domain">
107107
<div class="outer_div_page_results" id="hit__3">
108108

109-
<!-- Domain role_name -->
109+
<!-- Domain name -->
110110
<span class="search__result__subheading">
111-
http:get
111+
/api/v2/section/
112+
113+
<!-- Domain role name -->
114+
<div class="search__domain_role_name">
115+
[http:get]
116+
</div>
112117
</span>
113118

114119
<!-- Domain Content -->

sphinx_search/static/js/rtd_sphinx_search.js

Lines changed: 98 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,46 @@ const debounce = (func, wait) => {
4242

4343

4444
/**
45-
* Wrapper around underscorejs's template function.
46-
*
47-
* This is to make it work with new and old versions.
48-
*/
49-
const render_template = (template, data) => {
50-
// pre-1.7 syntax from underscorejs.
51-
let result = $u.template(template, data);
52-
if (typeof result === 'function') {
53-
// New syntax.
54-
result = $u.template(template)(data);
45+
* Build a section with its matching results.
46+
*
47+
* A section has the form:
48+
*
49+
* <a href="{link}">
50+
* <div class="outer_div_page_results" id="{id}">
51+
* <span class="search__result__subheading">
52+
* {title}
53+
* </span>
54+
* <p class="search__result__content">
55+
* {contents[0]}
56+
* </p>
57+
* <p class="search__result__content">
58+
* {contents[1]}
59+
* </p>
60+
* ...
61+
* </div>
62+
* </a>
63+
*
64+
* @param {String} id.
65+
* @param {String} title.
66+
* @param {String} link.
67+
* @param {Array} contents.
68+
*/
69+
const buildSection = function (id, title, link, contents) {
70+
let span_element = createDomNode("span", {class: "search__result__subheading"});
71+
span_element.innerHTML = title;
72+
73+
let div_element = createDomNode("div", {class: "outer_div_page_results", id: id});
74+
div_element.appendChild(span_element);
75+
76+
for (var i = 0; i < contents.length; i += 1) {
77+
let p_element = createDomNode("p", {class: "search__result__content"});
78+
p_element.innerHTML = contents[i];
79+
div_element.appendChild(p_element);
5580
}
56-
return result;
81+
82+
let section = createDomNode("a", {href: link});
83+
section.appendChild(div_element);
84+
return section;
5785
};
5886

5987

@@ -105,8 +133,10 @@ const isModalVisible = () => {
105133
*/
106134
const createDomNode = (nodeName, attributes) => {
107135
let node = document.createElement(nodeName);
108-
for (let attr in attributes) {
109-
node.setAttribute(attr, attributes[attr]);
136+
if (attributes !== null) {
137+
for (let attr in attributes) {
138+
node.setAttribute(attr, attributes[attr]);
139+
}
110140
}
111141
return node;
112142
};
@@ -135,21 +165,6 @@ const _is_string = str => {
135165
* @param {Number} id to be used in for this section
136166
*/
137167
const get_section_html = (sectionData, page_link, id) => {
138-
let section_template =
139-
'<a href="<%= section_link %>"> \
140-
<div class="outer_div_page_results" id="<%= section_id %>"> \
141-
<span class="search__result__subheading"> \
142-
<%= section_subheading %> \
143-
</span> \
144-
<% for (var i = 0; i < section_content.length; ++i) { %> \
145-
<p class="search__result__content"> \
146-
<%= section_content[i] %> \
147-
</p> \
148-
<% } %>\
149-
</div> \
150-
</a> \
151-
<br class="br-for-hits">';
152-
153168
let section_subheading = sectionData.title;
154169
let highlights = sectionData.highlights;
155170
if (highlights.title.length) {
@@ -173,17 +188,8 @@ const get_section_html = (sectionData, page_link, id) => {
173188
}
174189

175190
let section_link = `${page_link}#${sectionData.id}`;
176-
177191
let section_id = "hit__" + id;
178-
179-
let section_html = render_template(section_template, {
180-
section_link: section_link,
181-
section_id: section_id,
182-
section_subheading: section_subheading,
183-
section_content: section_content
184-
});
185-
186-
return section_html;
192+
return buildSection(section_id, section_subheading, section_link, section_content);
187193
};
188194

189195
/**
@@ -195,20 +201,6 @@ const get_section_html = (sectionData, page_link, id) => {
195201
* @param {Number} id to be used in for this section
196202
*/
197203
const get_domain_html = (domainData, page_link, id) => {
198-
let domain_template =
199-
'<a href="<%= domain_link %>"> \
200-
<div class="outer_div_page_results" id="<%= domain_id %>"> \
201-
<span class="search__result__subheading"> \
202-
<%= domain_subheading %> \
203-
<div class="search__domain_role_name"> \
204-
<%= domain_role_name %> \
205-
</div> \
206-
</span> \
207-
<p class="search__result__content"><%= domain_content %></p> \
208-
</div> \
209-
</a> \
210-
<br class="br-for-hits">';
211-
212204
let domain_link = `${page_link}#${domainData.id}`;
213205
let domain_role_name = domainData.role;
214206
let domain_name = domainData.name;
@@ -224,37 +216,50 @@ const get_domain_html = (domainData, page_link, id) => {
224216
}
225217

226218
let domain_id = "hit__" + id;
227-
domain_role_name = "[" + domain_role_name + "]";
228-
229-
let domain_html = render_template(domain_template, {
230-
domain_link: domain_link,
231-
domain_id: domain_id,
232-
domain_content: domain_content,
233-
domain_subheading: domain_name,
234-
domain_role_name: domain_role_name
235-
});
236219

237-
return domain_html;
220+
let div_role_name = createDomNode("div", {class: "search__domain_role_name"});
221+
div_role_name.innerText = `[${domain_role_name}]`;
222+
domain_name += div_role_name.outerHTML;
223+
224+
return buildSection(
225+
domain_id,
226+
domain_name,
227+
domain_link,
228+
[domain_content]
229+
);
238230
};
239231

232+
240233
/**
241234
* Generate search results for a single page.
242235
*
236+
* This has the form:
237+
* <div>
238+
* <a href="{link}">
239+
* <h2 class="search__result__title">
240+
* {title}
241+
* <small class="rtd_ui_search_subtitle">{subtitle}</small>
242+
* <br/>
243+
* </h2>
244+
* </a>
245+
*
246+
* <a href="{link}">
247+
* {section}
248+
* </a>
249+
* <br class="br-for-hits" />
250+
*
251+
* <a href="{link}">
252+
* {section}
253+
* </a>
254+
* <br class="br-for-hits" />
255+
* </div>
256+
*
243257
* @param {Object} resultData search results of a page
244258
* @param {String} projectName
245259
* @param {Number} id from the last section
246260
* @return {Object} a <div> node with the results of a single page
247261
*/
248262
const generateSingleResult = (resultData, projectName, id) => {
249-
let content = createDomNode("div");
250-
251-
let page_link_template =
252-
'<a href="<%= page_link %>"> \
253-
<h2 class="search__result__title"> \
254-
<%= page_title %> \
255-
</h2> \
256-
</a>';
257-
258263
let page_link = resultData.path;
259264
let page_title = resultData.title;
260265
let highlights = resultData.highlights;
@@ -263,47 +268,47 @@ const generateSingleResult = (resultData, projectName, id) => {
263268
page_title = highlights.title[0];
264269
}
265270

266-
// if result is not from the same project,
267-
// then it must be from subproject.
271+
let h2_element = createDomNode("h2", {class: "search__result__title"});
272+
h2_element.innerHTML = page_title;
273+
274+
// If the result is not from the same project,
275+
// then it's from a subproject.
268276
if (projectName !== resultData.project) {
269-
page_title +=
270-
" " +
271-
render_template(
272-
'<small class="rtd_ui_search_subtitle"> \
273-
(from project <%= project %>) \
274-
</small>',
275-
{
276-
project: resultData.project
277-
}
278-
);
277+
let subtitle = createDomNode("small", {class: "rtd_ui_search_subtitle"});
278+
subtitle.innerText = `(from project ${resultData.project})`;
279+
h2_element.appendChild(subtitle);
279280
}
281+
h2_element.appendChild(createDomNode("br"))
280282

281-
page_title += "<br>";
283+
let a_element = createDomNode("a", {href: page_link});
284+
a_element.appendChild(h2_element);
282285

283-
content.innerHTML += render_template(page_link_template, {
284-
page_link: page_link,
285-
page_title: page_title
286-
});
286+
let content = createDomNode("div");
287+
content.appendChild(a_element);
287288

289+
let separator = createDomNode("br", {class: "br-for-hits"});
288290
for (let i = 0; i < resultData.blocks.length; ++i) {
289291
let block = resultData.blocks[i];
290-
let html_structure = "";
291-
292+
let section = null;
292293
id += 1;
293294
if (block.type === "section") {
294-
html_structure = get_section_html(
295+
section = get_section_html(
295296
block,
296297
page_link,
297298
id,
298299
);
299300
} else if (block.type === "domain") {
300-
html_structure = get_domain_html(
301+
section = get_domain_html(
301302
block,
302303
page_link,
303304
id,
304305
);
305306
}
306-
content.innerHTML += html_structure;
307+
308+
if (section !== null) {
309+
content.appendChild(section);
310+
content.appendChild(separator);
311+
}
307312
}
308313
return content;
309314
};

0 commit comments

Comments
 (0)