Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add js-docs shortcode to ensure consistency between doc and js code #38316

Merged
merged 6 commits into from Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions js/src/util/sanitizer.js
Expand Up @@ -16,8 +16,6 @@ const uriAttributes = new Set([
'xlink:href'
])

const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i

/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
Expand Down Expand Up @@ -48,6 +46,9 @@ const allowedAttribute = (attribute, allowedAttributeList) => {
.some(regex => regex.test(attributeName))
}

// js-docs-start allow-list
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i

export const DefaultAllowlist = {
// Global attributes allowed on any supplied element below.
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
Expand Down Expand Up @@ -81,6 +82,7 @@ export const DefaultAllowlist = {
u: [],
ul: []
}
// js-docs-end allow-list

export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
if (!unsafeHtml.length) {
Expand Down
14 changes: 11 additions & 3 deletions site/assets/js/snippets.js
Expand Up @@ -60,6 +60,7 @@
})

// Instantiate all toasts in docs pages only
// js-docs-start live-toast
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')

Expand All @@ -69,14 +70,15 @@
toastBootstrap.show()
})
}
// js-docs-end live-toast

// -------------------------------
// Alerts
// -------------------------------
// Used in 'Show live toast' example in docs or StackBlitz
const alertPlaceholder = document.getElementById('liveAlertPlaceholder')
const alertTrigger = document.getElementById('liveAlertBtn')
// Used in 'Show live alert' example in docs or StackBlitz

// js-docs-start live-alert
const alertPlaceholder = document.getElementById('liveAlertPlaceholder')
const appendAlert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
Expand All @@ -89,11 +91,13 @@
alertPlaceholder.append(wrapper)
}

const alertTrigger = document.getElementById('liveAlertBtn')
if (alertTrigger) {
alertTrigger.addEventListener('click', () => {
appendAlert('Nice, you triggered this alert message!', 'success')
})
}
// js-docs-end live-alert

// --------
// Carousels
Expand Down Expand Up @@ -130,13 +134,16 @@
// Modal
// -------------------------------
// Modal 'Varying modal content' example in docs and StackBlitz
// js-docs-start varying-modal-content
const exampleModal = document.getElementById('exampleModal')
if (exampleModal) {
exampleModal.addEventListener('show.bs.modal', event => {
// Button that triggered the modal
const button = event.relatedTarget
// Extract info from data-bs-* attributes
const recipient = button.getAttribute('data-bs-whatever')
// If necessary, you could initiate an Ajax request here
// and then do the updating in a callback.

// Update the modal's content.
const modalTitle = exampleModal.querySelector('.modal-title')
Expand All @@ -146,6 +153,7 @@
modalBodyInput.value = recipient
})
}
// js-docs-end varying-modal-content

// -------------------------------
// Offcanvas
Expand Down
23 changes: 1 addition & 22 deletions site/content/docs/5.3/components/alerts.md
Expand Up @@ -38,28 +38,7 @@ Click the button below to show an alert (hidden with inline styles to start), th

We use the following JavaScript to trigger our live alert demo:

```js
const alertPlaceholder = document.getElementById('liveAlertPlaceholder')

const alert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
` <div>${message}</div>`,
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
'</div>'
].join('')

alertPlaceholder.append(wrapper)
}

const alertTrigger = document.getElementById('liveAlertBtn')
if (alertTrigger) {
alertTrigger.addEventListener('click', () => {
alert('Nice, you triggered this alert message!', 'success')
})
}
```
{{< js-docs name="live-alert" file="site/assets/js/snippets.js" >}}

### Link color

Expand Down
19 changes: 1 addition & 18 deletions site/content/docs/5.3/components/modal.md
Expand Up @@ -481,24 +481,7 @@ Below is a live demo followed by example HTML and JavaScript. For more informati
</div>
{{< /example >}}

```js
const exampleModal = document.getElementById('exampleModal')
exampleModal.addEventListener('show.bs.modal', event => {
// Button that triggered the modal
const button = event.relatedTarget
// Extract info from data-bs-* attributes
const recipient = button.getAttribute('data-bs-whatever')
// If necessary, you could initiate an Ajax request here
// and then do the updating in a callback.
//
// Update the modal's content.
const modalTitle = exampleModal.querySelector('.modal-title')
const modalBodyInput = exampleModal.querySelector('.modal-body input')

modalTitle.textContent = `New message to ${recipient}`
modalBodyInput.value = recipient
})
```
{{< js-docs name="varying-modal-content" file="site/assets/js/snippets.js" >}}

### Toggle between modals

Expand Down
12 changes: 1 addition & 11 deletions site/content/docs/5.3/components/toasts.md
Expand Up @@ -87,17 +87,7 @@ Click the button below to show a toast (positioned with our utilities in the low

We use the following JavaScript to trigger our live toast demo:

```js
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')

if (toastTrigger) {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastTrigger.addEventListener('click', () => {
toastBootstrap.show()
})
}
```
{{< js-docs name="live-toast" file="site/assets/js/snippets.js" >}}

### Translucent

Expand Down
37 changes: 1 addition & 36 deletions site/content/docs/5.3/getting-started/javascript.md
Expand Up @@ -231,42 +231,7 @@ Tooltips and Popovers use our built-in sanitizer to sanitize options which accep

The default `allowList` value is the following:

```js
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
const DefaultAllowlist = {
// Global attributes allowed on any supplied element below.
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
a: ['target', 'href', 'title', 'rel'],
area: [],
b: [],
br: [],
col: [],
code: [],
div: [],
em: [],
hr: [],
h1: [],
h2: [],
h3: [],
h4: [],
h5: [],
h6: [],
i: [],
img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
li: [],
ol: [],
p: [],
pre: [],
s: [],
small: [],
span: [],
sub: [],
sup: [],
strong: [],
u: [],
ul: []
}
```
{{< js-docs name="allow-list" file="js/src/util/sanitizer.js" >}}

If you want to add new values to this default `allowList` you can do the following:

Expand Down
37 changes: 37 additions & 0 deletions site/layouts/shortcodes/js-docs.html
@@ -0,0 +1,37 @@
{{- /*
Usage: `js-docs name="name" file="file/_location.js`

Prints everything between `// js-docs-start "name"` and `// js-docs-end "name"`
comments in the docs.
*/ -}}

{{- $name := .Get "name" -}}
{{- $file := .Get "file" -}}

{{- /* If any parameters are missing, print an error and exit */ -}}
{{- if or (not $name) (not $file) -}}
{{- errorf "%s: %q: Missing required parameters! Got: name=%q file=%q!" .Position .Name $name $file -}}
{{- else -}}
{{- $capture_start := printf "// js-docs-start %s\n" $name -}}
{{- $capture_end := printf "// js-docs-end %s" $name -}}
{{- $regex := printf `%s((?:.|\n)*)%s` $capture_start $capture_end -}}

{{- $match := findRE $regex (readFile $file) -}}
{{- $match = index $match 0 -}}

{{- if not $match -}}
{{- errorf "%s: %q: Got no matches for name=%q in file=%q!" .Position .Name $name $file -}}
{{- end -}}

{{- $match = replace $match $capture_start "" -}}
{{- $match = replace $match $capture_end "" -}}

<div class="bd-example-snippet bd-code-snippet">
<div class="bd-clipboard">
<button type="button" class="btn-clipboard" title="Copy to clipboard">
<svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg>
</button>
</div>
{{- highlight $match "js" "" -}}
</div>
{{- end -}}