@@ -86,6 +86,26 @@ import ApiSortable from '@/components/form/api/ApiSortable.vue'
8686import { errorToMultiLineToast } from ' @/components/toast/toasts'
8787import StoryboardSortable from ' @/components/activity/content/storyboard/StoryboardSortable.vue'
8888
89+ // This is a very poorly implemented polyfill for crypto.randomUUID
90+ // which was generated by ChatGPT. It should under no circumstances
91+ // be used for security/cryptographic purposes. In this component it
92+ // serves the use case of generating unique identifiers for storyboard sections.
93+ // We only employ this polyfill here because there are apparently some users
94+ // with ancient Safari versions lacking support for randomUUID,
95+ // see https://caniuse.com/mdn-api_crypto_randomuuid
96+ const poorUuidPolyfill = function () {
97+ function randomDigit () {
98+ const random = (Math .random () * 16 ) | 0
99+ return random .toString (16 )
100+ }
101+
102+ return ' xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' .replace (/ [xy] / g , function (c ) {
103+ const r = randomDigit ()
104+ const v = c === ' x' ? r : (r & 0x3 ) | 0x8
105+ return v .toString (16 )
106+ })
107+ }
108+
89109export default {
90110 name: ' Storyboard' ,
91111 components: {
@@ -133,7 +153,10 @@ export default {
133153 async addSection () {
134154 this .isAdding = true
135155
136- const sectionId = self .crypto .randomUUID ()
156+ const sectionId =
157+ typeof self .crypto ? .randomUUID !== ' function'
158+ ? poorUuidPolyfill ()
159+ : self .crypto .randomUUID ()
137160 try {
138161 // TODO: consider adding item to ApiSortable eagerly (should be easy, now that uuid is generated locally)
139162 await this .contentNode .$patch ({
0 commit comments