openapi-explorer 2.4.801 → 2.4.820
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/openapi-explorer.min.js +2 -2
- package/dist/es/components/api-request.js +1 -1
- package/dist/es/components/api-response.js +1 -1
- package/dist/es/components/syntax-highlighter.js +8 -5
- package/dist/es/openapi-explorer.js +6 -1
- package/dist/es/templates/code-samples-template.js +1 -1
- package/dist/es/utils/common-utils.js +5 -10
- package/dist/lib/components/api-request.js +1 -1
- package/dist/lib/components/api-response.js +1 -1
- package/dist/lib/components/syntax-highlighter.js +8 -5
- package/dist/lib/openapi-explorer.js +6 -1
- package/dist/lib/templates/code-samples-template.js +1 -1
- package/dist/lib/utils/common-utils.js +5 -10
- package/package.json +1 -1
|
@@ -455,7 +455,7 @@ export default class ApiRequest extends LitElement {
|
|
|
455
455
|
return;
|
|
456
456
|
}
|
|
457
457
|
this.activeResponseTab = e.target.dataset.tab;
|
|
458
|
-
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${getI18nText('operations.request')}</button> ${!hasResponse ? '' : html` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${getI18nText('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${getI18nText('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? html` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? html`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? html`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : html` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}"> </div> </div>`;
|
|
458
|
+
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${getI18nText('operations.request')}</button> ${!hasResponse ? '' : html` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${getI18nText('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${getI18nText('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? html` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? html`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? html`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : html` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}" .label="${getI18nText('operations.response')}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}" .label="${getI18nText('operations.response-headers')}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}" .label="${getI18nText('operations.request')}"> </div> </div>`;
|
|
459
459
|
}
|
|
460
460
|
apiCallTemplate() {
|
|
461
461
|
return html` <div style="display:flex;align-items:flex-end;margin:16px 0;font-size:var(--font-size-small)"> ${this.parameters.length > 0 || this.request_body ? html` <button class="m-btn thin-border" part="btn btn-outline" style="margin-right:5px" @click="${this.onClearRequestData}"> ${getI18nText('operations.clear')} </button>` : ''} <button class="m-btn primary btn-execute thin-border" part="btn btn-fill btn-try" @click="${this.onTryClick}">${getI18nText('operations.execute')}</button> </div> ${this.apiResponseTabTemplate()} `;
|
|
@@ -160,7 +160,7 @@ export default class ApiResponse extends LitElement {
|
|
|
160
160
|
if (!mimeRespDetails) {
|
|
161
161
|
return html` <pre style="color:var(--red)" class="example-panel border-top"> No example provided </pre> `;
|
|
162
162
|
}
|
|
163
|
-
return html` ${mimeRespDetails.examples.length === 1 ? html` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}">` : html` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => html`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => html` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}"> </div> `)} </span> `} `;
|
|
163
|
+
return html` ${mimeRespDetails.examples.length === 1 ? html` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}" .label="${getI18nText('operations.response')}">` : html` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => html`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => html` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}" .label="${getI18nText('operations.response')}"> </div> `)} </span> `} `;
|
|
164
164
|
}
|
|
165
165
|
mimeSchemaTemplate(mimeRespDetails) {
|
|
166
166
|
if (!mimeRespDetails) {
|
|
@@ -42,6 +42,9 @@ class SyntaxHighlighter extends LitElement {
|
|
|
42
42
|
content: {
|
|
43
43
|
type: Object
|
|
44
44
|
},
|
|
45
|
+
label: {
|
|
46
|
+
type: String
|
|
47
|
+
},
|
|
45
48
|
language: {
|
|
46
49
|
type: String,
|
|
47
50
|
attribute: 'language'
|
|
@@ -53,7 +56,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
53
56
|
};
|
|
54
57
|
}
|
|
55
58
|
static finalizeStyles() {
|
|
56
|
-
return [PrismStyles, FontStyle, InputStyle, css`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}`];
|
|
59
|
+
return [PrismStyles, FontStyle, InputStyle, css`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}.toolbar-copy-btn~.sr-only{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;width:1px;overflow:hidden;position:absolute;white-space:nowrap}`];
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
/**
|
|
@@ -73,7 +76,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
73
76
|
return null;
|
|
74
77
|
}
|
|
75
78
|
render() {
|
|
76
|
-
return this.renderCopyWrapper(this.renderHighlight());
|
|
79
|
+
return this.renderCopyWrapper(this.renderHighlight(), this.label.toLowerCase());
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
/**
|
|
@@ -89,7 +92,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
89
92
|
}
|
|
90
93
|
const stringContent = ((_this$content = this.content) === null || _this$content === void 0 ? void 0 : _this$content.toString()) || '';
|
|
91
94
|
const increasedSpaceContent = lang !== 'python' && lang !== 'yaml' && lang !== 'toml' ? stringContent.split('\n').map(line => line.replace(/^\s{2}/g, ' ')).join('\n') : stringContent;
|
|
92
|
-
return grammar ? html`<pre><code>${unsafeHTML(Prism.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : html`<pre>${increasedSpaceContent}</pre>`;
|
|
95
|
+
return grammar ? html`<pre tabindex="0" role="region" aria-label="${this.label}"><code>${unsafeHTML(Prism.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : html`<pre tabindex="0" role="region" aria-label="${this.label}">${increasedSpaceContent}</pre>`;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
/**
|
|
@@ -97,8 +100,8 @@ class SyntaxHighlighter extends LitElement {
|
|
|
97
100
|
* @param {*} content Content
|
|
98
101
|
* @returns Content
|
|
99
102
|
*/
|
|
100
|
-
renderCopyWrapper(content) {
|
|
101
|
-
return html`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" part="btn btn-fill btn-copy">${getI18nText('operations.copy')}</button> ${content} </div>`;
|
|
103
|
+
renderCopyWrapper(content, label) {
|
|
104
|
+
return html`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" aria-label="${getI18nText('operations.copy')} ${label}" part="btn btn-fill btn-copy">${getI18nText('operations.copy')}</button> ${content} <div class="sr-only" aria-live="polite" role="status"></div> </div>`;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
/**
|
|
@@ -491,6 +491,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
491
491
|
behavior: 'auto',
|
|
492
492
|
block: 'start'
|
|
493
493
|
});
|
|
494
|
+
gotoEl.focus();
|
|
494
495
|
replaceState(tmpElementId);
|
|
495
496
|
}
|
|
496
497
|
}, isExpandingNeeded ? 150 : 0);
|
|
@@ -532,6 +533,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
532
533
|
behavior: 'auto',
|
|
533
534
|
block: 'start'
|
|
534
535
|
});
|
|
536
|
+
gotoEl.focus();
|
|
535
537
|
}
|
|
536
538
|
}
|
|
537
539
|
}
|
|
@@ -668,6 +670,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
668
670
|
behavior: 'auto',
|
|
669
671
|
block: 'start'
|
|
670
672
|
});
|
|
673
|
+
contentEl.focus();
|
|
671
674
|
|
|
672
675
|
// Update Location Hash
|
|
673
676
|
replaceState(elementId);
|
|
@@ -677,6 +680,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
677
680
|
behavior: 'auto',
|
|
678
681
|
block: 'start'
|
|
679
682
|
});
|
|
683
|
+
contentEl.focus();
|
|
680
684
|
|
|
681
685
|
// Update Location Hash
|
|
682
686
|
replaceState(elementId);
|
|
@@ -686,7 +690,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
686
690
|
behavior: 'auto',
|
|
687
691
|
block: 'start'
|
|
688
692
|
});
|
|
689
|
-
|
|
693
|
+
this.shadowRoot.getElementById('operations-root').focus();
|
|
690
694
|
// Update Location Hash
|
|
691
695
|
replaceState(elementId);
|
|
692
696
|
newNavEl = this.shadowRoot.getElementById(`link-${elementId}`);
|
|
@@ -718,6 +722,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
718
722
|
block: 'center'
|
|
719
723
|
}), 600);
|
|
720
724
|
}
|
|
725
|
+
newNavEl.focus();
|
|
721
726
|
}
|
|
722
727
|
await sleep(0);
|
|
723
728
|
const oldNavEl = this.shadowRoot.querySelector('.nav-bar-tag.active, .nav-bar-path.active, .nav-bar-info.active, .nav-bar-h1.active, .nav-bar-h2.active');
|
|
@@ -22,7 +22,7 @@ export default function codeSamplesTemplate(xCodeSamples) {
|
|
|
22
22
|
}).filter(l => typeof l !== 'undefined'));
|
|
23
23
|
const sanitizedSource = v.source.split('\n').map(s => s.substring(0, paddingToRemove).match(/^\s+$/) ? s.substring(paddingToRemove) : s);
|
|
24
24
|
const fullSource = sanitizedSource.join('\n');
|
|
25
|
-
return html` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}"> </div>`;
|
|
25
|
+
return html` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}" .label="${getI18nText('parameters.samples')}"> </div>`;
|
|
26
26
|
})} </div></section>`;
|
|
27
27
|
}
|
|
28
28
|
/* eslint-enable indent */
|
|
@@ -17,7 +17,8 @@ export const invalidCharsRegEx = new RegExp(/[\s#:?&={}-]+/, 'g'); // used for g
|
|
|
17
17
|
export function sleep(ms) {
|
|
18
18
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
19
19
|
}
|
|
20
|
-
export function copyToClipboard(copyData, eventTarget) {
|
|
20
|
+
export async function copyToClipboard(copyData, eventTarget) {
|
|
21
|
+
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
21
22
|
// In lots of places we have more than a couple of spaces for <pre> display purposes, we remove those extra spaces here.
|
|
22
23
|
let data = copyData === null || copyData === void 0 ? void 0 : copyData.trim().replace(/\s{8}/g, ' ');
|
|
23
24
|
try {
|
|
@@ -29,25 +30,19 @@ export function copyToClipboard(copyData, eventTarget) {
|
|
|
29
30
|
} catch (error) {
|
|
30
31
|
// Ignore non JSON text;
|
|
31
32
|
}
|
|
32
|
-
const textArea = document.createElement('textarea');
|
|
33
|
-
textArea.value = data;
|
|
34
|
-
textArea.style.position = 'fixed'; // avoid scrolling to bottom
|
|
35
|
-
document.body.appendChild(textArea);
|
|
36
|
-
textArea.focus();
|
|
37
|
-
textArea.select();
|
|
38
33
|
try {
|
|
39
|
-
|
|
40
|
-
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
34
|
+
await window.navigator.clipboard.writeText(data);
|
|
41
35
|
if (btnEl) {
|
|
42
36
|
btnEl.innerText = getI18nText('operations.copied');
|
|
37
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = getI18nText('operations.copied');
|
|
43
38
|
setTimeout(() => {
|
|
44
39
|
btnEl.innerText = getI18nText('operations.copy');
|
|
40
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = '';
|
|
45
41
|
}, 5000);
|
|
46
42
|
}
|
|
47
43
|
} catch (err) {
|
|
48
44
|
console.error('Unable to copy', err); // eslint-disable-line no-console
|
|
49
45
|
}
|
|
50
|
-
document.body.removeChild(textArea);
|
|
51
46
|
}
|
|
52
47
|
export function getBaseUrlFromUrl(url) {
|
|
53
48
|
const pathArray = url.split('/');
|
|
@@ -460,7 +460,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
460
460
|
return;
|
|
461
461
|
}
|
|
462
462
|
this.activeResponseTab = e.target.dataset.tab;
|
|
463
|
-
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${(0, _index.getI18nText)('operations.request')}</button> ${!hasResponse ? '' : (0, _lit.html)` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${(0, _index.getI18nText)('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${(0, _index.getI18nText)('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? (0, _lit.html)` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? (0, _lit.html)`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? (0, _lit.html)`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : (0, _lit.html)` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}"> </div> </div>`;
|
|
463
|
+
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${(0, _index.getI18nText)('operations.request')}</button> ${!hasResponse ? '' : (0, _lit.html)` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${(0, _index.getI18nText)('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${(0, _index.getI18nText)('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? (0, _lit.html)` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? (0, _lit.html)`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? (0, _lit.html)`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : (0, _lit.html)` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}" .label="${(0, _index.getI18nText)('operations.response')}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}" .label="${(0, _index.getI18nText)('operations.response-headers')}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}" .label="${(0, _index.getI18nText)('operations.request')}"> </div> </div>`;
|
|
464
464
|
}
|
|
465
465
|
apiCallTemplate() {
|
|
466
466
|
return (0, _lit.html)` <div style="display:flex;align-items:flex-end;margin:16px 0;font-size:var(--font-size-small)"> ${this.parameters.length > 0 || this.request_body ? (0, _lit.html)` <button class="m-btn thin-border" part="btn btn-outline" style="margin-right:5px" @click="${this.onClearRequestData}"> ${(0, _index.getI18nText)('operations.clear')} </button>` : ''} <button class="m-btn primary btn-execute thin-border" part="btn btn-fill btn-try" @click="${this.onTryClick}">${(0, _index.getI18nText)('operations.execute')}</button> </div> ${this.apiResponseTabTemplate()} `;
|
|
@@ -165,7 +165,7 @@ class ApiResponse extends _lit.LitElement {
|
|
|
165
165
|
if (!mimeRespDetails) {
|
|
166
166
|
return (0, _lit.html)` <pre style="color:var(--red)" class="example-panel border-top"> No example provided </pre> `;
|
|
167
167
|
}
|
|
168
|
-
return (0, _lit.html)` ${mimeRespDetails.examples.length === 1 ? (0, _lit.html)` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}">` : (0, _lit.html)` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => (0, _lit.html)`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => (0, _lit.html)` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}"> </div> `)} </span> `} `;
|
|
168
|
+
return (0, _lit.html)` ${mimeRespDetails.examples.length === 1 ? (0, _lit.html)` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}" .label="${(0, _index.getI18nText)('operations.response')}">` : (0, _lit.html)` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => (0, _lit.html)`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => (0, _lit.html)` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}" .label="${(0, _index.getI18nText)('operations.response')}"> </div> `)} </span> `} `;
|
|
169
169
|
}
|
|
170
170
|
mimeSchemaTemplate(mimeRespDetails) {
|
|
171
171
|
if (!mimeRespDetails) {
|
|
@@ -44,6 +44,9 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
44
44
|
content: {
|
|
45
45
|
type: Object
|
|
46
46
|
},
|
|
47
|
+
label: {
|
|
48
|
+
type: String
|
|
49
|
+
},
|
|
47
50
|
language: {
|
|
48
51
|
type: String,
|
|
49
52
|
attribute: 'language'
|
|
@@ -55,7 +58,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
55
58
|
};
|
|
56
59
|
}
|
|
57
60
|
static finalizeStyles() {
|
|
58
|
-
return [_prismStyles.default, _fontStyles.default, _inputStyles.default, (0, _lit.css)`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}`];
|
|
61
|
+
return [_prismStyles.default, _fontStyles.default, _inputStyles.default, (0, _lit.css)`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}.toolbar-copy-btn~.sr-only{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;width:1px;overflow:hidden;position:absolute;white-space:nowrap}`];
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
/**
|
|
@@ -75,7 +78,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
75
78
|
return null;
|
|
76
79
|
}
|
|
77
80
|
render() {
|
|
78
|
-
return this.renderCopyWrapper(this.renderHighlight());
|
|
81
|
+
return this.renderCopyWrapper(this.renderHighlight(), this.label.toLowerCase());
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
/**
|
|
@@ -91,7 +94,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
91
94
|
}
|
|
92
95
|
const stringContent = ((_this$content = this.content) === null || _this$content === void 0 ? void 0 : _this$content.toString()) || '';
|
|
93
96
|
const increasedSpaceContent = lang !== 'python' && lang !== 'yaml' && lang !== 'toml' ? stringContent.split('\n').map(line => line.replace(/^\s{2}/g, ' ')).join('\n') : stringContent;
|
|
94
|
-
return grammar ? (0, _lit.html)`<pre><code>${(0, _unsafeHtml.unsafeHTML)(_prismjs.default.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : (0, _lit.html)`<pre>${increasedSpaceContent}</pre>`;
|
|
97
|
+
return grammar ? (0, _lit.html)`<pre tabindex="0" role="region" aria-label="${this.label}"><code>${(0, _unsafeHtml.unsafeHTML)(_prismjs.default.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : (0, _lit.html)`<pre tabindex="0" role="region" aria-label="${this.label}">${increasedSpaceContent}</pre>`;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
/**
|
|
@@ -99,8 +102,8 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
99
102
|
* @param {*} content Content
|
|
100
103
|
* @returns Content
|
|
101
104
|
*/
|
|
102
|
-
renderCopyWrapper(content) {
|
|
103
|
-
return (0, _lit.html)`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" part="btn btn-fill btn-copy">${(0, _index.getI18nText)('operations.copy')}</button> ${content} </div>`;
|
|
105
|
+
renderCopyWrapper(content, label) {
|
|
106
|
+
return (0, _lit.html)`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" aria-label="${(0, _index.getI18nText)('operations.copy')} ${label}" part="btn btn-fill btn-copy">${(0, _index.getI18nText)('operations.copy')}</button> ${content} <div class="sr-only" aria-live="polite" role="status"></div> </div>`;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/**
|
|
@@ -497,6 +497,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
497
497
|
behavior: 'auto',
|
|
498
498
|
block: 'start'
|
|
499
499
|
});
|
|
500
|
+
gotoEl.focus();
|
|
500
501
|
(0, _commonUtils.replaceState)(tmpElementId);
|
|
501
502
|
}
|
|
502
503
|
}, isExpandingNeeded ? 150 : 0);
|
|
@@ -538,6 +539,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
538
539
|
behavior: 'auto',
|
|
539
540
|
block: 'start'
|
|
540
541
|
});
|
|
542
|
+
gotoEl.focus();
|
|
541
543
|
}
|
|
542
544
|
}
|
|
543
545
|
}
|
|
@@ -674,6 +676,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
674
676
|
behavior: 'auto',
|
|
675
677
|
block: 'start'
|
|
676
678
|
});
|
|
679
|
+
contentEl.focus();
|
|
677
680
|
|
|
678
681
|
// Update Location Hash
|
|
679
682
|
(0, _commonUtils.replaceState)(elementId);
|
|
@@ -683,6 +686,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
683
686
|
behavior: 'auto',
|
|
684
687
|
block: 'start'
|
|
685
688
|
});
|
|
689
|
+
contentEl.focus();
|
|
686
690
|
|
|
687
691
|
// Update Location Hash
|
|
688
692
|
(0, _commonUtils.replaceState)(elementId);
|
|
@@ -692,7 +696,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
692
696
|
behavior: 'auto',
|
|
693
697
|
block: 'start'
|
|
694
698
|
});
|
|
695
|
-
|
|
699
|
+
this.shadowRoot.getElementById('operations-root').focus();
|
|
696
700
|
// Update Location Hash
|
|
697
701
|
(0, _commonUtils.replaceState)(elementId);
|
|
698
702
|
newNavEl = this.shadowRoot.getElementById(`link-${elementId}`);
|
|
@@ -724,6 +728,7 @@ class OpenApiExplorer extends _lit.LitElement {
|
|
|
724
728
|
block: 'center'
|
|
725
729
|
}), 600);
|
|
726
730
|
}
|
|
731
|
+
newNavEl.focus();
|
|
727
732
|
}
|
|
728
733
|
await (0, _commonUtils.sleep)(0);
|
|
729
734
|
const oldNavEl = this.shadowRoot.querySelector('.nav-bar-tag.active, .nav-bar-path.active, .nav-bar-info.active, .nav-bar-h1.active, .nav-bar-h2.active');
|
|
@@ -25,7 +25,7 @@ function codeSamplesTemplate(xCodeSamples) {
|
|
|
25
25
|
}).filter(l => typeof l !== 'undefined'));
|
|
26
26
|
const sanitizedSource = v.source.split('\n').map(s => s.substring(0, paddingToRemove).match(/^\s+$/) ? s.substring(paddingToRemove) : s);
|
|
27
27
|
const fullSource = sanitizedSource.join('\n');
|
|
28
|
-
return (0, _lit.html)` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}"> </div>`;
|
|
28
|
+
return (0, _lit.html)` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}" .label="${(0, _index.getI18nText)('parameters.samples')}"> </div>`;
|
|
29
29
|
})} </div></section>`;
|
|
30
30
|
}
|
|
31
31
|
/* eslint-enable indent */
|
|
@@ -32,7 +32,8 @@ const invalidCharsRegEx = exports.invalidCharsRegEx = new RegExp(/[\s#:?&={}-]+/
|
|
|
32
32
|
function sleep(ms) {
|
|
33
33
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
34
34
|
}
|
|
35
|
-
function copyToClipboard(copyData, eventTarget) {
|
|
35
|
+
async function copyToClipboard(copyData, eventTarget) {
|
|
36
|
+
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
36
37
|
// In lots of places we have more than a couple of spaces for <pre> display purposes, we remove those extra spaces here.
|
|
37
38
|
let data = copyData === null || copyData === void 0 ? void 0 : copyData.trim().replace(/\s{8}/g, ' ');
|
|
38
39
|
try {
|
|
@@ -44,25 +45,19 @@ function copyToClipboard(copyData, eventTarget) {
|
|
|
44
45
|
} catch (error) {
|
|
45
46
|
// Ignore non JSON text;
|
|
46
47
|
}
|
|
47
|
-
const textArea = document.createElement('textarea');
|
|
48
|
-
textArea.value = data;
|
|
49
|
-
textArea.style.position = 'fixed'; // avoid scrolling to bottom
|
|
50
|
-
document.body.appendChild(textArea);
|
|
51
|
-
textArea.focus();
|
|
52
|
-
textArea.select();
|
|
53
48
|
try {
|
|
54
|
-
|
|
55
|
-
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
49
|
+
await window.navigator.clipboard.writeText(data);
|
|
56
50
|
if (btnEl) {
|
|
57
51
|
btnEl.innerText = (0, _index.getI18nText)('operations.copied');
|
|
52
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = (0, _index.getI18nText)('operations.copied');
|
|
58
53
|
setTimeout(() => {
|
|
59
54
|
btnEl.innerText = (0, _index.getI18nText)('operations.copy');
|
|
55
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = '';
|
|
60
56
|
}, 5000);
|
|
61
57
|
}
|
|
62
58
|
} catch (err) {
|
|
63
59
|
console.error('Unable to copy', err); // eslint-disable-line no-console
|
|
64
60
|
}
|
|
65
|
-
document.body.removeChild(textArea);
|
|
66
61
|
}
|
|
67
62
|
function getBaseUrlFromUrl(url) {
|
|
68
63
|
const pathArray = url.split('/');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-explorer",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.820",
|
|
4
4
|
"description": "OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console",
|
|
5
5
|
"author": "Authress Developers <developers@authress.io>",
|
|
6
6
|
"type": "module",
|