Skip to content

Commit 5e15597

Browse files
committed
code refactoring: improved code organization, performance and fixed certain edge cases
1 parent c5d5a74 commit 5e15597

11 files changed

+345
-330
lines changed

src/rapidoc.js

Lines changed: 143 additions & 128 deletions
Large diffs are not rendered by default.

src/templates/advance-search-template.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ export default function searchByPropertiesModalTemplate() {
4747
<div
4848
class="mono-font small-font-size hover-bg"
4949
style='padding: 5px; cursor: pointer; border-bottom: 1px solid var(--light-border-color); ${path.deprecated ? 'filter:opacity(0.5);' : ''}'
50-
data-content-id='${path.method}-${path.path}'
50+
data-content-id='${path.elementId}'
5151
tabindex = '0'
5252
@click="${
53-
() => {
53+
(e) => {
5454
this.matchPaths = ''; // clear quick filter if applied
5555
this.showAdvancedSearchDialog = false; // Hide Search Dialog
5656
this.requestUpdate();
57-
this.scrollTo(`${path.elementId}`);
57+
this.scrollToEventTarget(e, true);
5858
}
5959
}"
6060
>

src/templates/components-template.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,24 @@ import '@/components/schema-tree';
88
function componentBodyTemplate(sComponent) {
99
return html`
1010
<div class='divider'></div>
11-
<div class='expanded-endpoint-body observe-me ${sComponent.name}' id='cmp-${sComponent.id}' >
11+
<div class='expanded-endpoint-body observe-me ${sComponent.name}' id='cmp--${sComponent.id}' >
1212
${html`
1313
<h1> ${sComponent.name} </h1>
1414
${sComponent.component
1515
? html`
1616
<div class='mono-font regular-font-size' style='padding: 8px 0; color:var(--fg2)'>
17-
18-
<json-tree
19-
class="border tree"
20-
render-style='${this.renderStyle}'
21-
.data="${sComponent.component}"
22-
></json-tree>
23-
17+
<json-tree class="border tree" render-style='${this.renderStyle}' .data="${sComponent.component}"> </json-tree>
2418
</div>`
2519
: ''}
2620
`}
27-
2821
</div>
2922
`;
3023
}
3124

3225
export default function componentsTemplate() {
3326
return html`
3427
${this.resolvedSpec.components.map((component) => html`
35-
<div id="cmp-${component.name.toLowerCase()}" class='regular-font section-gap--read-mode observe-me' style="border-top:1px solid var(--primary-color);">
28+
<div id="cmp--${component.name.toLowerCase()}" class='regular-font section-gap--read-mode observe-me' style="border-top:1px solid var(--primary-color);">
3629
<div class="title tag">${component.name}</div>
3730
<div class="regular-font-size">
3831
${unsafeHTML(`<div class='m-markdown regular-font'>${marked(component.description ? component.description : '')}</div>`)}

src/templates/expanded-endpoint-template.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import '@/components/api-request';
99
import '@/components/api-response';
1010

1111
/* eslint-disable indent */
12-
1312
export function expandedEndpointBodyTemplate(path, tagName = '') {
1413
const acceptContentTypes = new Set();
1514
for (const respStatus in path.responses) {

src/templates/focused-endpoint-template.js

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,31 @@ import marked from 'marked';
44
import { expandedEndpointBodyTemplate } from '@/templates/expanded-endpoint-template';
55
import '@/components/api-request';
66
import '@/components/api-response';
7+
import componentsTemplate from '@/templates/components-template';
8+
import overviewTemplate from '@/templates/overview-template';
9+
import serverTemplate from '@/templates/server-template';
10+
import securitySchemeTemplate from '@/templates/security-scheme-template';
11+
import { expandCollapseNavBarTag } from '@/templates/navbar-template';
12+
13+
function wrapFocusedTemplate(templateToWrap) {
14+
return html`
15+
<div class='regular-font section-gap--focused-mode'>
16+
${templateToWrap};
17+
</div>`;
18+
}
19+
20+
function defaultContentTemplate() {
21+
// In focused mode default content is overview or first path
22+
if (this.showInfo === 'true') {
23+
return wrapFocusedTemplate(overviewTemplate.call(this));
24+
}
25+
const selectedTagObj = this.resolvedSpec.tags[0];
26+
const selectedPathObj = this.resolvedSpec.tags[0]?.paths[0];
27+
return (selectedTagObj && selectedPathObj)
28+
? wrapFocusedTemplate(expandedEndpointBodyTemplate.call(this, selectedPathObj, selectedTagObj.name))
29+
: wrapFocusedTemplate('');
30+
}
731

8-
/* eslint-disable indent */
932
function focusedTagBodyTemplate(tag) {
1033
return html`
1134
<h1 id="${tag.elementId}">${tag.name}</h1>
@@ -14,45 +37,46 @@ function focusedTagBodyTemplate(tag) {
1437
}
1538

1639
export default function focusedEndpointTemplate() {
17-
let itemToFocus = '';
18-
let selectedPathObj = {};
19-
let selectedTagObj = {};
20-
let i = 0;
21-
if (this.selectedContentId) {
22-
itemToFocus = this.selectedContentId;
23-
} else {
24-
itemToFocus = 'overview';
40+
if (!this.focusedElementId) {
41+
return;
2542
}
26-
if (itemToFocus === 'overview' || itemToFocus === 'authentication' || itemToFocus === 'api-servers') {
27-
selectedPathObj = {};
28-
selectedTagObj = {};
29-
} else if (itemToFocus.startsWith('tag--')) {
30-
selectedTagObj = this.resolvedSpec.tags.find((v) => v.elementId === itemToFocus);
43+
const focusElId = this.focusedElementId;
44+
let selectedPathObj = null;
45+
let selectedTagObj = null;
46+
let focusedTemplate;
47+
let i = 0;
48+
if (focusElId.startsWith('overview') && this.showInfo === 'true') {
49+
focusedTemplate = overviewTemplate.call(this);
50+
} else if (focusElId === 'auth' && this.allowAuthentication === 'true') {
51+
focusedTemplate = securitySchemeTemplate.call(this);
52+
} else if (focusElId === 'servers' && this.allowServerSelection === 'true') {
53+
focusedTemplate = serverTemplate.call(this);
54+
} else if (focusElId.startsWith('cmp--') && this.showComponents === 'true') {
55+
focusedTemplate = componentsTemplate.call(this);
56+
} else if (focusElId.startsWith('tag--')) {
57+
selectedTagObj = this.resolvedSpec.tags.find((v) => v.elementId === focusElId);
58+
if (selectedTagObj) {
59+
focusedTemplate = wrapFocusedTemplate.call(this, focusedTagBodyTemplate.call(this, selectedTagObj));
60+
} else {
61+
focusedTemplate = defaultContentTemplate.call(this);
62+
}
3163
} else {
3264
for (i = 0; i < this.resolvedSpec.tags.length; i += 1) {
3365
selectedTagObj = this.resolvedSpec.tags[i];
34-
selectedPathObj = this.resolvedSpec.tags[i].paths.find((v) => `${v.elementId}` === itemToFocus);
66+
selectedPathObj = this.resolvedSpec.tags[i].paths.find((v) => `${v.elementId}` === focusElId);
3567
if (selectedPathObj) {
3668
break;
3769
}
3870
}
39-
if (!selectedPathObj) {
40-
selectedTagObj = this.resolvedSpec.tags[0];
41-
selectedPathObj = this.resolvedSpec.tags[0]?.paths[0];
71+
if (selectedPathObj) {
72+
// In focused mode we must expand the nav-bar tag element if it is collapsed
73+
const newNavEl = this.shadowRoot.getElementById(`link-${focusElId}`);
74+
expandCollapseNavBarTag(newNavEl, 'expand');
75+
focusedTemplate = wrapFocusedTemplate.call(this, expandedEndpointBodyTemplate.call(this, selectedPathObj, selectedTagObj.name));
76+
} else {
77+
// if focusedElementId is not found then show the default content (overview or first-path)
78+
focusedTemplate = defaultContentTemplate.call(this);
4279
}
4380
}
44-
45-
return itemToFocus === 'overview' || itemToFocus === 'authentication' || itemToFocus === 'api-servers'
46-
? ''
47-
: itemToFocus.startsWith('tag--')
48-
? html`
49-
<div class='regular-font section-gap--focused-mode'>
50-
${focusedTagBodyTemplate.call(this, selectedTagObj)}
51-
</div>`
52-
: html`
53-
<div class='regular-font section-gap--focused-mode'>
54-
${expandedEndpointBodyTemplate.call(this, selectedPathObj, selectedTagObj.name)}
55-
</div>
56-
`;
81+
return focusedTemplate;
5782
}
58-
/* eslint-enable indent */

src/templates/main-body-template.js

Lines changed: 24 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,19 @@
11
import { html } from 'lit-element';
2-
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
3-
4-
import marked from 'marked';
52

63
// Templates
74
import expandedEndpointTemplate from '@/templates/expanded-endpoint-template';
85
import focusedEndpointTemplate from '@/templates/focused-endpoint-template';
6+
import overviewTemplate from '@/templates/overview-template';
97
import endpointTemplate from '@/templates/endpoint-template';
108
import serverTemplate from '@/templates/server-template';
119
import securitySchemeTemplate from '@/templates/security-scheme-template';
12-
import componentsTemplate from '@/templates/components-template';
1310
import headerTemplate from '@/templates/header-template';
1411
import navbarTemplate from '@/templates/navbar-template';
1512
import advancedSearchTemplate from '@/templates/advance-search-template';
1613

1714
import SetTheme from '@/utils/theme';
1815
import { isValidHexColor } from '@/utils/color-utils';
1916

20-
function infoDescriptionHeadingRenderer() {
21-
const renderer = new marked.Renderer();
22-
renderer.heading = ((text, level, raw, slugger) => `<h${level} class="observe-me" id="overview--${slugger.slug(raw)}">${text}</h${level}>`);
23-
return renderer;
24-
}
25-
26-
/* eslint-disable indent */
27-
28-
function overviewTemplate() {
29-
return html`
30-
<div id="overview" class="observe-me ${this.renderStyle === 'read' ? 'section-gap--read-mode' : (this.renderStyle === 'focused' ? 'section-gap--read-mode' : 'section-gap')}">
31-
<div id="api-title" style="font-size:32px">
32-
${this.resolvedSpec.info.title}
33-
${!this.resolvedSpec.info.version ? '' : html`
34-
<span style = 'font-size:var(--font-size-small);font-weight:bold'>
35-
${this.resolvedSpec.info.version}
36-
</span>`
37-
}
38-
</div>
39-
<div id="api-info" style="font-size:calc(var(--font-size-regular) - 1px); margin-top:8px;">
40-
${this.resolvedSpec.info.contact?.email
41-
? html`<span>${this.resolvedSpec.info.contact.name || 'Email'}:
42-
<a href="mailto:${this.resolvedSpec.info.contact.email}">${this.resolvedSpec.info.contact.email}</a>
43-
</span>`
44-
: ''
45-
}
46-
${this.resolvedSpec.info.contact?.url
47-
? html`<span>URL: <a href="${this.resolvedSpec.info.contact.url}">${this.resolvedSpec.info.contact.url}</a></span>`
48-
: ''
49-
}
50-
${this.resolvedSpec.info.license
51-
? html`<span>License:
52-
${this.resolvedSpec.info.license.url
53-
? html`<a href="${this.resolvedSpec.info.license.url}">${this.resolvedSpec.info.license.name}</a>`
54-
: this.resolvedSpec.info.license.name
55-
}</span>`
56-
: ''
57-
}
58-
${this.resolvedSpec.info.termsOfService
59-
? html`<span><a href="${this.resolvedSpec.info.termsOfService}">Terms of Service</a></span>`
60-
: ''
61-
}
62-
</div>
63-
<div id="api-description">
64-
${this.resolvedSpec.info.description
65-
? html`${unsafeHTML(`<div class="m-markdown regular-font">${marked(this.resolvedSpec.info.description, { renderer: infoDescriptionHeadingRenderer() })}</div>`)}`
66-
: ''
67-
}
68-
</div>
69-
</div>
70-
`;
71-
}
72-
7317
export default function mainBodyTemplate() {
7418
const newTheme = {
7519
bg1: isValidHexColor(this.bgColor) ? this.bgColor : '',
@@ -86,6 +30,7 @@ export default function mainBodyTemplate() {
8630
navAccentColor: isValidHexColor(this.navAccentColor) ? this.navAccentColor : '',
8731
};
8832

33+
/* eslint-disable indent */
8934
return html`
9035
${this.theme === 'dark' ? SetTheme.call(this, 'dark', newTheme) : SetTheme.call(this, 'light', newTheme)}
9136
@@ -107,48 +52,28 @@ export default function mainBodyTemplate() {
10752
<main class="main-content regular-font">
10853
<slot></slot>
10954
<div class="main-content-inner--${this.renderStyle}-mode">
110-
${this.loading === true ? html`<div class="loader"></div>` : ''}
111-
${this.loadFailed === true ? html`<div style="text-align: center;margin: 16px;"> Unable to load the Spec</div>` : ''}
112-
${this.resolvedSpec
113-
? html`
114-
${(this.showInfo === 'false' || !this.resolvedSpec.info)
115-
? ''
116-
: this.renderStyle === 'focused'
117-
? (this.selectedContentId === 'overview' ? overviewTemplate.call(this) : '')
118-
: overviewTemplate.call(this)
119-
}
120-
121-
${this.allowServerSelection === 'false'
122-
? ''
123-
: this.renderStyle === 'focused'
124-
? (this.selectedContentId === 'api-servers' ? serverTemplate.call(this) : '')
125-
: serverTemplate.call(this)
126-
}
127-
128-
${(this.allowAuthentication === 'false' || !this.resolvedSpec.securitySchemes)
129-
? ''
130-
: this.renderStyle === 'focused'
131-
? (this.selectedContentId === 'authentication' ? securitySchemeTemplate.call(this) : '')
132-
: securitySchemeTemplate.call(this)
133-
}
134-
<div class="operations-root" @click="${(e) => { this.handleHref(e); }}">
135-
${this.resolvedSpec.tags
136-
? this.renderStyle === 'read'
137-
? expandedEndpointTemplate.call(this)
138-
: this.renderStyle === 'focused'
139-
? this.selectedContentId.startsWith('cmp-')
140-
? componentsTemplate.call(this)
141-
: focusedEndpointTemplate.call(this)
142-
: endpointTemplate.call(this)
143-
: ''
144-
}
145-
</div>
146-
147-
${this.showComponents === 'true' && this.renderStyle !== 'focused'
148-
? componentsTemplate.call(this)
149-
: ''}
150-
`
151-
: ''
55+
${this.loading === true
56+
? html`<div class="loader"></div>`
57+
: html`
58+
${this.loadFailed === true
59+
? html`<div style="text-align: center;margin: 16px;"> Unable to load the Spec</div>`
60+
: html`
61+
<div class="operations-root" @click="${(e) => { this.handleHref(e); }}">
62+
${this.renderStyle === 'focused'
63+
? html`${focusedEndpointTemplate.call(this)}`
64+
: html`
65+
${this.showInfo === 'true' ? overviewTemplate.call(this) : ''}
66+
${this.allowServerSelection === 'true' ? serverTemplate.call(this) : ''}
67+
${this.allowAuthentication === 'true' ? securitySchemeTemplate.call(this) : ''}
68+
${this.renderStyle === 'read'
69+
? expandedEndpointTemplate.call(this)
70+
: endpointTemplate.call(this)
71+
}
72+
`
73+
}
74+
</div>
75+
`
76+
}`
15277
}
15378
</div>
15479
<slot name="footer"></slot>

0 commit comments

Comments
 (0)