diff --git a/js/src/util/sanitizer.js b/js/src/util/sanitizer.js index af846a21e897..5a07a67c1a82 100644 --- a/js/src/util/sanitizer.js +++ b/js/src/util/sanitizer.js @@ -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. * @@ -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], @@ -81,6 +82,7 @@ export const DefaultAllowlist = { u: [], ul: [] } +// js-docs-end allow-list export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { if (!unsafeHtml.length) { diff --git a/site/assets/js/snippets.js b/site/assets/js/snippets.js index 95fce2da8511..66c7a005ce21 100644 --- a/site/assets/js/snippets.js +++ b/site/assets/js/snippets.js @@ -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') @@ -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 = [ @@ -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 @@ -130,6 +134,7 @@ // 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 => { @@ -137,6 +142,8 @@ 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') @@ -146,6 +153,7 @@ modalBodyInput.value = recipient }) } + // js-docs-end varying-modal-content // ------------------------------- // Offcanvas diff --git a/site/content/docs/5.3/components/alerts.md b/site/content/docs/5.3/components/alerts.md index 7ea5b9b42810..b6e78ea4285e 100644 --- a/site/content/docs/5.3/components/alerts.md +++ b/site/content/docs/5.3/components/alerts.md @@ -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 = [ - `' - ].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 diff --git a/site/content/docs/5.3/components/modal.md b/site/content/docs/5.3/components/modal.md index e723a49ce283..edd533ed71c2 100644 --- a/site/content/docs/5.3/components/modal.md +++ b/site/content/docs/5.3/components/modal.md @@ -481,24 +481,7 @@ Below is a live demo followed by example HTML and JavaScript. For more informati {{< /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 diff --git a/site/content/docs/5.3/components/toasts.md b/site/content/docs/5.3/components/toasts.md index d882fc04b521..a7d1cb7130e2 100644 --- a/site/content/docs/5.3/components/toasts.md +++ b/site/content/docs/5.3/components/toasts.md @@ -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 diff --git a/site/content/docs/5.3/getting-started/javascript.md b/site/content/docs/5.3/getting-started/javascript.md index 827cd2199e5a..739e9ef63ef3 100644 --- a/site/content/docs/5.3/getting-started/javascript.md +++ b/site/content/docs/5.3/getting-started/javascript.md @@ -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: diff --git a/site/layouts/shortcodes/js-docs.html b/site/layouts/shortcodes/js-docs.html new file mode 100644 index 000000000000..1a479db6789d --- /dev/null +++ b/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 "" -}} + +
+
+ +
+ {{- highlight $match "js" "" -}} +
+{{- end -}}