fcad-core-dragon 2.0.1 → 2.0.2-beta.2
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/.editorconfig +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +17 -1
- package/bk.scss +117 -117
- package/package.json +1 -1
- package/src/$locales/en.json +18 -4
- package/src/$locales/fr.json +17 -3
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +36 -341
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +16 -21
- package/src/components/AppBasePage.vue +45 -14
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppBaseSkeleton.vue +45 -0
- package/src/components/AppCompAudio.vue +12 -3
- package/src/components/AppCompButtonProgress.vue +13 -2
- package/src/components/AppCompCarousel.vue +12 -4
- package/src/components/AppCompInputCheckBoxNx.vue +324 -0
- package/src/components/AppCompInputDropdownNx.vue +295 -0
- package/src/components/AppCompInputRadioNx.vue +264 -0
- package/src/components/AppCompInputTextNx.vue +148 -0
- package/src/components/AppCompInputTextTableNx.vue +198 -0
- package/src/components/AppCompInputTextToFillDropdownNx.vue +291 -0
- package/src/components/AppCompInputTextToFillNx.vue +277 -0
- package/src/components/AppCompJauge.vue +11 -4
- package/src/components/AppCompMenu.vue +7 -14
- package/src/components/AppCompMenuItem.vue +7 -5
- package/src/components/AppCompNavigation.vue +21 -21
- package/src/components/AppCompNoteCall.vue +1 -0
- package/src/components/AppCompNoteCredit.vue +2 -1
- package/src/components/AppCompPlayBarNext.vue +94 -41
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompPopUpNext.vue +6 -6
- package/src/components/AppCompQuiz.vue +500 -0
- package/src/components/AppCompQuizRecall.vue +113 -66
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +39 -10
- package/src/components/AppCompVideoPlayer.vue +1 -1
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/composables/useQuiz.js +62 -179
- package/src/directives/nvdaFix.js +53 -0
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +227 -30
- package/src/mixins/$mediaMixins.js +1 -11
- package/src/module/stores/appStore.js +29 -11
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/group.js +26 -26
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/Statement/statementRef.js +23 -23
- package/src/module/xapi/Statement/substatement.js +22 -22
- package/src/module/xapi/Statement/verb.js +36 -36
- package/src/module/xapi/activitytypes.js +17 -17
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +14 -14
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/idb.js +1 -1
- package/src/plugins/save.js +37 -37
- package/src/plugins/scorm.js +287 -287
- package/src/plugins/xapi.js +11 -11
- package/src/public/index.html +33 -33
- package/src/shared/generalfuncs.js +134 -0
- package/src/shared/validators.js +308 -234
- package/src/components/AppCompInputCheckBoxNext.vue +0 -205
- package/src/components/AppCompInputDropdownNext.vue +0 -201
- package/src/components/AppCompInputRadioNext.vue +0 -158
- package/src/components/AppCompInputTextNext.vue +0 -124
- package/src/components/AppCompInputTextTableNext.vue +0 -142
- package/src/components/AppCompInputTextToFillDropdownNext.vue +0 -238
- package/src/components/AppCompInputTextToFillNext.vue +0 -171
- package/src/components/AppCompQuizNext.vue +0 -2908
|
@@ -11,19 +11,21 @@
|
|
|
11
11
|
<div v-if="error" id="sidebar-submenu" :class="{ isOpen: isOpened }">
|
|
12
12
|
<focus-trap :active="isOpened">
|
|
13
13
|
<div ref="target">
|
|
14
|
+
<!-- <div class="submenu-header"> -->
|
|
14
15
|
<app-base-button
|
|
15
16
|
id="close-toc"
|
|
16
17
|
class="btn-ghost"
|
|
17
18
|
:title="$t('button.closePopUp')"
|
|
18
19
|
@click="onCloseWidget('toc')"
|
|
19
20
|
>
|
|
20
|
-
<svg>
|
|
21
|
+
<svg aria-hidden="true" focusable="false">
|
|
21
22
|
<use href="#close-square-icon" />
|
|
22
23
|
</svg>
|
|
23
24
|
</app-base-button>
|
|
25
|
+
<!-- </div> -->
|
|
24
26
|
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
+
<!-- <div class="submenu-content"> -->
|
|
28
|
+
<p class="t-act" v-html="`${title}`"></p>
|
|
27
29
|
<div class="box-prog-act">
|
|
28
30
|
<p>
|
|
29
31
|
{{ $t('text.activity_progress') }}
|
|
@@ -46,19 +48,20 @@
|
|
|
46
48
|
<p class="anchor-t" v-html="anchor.title"></p>
|
|
47
49
|
<p class="state">
|
|
48
50
|
<span class="box-text">
|
|
49
|
-
<svg>
|
|
51
|
+
<svg aria-hidden="true" focusable="false">
|
|
50
52
|
<use href="#check-toc" />
|
|
51
53
|
</svg>
|
|
52
54
|
{{ $t('text.complete') }}
|
|
53
55
|
</span>
|
|
54
56
|
</p>
|
|
55
57
|
</div>
|
|
56
|
-
<svg>
|
|
58
|
+
<svg aria-hidden="true" focusable="false">
|
|
57
59
|
<use href="#chevronD-icon" />
|
|
58
60
|
</svg>
|
|
59
61
|
</div>
|
|
60
62
|
</RouterLink>
|
|
61
63
|
</div>
|
|
64
|
+
<!-- </div> -->
|
|
62
65
|
</div>
|
|
63
66
|
</focus-trap>
|
|
64
67
|
</div>
|
|
@@ -147,8 +150,25 @@ export default {
|
|
|
147
150
|
if (activity.charAt(1) == '0' || activity.charAt(1) == 0)
|
|
148
151
|
nb = activity.substr(2)
|
|
149
152
|
else nb = activity.substr(1)
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
//Format title in the Progress info
|
|
154
|
+
switch (nb) {
|
|
155
|
+
case '0':
|
|
156
|
+
this.title = menuInfo[activity].subTitle
|
|
157
|
+
? `Introduction : ${menuInfo[activity].subTitle}`
|
|
158
|
+
: `Introduction`
|
|
159
|
+
break
|
|
160
|
+
|
|
161
|
+
case '99':
|
|
162
|
+
this.title = menuInfo[activity].subTitle
|
|
163
|
+
? `Conclusion : ${menuInfo[activity].subTitle}`
|
|
164
|
+
: `Conclusion`
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
default:
|
|
168
|
+
this.title = menuInfo[activity].subTitle
|
|
169
|
+
? `${this.$t('text.activity')} ${nb} : ${menuInfo[activity].subTitle}`
|
|
170
|
+
: `${this.$t('text.activity')} ${nb}`
|
|
171
|
+
}
|
|
152
172
|
|
|
153
173
|
//create anchors title and path
|
|
154
174
|
if (menuInfo[activity] && menuInfo[activity].anchors) {
|
|
@@ -308,14 +328,19 @@ export default {
|
|
|
308
328
|
transition: left 0.5s ease-in-out;
|
|
309
329
|
|
|
310
330
|
&.isOpen {
|
|
311
|
-
display:
|
|
331
|
+
display: flex;
|
|
332
|
+
flex-direction: column;
|
|
312
333
|
}
|
|
313
334
|
|
|
335
|
+
// .sidebar-submenu-content {
|
|
336
|
+
// display: flex;
|
|
337
|
+
// flex-direction: column;
|
|
338
|
+
// }
|
|
314
339
|
#close-toc {
|
|
315
340
|
position: absolute;
|
|
316
341
|
right: 24px;
|
|
317
342
|
margin-bottom: 0;
|
|
318
|
-
padding:
|
|
343
|
+
padding: 12px;
|
|
319
344
|
width: 48px;
|
|
320
345
|
height: 48px;
|
|
321
346
|
display: flex;
|
|
@@ -374,7 +399,11 @@ export default {
|
|
|
374
399
|
}
|
|
375
400
|
&[done='true'] {
|
|
376
401
|
.state {
|
|
377
|
-
display:
|
|
402
|
+
display: flex;
|
|
403
|
+
align-items: center;
|
|
404
|
+
svg {
|
|
405
|
+
margin-right: 10px;
|
|
406
|
+
}
|
|
378
407
|
}
|
|
379
408
|
}
|
|
380
409
|
|
|
@@ -111,7 +111,7 @@ export default {
|
|
|
111
111
|
...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
|
|
112
112
|
//Return true if the video is loading (to show the loading display)
|
|
113
113
|
isLoading() {
|
|
114
|
-
if (!this.isSet
|
|
114
|
+
if (!this.isSet) return true
|
|
115
115
|
else return false
|
|
116
116
|
},
|
|
117
117
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<router-view />
|
|
3
|
-
</template>
|
|
4
|
-
<script>
|
|
5
|
-
export default {}
|
|
6
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<router-view />
|
|
3
|
+
</template>
|
|
4
|
+
<script>
|
|
5
|
+
export default {}
|
|
6
|
+
</script>
|
|
@@ -2,185 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import i18n from '@/i18n' //Must import directly the local from project app because vue-18in does not work in legacy mode with composable
|
|
4
4
|
|
|
5
|
-
export function useQuiz(
|
|
6
|
-
const { quizType, solution, showSolution, quizInputType } = quiz
|
|
5
|
+
export function useQuiz() {
|
|
7
6
|
const { t } = i18n.global
|
|
8
|
-
|
|
9
|
-
// /**
|
|
10
|
-
// * @param {String} inputId
|
|
11
|
-
// * @returns {Array} the class
|
|
12
|
-
// */
|
|
13
|
-
function classInput(inputId, optSelected = null) {
|
|
14
|
-
let theClass = []
|
|
15
|
-
|
|
16
|
-
switch (true) {
|
|
17
|
-
case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
|
|
18
|
-
if (inputId == quizInputType.value) {
|
|
19
|
-
theClass.push('reponseSelectionner')
|
|
20
|
-
}
|
|
21
|
-
break
|
|
22
|
-
|
|
23
|
-
case quizType.value == 'choix_mult':
|
|
24
|
-
if (containsValue(quizInputType.value, inputId)) {
|
|
25
|
-
theClass.push('reponseSelectionner')
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (showSolution.value) {
|
|
30
|
-
if (solution.value !== null) {
|
|
31
|
-
switch (true) {
|
|
32
|
-
case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
|
|
33
|
-
if (inputId == solution.value) {
|
|
34
|
-
theClass.push('correct_answer')
|
|
35
|
-
} else {
|
|
36
|
-
theClass.push('wrong_answer')
|
|
37
|
-
}
|
|
38
|
-
break
|
|
39
|
-
|
|
40
|
-
case quizType.value == 'choix_mult':
|
|
41
|
-
if (containsValue(solution.value, inputId)) {
|
|
42
|
-
theClass.push('correct_answer')
|
|
43
|
-
} else {
|
|
44
|
-
theClass.push('wrong_answer')
|
|
45
|
-
}
|
|
46
|
-
break
|
|
47
|
-
case quizType.value == 'dropdown':
|
|
48
|
-
if (!optSelected || !optSelected[inputId]) return
|
|
49
|
-
if (solution.value[inputId] == optSelected[inputId]) {
|
|
50
|
-
theClass.push('correct_answer')
|
|
51
|
-
} else {
|
|
52
|
-
theClass.push('wrong_answer')
|
|
53
|
-
}
|
|
54
|
-
break
|
|
55
|
-
|
|
56
|
-
case quizType.value == 'texte_troue_select':
|
|
57
|
-
if (typeof optSelected[inputId] !== 'undefined') {
|
|
58
|
-
if (
|
|
59
|
-
Object.values(solution.value[inputId])[0] ==
|
|
60
|
-
optSelected[inputId]
|
|
61
|
-
) {
|
|
62
|
-
theClass.push('correct_answer')
|
|
63
|
-
} else {
|
|
64
|
-
theClass.push('wrong_answer')
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
break
|
|
68
|
-
|
|
69
|
-
case quizType.value == 'texte_tableau':
|
|
70
|
-
if (
|
|
71
|
-
containsValue(
|
|
72
|
-
solution.value[inputId].reponse_value,
|
|
73
|
-
optSelected[inputId]
|
|
74
|
-
)
|
|
75
|
-
) {
|
|
76
|
-
theClass.push('correct_answer')
|
|
77
|
-
} else {
|
|
78
|
-
theClass.push('wrong_answer')
|
|
79
|
-
}
|
|
80
|
-
break
|
|
81
|
-
case quizType.value == 'texte_troue':
|
|
82
|
-
if (typeof optSelected[inputId] !== 'undefined') {
|
|
83
|
-
if (
|
|
84
|
-
containsValue(
|
|
85
|
-
Object.values(solution.value[inputId])[0],
|
|
86
|
-
optSelected[inputId]
|
|
87
|
-
)
|
|
88
|
-
) {
|
|
89
|
-
theClass.push('correct_answer')
|
|
90
|
-
} else {
|
|
91
|
-
theClass.push('wrong_answer')
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
break
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return theClass
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function messageAccessibility(inputId, optSelected = null) {
|
|
102
|
-
let mess = ''
|
|
103
|
-
if (showSolution.value) {
|
|
104
|
-
if (solution.value !== null) {
|
|
105
|
-
switch (true) {
|
|
106
|
-
case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
|
|
107
|
-
if (inputId == solution.value) {
|
|
108
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
109
|
-
} else {
|
|
110
|
-
mess = `${t('quizState.badAnswer')}`
|
|
111
|
-
}
|
|
112
|
-
break
|
|
113
|
-
|
|
114
|
-
case quizType.value == 'choix_mult':
|
|
115
|
-
if (containsValue(solution.value, inputId)) {
|
|
116
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
117
|
-
} else {
|
|
118
|
-
mess = `${t('quizState.badAnswer')}`
|
|
119
|
-
}
|
|
120
|
-
break
|
|
121
|
-
case quizType.value == 'dropdown':
|
|
122
|
-
if (solution[inputId.value] == optSelected[inputId.value]) {
|
|
123
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
124
|
-
} else {
|
|
125
|
-
mess = `${t('quizState.badAnswer')}`
|
|
126
|
-
}
|
|
127
|
-
break
|
|
128
|
-
|
|
129
|
-
case quizType.value == 'texte_troue_select':
|
|
130
|
-
if (typeof optSelected[inputId] !== 'undefined') {
|
|
131
|
-
if (
|
|
132
|
-
Object.values(solution.value[inputId])[0] ==
|
|
133
|
-
optSelected[inputId]
|
|
134
|
-
) {
|
|
135
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
136
|
-
} else {
|
|
137
|
-
mess = `${t('quizState.badAnswer')}`
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
break
|
|
141
|
-
|
|
142
|
-
case quizType.value == 'texte_tableau':
|
|
143
|
-
if (
|
|
144
|
-
containsValue(
|
|
145
|
-
solution.value[inputId].reponse_value,
|
|
146
|
-
optSelected[inputId]
|
|
147
|
-
)
|
|
148
|
-
) {
|
|
149
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
150
|
-
} else {
|
|
151
|
-
mess = `${t('quizState.badAnswer')}`
|
|
152
|
-
}
|
|
153
|
-
break
|
|
154
|
-
case quizType.value == 'texte_troue':
|
|
155
|
-
if (typeof optSelected[inputId] !== 'undefined') {
|
|
156
|
-
if (
|
|
157
|
-
containsValue(
|
|
158
|
-
Object.values(solution.value[inputId])[0],
|
|
159
|
-
optSelected[inputId]
|
|
160
|
-
)
|
|
161
|
-
) {
|
|
162
|
-
mess = `${t('quizState.goodAnswer')}`
|
|
163
|
-
} else {
|
|
164
|
-
mess = `${t('quizState.badAnswer')}`
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
break
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return mess
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* @description check if a values exists in a array
|
|
176
|
-
* @param {Array} array
|
|
177
|
-
* @param value
|
|
178
|
-
* @returns {Boolean}
|
|
179
|
-
*/
|
|
180
|
-
function containsValue(array, value) {
|
|
181
|
-
return array.includes(value)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
7
|
/**
|
|
185
8
|
* @description shuffles an array used to randomized the option order if shuffleAnswers is true
|
|
186
9
|
* @param {Array} array
|
|
@@ -201,6 +24,66 @@ export function useQuiz(quiz) {
|
|
|
201
24
|
}
|
|
202
25
|
return newArray2
|
|
203
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* @description add retro style to the quiz
|
|
29
|
+
* @param {Object} solution - the solution of the quiz
|
|
30
|
+
* @param {Array} reponse - the user response
|
|
31
|
+
* @param {Number} length - the length of the input value
|
|
32
|
+
* @returns {Object|Boolean}
|
|
33
|
+
*/
|
|
34
|
+
function addRetroStyle(solution, reponse, length) {
|
|
35
|
+
let classRetro = []
|
|
36
|
+
let mesA11y = []
|
|
37
|
+
if (solution != null) {
|
|
38
|
+
reponse.forEach((el) => {
|
|
39
|
+
if (el.correct == true) {
|
|
40
|
+
classRetro.push('goodAnswer')
|
|
41
|
+
mesA11y.push(`${t('quizState.goodAnswer')}`)
|
|
42
|
+
} else {
|
|
43
|
+
classRetro.push('badAnswer')
|
|
44
|
+
mesA11y.push(`${t('quizState.badAnswer')}`)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
} else {
|
|
48
|
+
classRetro.push('NeutralAnswer')
|
|
49
|
+
mesA11y.push(`${t('quizState.neutralAnswer')}`)
|
|
50
|
+
}
|
|
204
51
|
|
|
205
|
-
|
|
52
|
+
return { classRetro, mesA11y }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @description reset the list of validation style of a quiz
|
|
57
|
+
* @param {Array} aList - a list of array to reset
|
|
58
|
+
* @emits hide-retro - event message to hide the retro Message
|
|
59
|
+
* $el- the target quiz,
|
|
60
|
+
* false|true of th event
|
|
61
|
+
* */
|
|
62
|
+
function resetRetroStyle(aList) {
|
|
63
|
+
aList.forEach((a) => {
|
|
64
|
+
if (a && a.length > 0) a.splice(0)
|
|
65
|
+
})
|
|
66
|
+
this.$bus.$emit('hide-retro', this.$el, false)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function retroType(solution, reponse) {
|
|
70
|
+
if (solution != null) {
|
|
71
|
+
if (reponse.length == solution.length) {
|
|
72
|
+
let Ag = (i) => i.correct
|
|
73
|
+
if (reponse.every(Ag)) return 'retro_positive'
|
|
74
|
+
else return 'retro_negative'
|
|
75
|
+
} else {
|
|
76
|
+
return 'retro_negative'
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
return `retro_neutre`
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
addRetroStyle,
|
|
85
|
+
resetRetroStyle,
|
|
86
|
+
retroType,
|
|
87
|
+
shuffleArray
|
|
88
|
+
}
|
|
206
89
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file nvdaFix.js
|
|
3
|
+
* @description Directive to fix NVDA screen reader issues with Vuetify dropdowns.
|
|
4
|
+
* This directive hides the input field from screen readers and provides an aria-live region
|
|
5
|
+
* to announce the selected option.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <v-select v-nvda-fix="selectedOptionText" ...>
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
mounted(el, binding) {
|
|
13
|
+
// 1. Hide Vuetify input by adding aria-hidden="true"
|
|
14
|
+
const input = el.querySelector('input[type="text"]')
|
|
15
|
+
if (input) {
|
|
16
|
+
input.setAttribute('aria-hidden', 'true')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 2. Create/update aria-live for screen reader
|
|
20
|
+
const valueText =
|
|
21
|
+
binding && binding.value ? binding.value : 'choisir une option'
|
|
22
|
+
let liveRegion = el.querySelector('.nvda-live-region')
|
|
23
|
+
|
|
24
|
+
if (!liveRegion) {
|
|
25
|
+
liveRegion = document.createElement('div')
|
|
26
|
+
liveRegion.className = 'nvda-live-region sr-only'
|
|
27
|
+
liveRegion.setAttribute('aria-live', 'polite')
|
|
28
|
+
el.appendChild(liveRegion)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
liveRegion.textContent = `🍍${valueText}`
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* @description Directive updated hook to handle changes in the selected option.
|
|
35
|
+
* This updates the aria-live region with the new selected option text.
|
|
36
|
+
* @param {Object} el - The element the directive is bound to.
|
|
37
|
+
* @param {Object} binding - The binding object containing the new value.
|
|
38
|
+
*/
|
|
39
|
+
updated(el, binding) {
|
|
40
|
+
// update aria-live when selected option changes
|
|
41
|
+
const valueText = binding.value?.text || ''
|
|
42
|
+
const input = el.querySelector('input[type="text"]')
|
|
43
|
+
const liveRegion = el.querySelector('.nvda-live-region')
|
|
44
|
+
|
|
45
|
+
if (input) {
|
|
46
|
+
input.setAttribute('aria-hidden', 'true')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (liveRegion) {
|
|
50
|
+
liveRegion.textContent = `🍍${valueText}`
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<app-base-module :module-config="$data" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
<script>
|
|
6
|
-
export default {
|
|
7
|
-
data() {
|
|
8
|
-
return {
|
|
9
|
-
id: 'module_99',
|
|
10
|
-
consigneBehavior: 'onHover', //Controle the behavior of desplaying instruction
|
|
11
|
-
bookmarkActive: true, // Controle the use of saved point
|
|
12
|
-
allowNavigationToActivity: null
|
|
13
|
-
|
|
14
|
-
//main:''// Edit to define the ID of the node that will be main. When skipping to main content in the page.
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
created() {
|
|
18
|
-
this.allowNavigationToActivity =
|
|
19
|
-
this.$helper.getSettingsFromStore('auto_next_activity')
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<app-base-module :module-config="$data" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
export default {
|
|
7
|
+
data() {
|
|
8
|
+
return {
|
|
9
|
+
id: 'module_99',
|
|
10
|
+
consigneBehavior: 'onHover', //Controle the behavior of desplaying instruction
|
|
11
|
+
bookmarkActive: true, // Controle the use of saved point
|
|
12
|
+
allowNavigationToActivity: null
|
|
13
|
+
|
|
14
|
+
//main:''// Edit to define the ID of the node that will be main. When skipping to main content in the page.
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
created() {
|
|
18
|
+
this.allowNavigationToActivity =
|
|
19
|
+
this.$helper.getSettingsFromStore('auto_next_activity')
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<app-comp-menu></app-comp-menu>
|
|
4
|
-
<!-- <h6>normal</h6>
|
|
5
|
-
<div class="t normal"></div>
|
|
6
|
-
<h6>red</h6>
|
|
7
|
-
<div class="t red"></div>
|
|
8
|
-
<h6>green</h6>
|
|
9
|
-
<div class="t green"></div>
|
|
10
|
-
<h6>hue</h6>
|
|
11
|
-
<div class="t hue"></div>
|
|
12
|
-
<h6>Saturation</h6>
|
|
13
|
-
<div class="t saturation"></div>
|
|
14
|
-
<h6>desaturation</h6>
|
|
15
|
-
<div class="t desaturation"></div>
|
|
16
|
-
<h6>lighteness</h6>
|
|
17
|
-
<div class="t lighteness"></div>
|
|
18
|
-
<h6>darkness</h6>
|
|
19
|
-
<div class="t darkness"></div>
|
|
20
|
-
<h6>whiteness</h6>
|
|
21
|
-
<div class="t whiteness"></div>
|
|
22
|
-
<h6>blackness</h6>
|
|
23
|
-
<div class="t blackness"></div> -->
|
|
24
|
-
</div>
|
|
25
|
-
</template>
|
|
26
|
-
|
|
27
|
-
<script>
|
|
28
|
-
export default {
|
|
29
|
-
data() {
|
|
30
|
-
return {}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
</script>
|
|
34
|
-
<!-- <style lang="scss">
|
|
35
|
-
@use 'sass:color';
|
|
36
|
-
$color: #f11532;
|
|
37
|
-
$color-red: color.change($color, $red: 155);
|
|
38
|
-
$color-green: color.change($color, $green: 255);
|
|
39
|
-
$color-hue: adjust-hue($color, -30deg);
|
|
40
|
-
$color-saturation: color.scale($color, $saturation: 100%);
|
|
41
|
-
$color-desaturate: color.scale($color, $saturation: -50%);
|
|
42
|
-
$color-lighteness: color.scale($color, $lightness: 50%);
|
|
43
|
-
$color-darkness: color.scale($color, $lightness: -50%);
|
|
44
|
-
$color-whiteness: color.scale($color, $whiteness: 50%);
|
|
45
|
-
$color-blackness: color.scale($color, $blackness: 50%);
|
|
46
|
-
|
|
47
|
-
.t {
|
|
48
|
-
width: 50px;
|
|
49
|
-
height: 50px;
|
|
50
|
-
|
|
51
|
-
&.normal {
|
|
52
|
-
background: $color;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
&.red {
|
|
56
|
-
background: $color-red;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
&.green {
|
|
60
|
-
background: $color-green;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
&.hue {
|
|
64
|
-
background: $color-hue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
&.saturation {
|
|
68
|
-
background: $color-saturation;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
&.desaturation {
|
|
72
|
-
background: $color-desaturate;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
&.lighteness {
|
|
76
|
-
background: $color-lighteness;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
&.darkness {
|
|
80
|
-
background: $color-darkness;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
&.whiteness {
|
|
84
|
-
background: $color-whiteness;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
&.blackness {
|
|
88
|
-
background: $color-blackness;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
</style> -->
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<app-comp-menu></app-comp-menu>
|
|
4
|
+
<!-- <h6>normal</h6>
|
|
5
|
+
<div class="t normal"></div>
|
|
6
|
+
<h6>red</h6>
|
|
7
|
+
<div class="t red"></div>
|
|
8
|
+
<h6>green</h6>
|
|
9
|
+
<div class="t green"></div>
|
|
10
|
+
<h6>hue</h6>
|
|
11
|
+
<div class="t hue"></div>
|
|
12
|
+
<h6>Saturation</h6>
|
|
13
|
+
<div class="t saturation"></div>
|
|
14
|
+
<h6>desaturation</h6>
|
|
15
|
+
<div class="t desaturation"></div>
|
|
16
|
+
<h6>lighteness</h6>
|
|
17
|
+
<div class="t lighteness"></div>
|
|
18
|
+
<h6>darkness</h6>
|
|
19
|
+
<div class="t darkness"></div>
|
|
20
|
+
<h6>whiteness</h6>
|
|
21
|
+
<div class="t whiteness"></div>
|
|
22
|
+
<h6>blackness</h6>
|
|
23
|
+
<div class="t blackness"></div> -->
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script>
|
|
28
|
+
export default {
|
|
29
|
+
data() {
|
|
30
|
+
return {}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
<!-- <style lang="scss">
|
|
35
|
+
@use 'sass:color';
|
|
36
|
+
$color: #f11532;
|
|
37
|
+
$color-red: color.change($color, $red: 155);
|
|
38
|
+
$color-green: color.change($color, $green: 255);
|
|
39
|
+
$color-hue: adjust-hue($color, -30deg);
|
|
40
|
+
$color-saturation: color.scale($color, $saturation: 100%);
|
|
41
|
+
$color-desaturate: color.scale($color, $saturation: -50%);
|
|
42
|
+
$color-lighteness: color.scale($color, $lightness: 50%);
|
|
43
|
+
$color-darkness: color.scale($color, $lightness: -50%);
|
|
44
|
+
$color-whiteness: color.scale($color, $whiteness: 50%);
|
|
45
|
+
$color-blackness: color.scale($color, $blackness: 50%);
|
|
46
|
+
|
|
47
|
+
.t {
|
|
48
|
+
width: 50px;
|
|
49
|
+
height: 50px;
|
|
50
|
+
|
|
51
|
+
&.normal {
|
|
52
|
+
background: $color;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.red {
|
|
56
|
+
background: $color-red;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.green {
|
|
60
|
+
background: $color-green;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&.hue {
|
|
64
|
+
background: $color-hue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.saturation {
|
|
68
|
+
background: $color-saturation;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&.desaturation {
|
|
72
|
+
background: $color-desaturate;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.lighteness {
|
|
76
|
+
background: $color-lighteness;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.darkness {
|
|
80
|
+
background: $color-darkness;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
&.whiteness {
|
|
84
|
+
background: $color-whiteness;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&.blackness {
|
|
88
|
+
background: $color-blackness;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</style> -->
|