@asd20/ui-next 2.18.0 → 2.20.0
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# [2.20.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.19.0...ui-next-v2.20.0) (2026-08-07)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* adjust video descriptions rendering for tiptap messages ([fbe3171](https://github.com/academydistrict20/asd20-ui-next/commit/fbe3171d365aeffeb7f66add00756ab9689f40a2))
|
|
9
|
+
|
|
10
|
+
# [2.19.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.18.0...ui-next-v2.19.0) (2026-08-06)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* add azure blob mp4 and myvrspot video urls for tiptap editor ([b7bc2e9](https://github.com/academydistrict20/asd20-ui-next/commit/b7bc2e94bf8502bb990bfb063c14b6631f981f80))
|
|
16
|
+
|
|
3
17
|
# [2.18.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.17.0...ui-next-v2.18.0) (2026-08-06)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
|
@@ -59,6 +59,10 @@ const MARK_TYPES = new Set([
|
|
|
59
59
|
const TABLE_HEADER_SCOPES = new Set(['col', 'row', 'colgroup', 'rowgroup'])
|
|
60
60
|
const VIDEO_TITLE_MAX_LENGTH = 200
|
|
61
61
|
const VIDEO_DESCRIPTION_MAX_LENGTH = 1000
|
|
62
|
+
const MYVRSPOT_VIDEO_ID_PATTERN = /^[A-Za-z0-9_-]{16,256}$/
|
|
63
|
+
const MYVRSPOT_HOST = 'live.myvrspot.com'
|
|
64
|
+
const ASD20_VIDEO_HOST = 'asd20websitestorage.blob.core.windows.net'
|
|
65
|
+
const ASD20_VIDEO_PATH_PREFIX = '/asd20-images/videos/'
|
|
62
66
|
const VIDEO_PROVIDER_RULES = Object.freeze([
|
|
63
67
|
{
|
|
64
68
|
host: 'www.youtube.com',
|
|
@@ -236,14 +240,36 @@ function isCanonicalVideoEmbedSource(value) {
|
|
|
236
240
|
url.username ||
|
|
237
241
|
url.password ||
|
|
238
242
|
url.port ||
|
|
239
|
-
url.search ||
|
|
240
243
|
url.hash
|
|
241
244
|
) {
|
|
242
245
|
return false
|
|
243
246
|
}
|
|
244
247
|
|
|
248
|
+
const host = url.hostname.toLowerCase()
|
|
249
|
+
if (host === MYVRSPOT_HOST) {
|
|
250
|
+
const videoId = url.searchParams.get('v') || ''
|
|
251
|
+
return (
|
|
252
|
+
url.pathname === '/iframe' &&
|
|
253
|
+
MYVRSPOT_VIDEO_ID_PATTERN.test(videoId) &&
|
|
254
|
+
url.searchParams.get('share') === '1' &&
|
|
255
|
+
[...url.searchParams].length === 2 &&
|
|
256
|
+
value === `https://${MYVRSPOT_HOST}/iframe?v=${videoId}&share=1`
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (host === ASD20_VIDEO_HOST) {
|
|
261
|
+
return (
|
|
262
|
+
!url.search &&
|
|
263
|
+
url.pathname.startsWith(ASD20_VIDEO_PATH_PREFIX) &&
|
|
264
|
+
url.pathname.toLowerCase().endsWith('.mp4') &&
|
|
265
|
+
value === `https://${ASD20_VIDEO_HOST}${url.pathname}`
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (url.search) return false
|
|
270
|
+
|
|
245
271
|
const rule = VIDEO_PROVIDER_RULES.find(
|
|
246
|
-
candidate => candidate.host ===
|
|
272
|
+
candidate => candidate.host === host
|
|
247
273
|
)
|
|
248
274
|
return Boolean(
|
|
249
275
|
rule &&
|
|
@@ -265,6 +291,16 @@ function validateRequiredCanonicalText(node, name, path, maximumLength) {
|
|
|
265
291
|
: null
|
|
266
292
|
}
|
|
267
293
|
|
|
294
|
+
function validateOptionalCanonicalText(node, name, path, maximumLength) {
|
|
295
|
+
const value = node.attrs?.[name]
|
|
296
|
+
if (value === undefined) return null
|
|
297
|
+
return typeof value !== 'string' ||
|
|
298
|
+
value !== value.trim() ||
|
|
299
|
+
value.length > maximumLength
|
|
300
|
+
? issue('malformed-attribute', path, name)
|
|
301
|
+
: null
|
|
302
|
+
}
|
|
303
|
+
|
|
268
304
|
function validateMarks(marks, path) {
|
|
269
305
|
if (marks === undefined) return null
|
|
270
306
|
if (!Array.isArray(marks)) return issue('malformed-marks', path)
|
|
@@ -505,7 +541,7 @@ function validateNode(node, path) {
|
|
|
505
541
|
VIDEO_TITLE_MAX_LENGTH
|
|
506
542
|
)
|
|
507
543
|
if (titleIssue) return titleIssue
|
|
508
|
-
const descriptionIssue =
|
|
544
|
+
const descriptionIssue = validateOptionalCanonicalText(
|
|
509
545
|
node,
|
|
510
546
|
'descriptiveText',
|
|
511
547
|
path,
|
|
@@ -783,15 +819,14 @@ function renderStandardNode(node) {
|
|
|
783
819
|
.join('')}</div></figure>`
|
|
784
820
|
}
|
|
785
821
|
if (node.type === 'videoEmbed') {
|
|
822
|
+
const description = node.attrs?.descriptiveText || ''
|
|
786
823
|
return `<div class="asd20-message-video" data-cc-node="video"${attribute(
|
|
787
824
|
'data-src',
|
|
788
825
|
node.attrs.src
|
|
789
826
|
)}${attribute('data-title', node.attrs.title)}${attribute(
|
|
790
827
|
'data-descriptive-text',
|
|
791
|
-
|
|
792
|
-
)}><
|
|
793
|
-
node.attrs.descriptiveText
|
|
794
|
-
)}</p><div class="asd20-message-video__frame"><iframe${attribute(
|
|
828
|
+
description
|
|
829
|
+
)}><div class="asd20-message-video__frame"><iframe${attribute(
|
|
795
830
|
'src',
|
|
796
831
|
node.attrs.src
|
|
797
832
|
)}${attribute(
|
|
@@ -801,7 +836,13 @@ function renderStandardNode(node) {
|
|
|
801
836
|
'allowfullscreen',
|
|
802
837
|
'',
|
|
803
838
|
true
|
|
804
|
-
)}></iframe></div
|
|
839
|
+
)}></iframe></div>${
|
|
840
|
+
description
|
|
841
|
+
? `<p class="asd20-message-video__description">${escapeHtml(
|
|
842
|
+
description
|
|
843
|
+
)}</p>`
|
|
844
|
+
: ''
|
|
845
|
+
}</div>`
|
|
805
846
|
}
|
|
806
847
|
if (node.type === 'table') return renderTable(node)
|
|
807
848
|
if (node.type === 'tableRow') return `<tr>${renderChildren(node)}</tr>`
|