openapi-explorer 2.4.812 → 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.
@@ -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
  /**
@@ -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
- document.execCommand('copy');
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
  /**
@@ -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
- document.execCommand('copy');
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.812",
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",