coursecode 0.1.56 → 0.1.58
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/README.md +8 -1
- package/bin/cli.js +16 -0
- package/framework/docs/FRAMEWORK_GUIDE.md +25 -7
- package/framework/docs/USER_GUIDE.md +14 -0
- package/framework/js/app/AppActions.js +17 -23
- package/framework/js/app/AppUI.js +7 -4
- package/framework/js/assessment/AssessmentActions.js +16 -15
- package/framework/js/assessment/AssessmentFactory.js +44 -15
- package/framework/js/automation/api-engagement.js +6 -3
- package/framework/js/components/ui-components/audio-player.js +30 -8
- package/framework/js/components/ui-components/collapse.js +4 -2
- package/framework/js/components/ui-components/dropdown.js +7 -3
- package/framework/js/components/ui-components/embed-frame.js +5 -1
- package/framework/js/components/ui-components/flip-card.js +12 -6
- package/framework/js/components/ui-components/interactive-image.js +28 -52
- package/framework/js/components/ui-components/lightbox.js +19 -5
- package/framework/js/components/ui-components/modal.js +20 -7
- package/framework/js/components/ui-components/notifications.js +8 -3
- package/framework/js/components/ui-components/video-player.js +46 -20
- package/framework/js/core/event-bus.js +31 -28
- package/framework/js/drivers/cmi5-driver.js +186 -83
- package/framework/js/drivers/driver-factory.js +7 -1
- package/framework/js/drivers/driver-interface.js +1 -1
- package/framework/js/drivers/http-driver-base.js +6 -0
- package/framework/js/drivers/lti-driver.js +112 -47
- package/framework/js/drivers/proxy-driver.js +347 -49
- package/framework/js/drivers/scorm-12-driver.js +213 -130
- package/framework/js/drivers/scorm-2004-driver.js +32 -19
- package/framework/js/drivers/scorm-driver-base.js +12 -0
- package/framework/js/drivers/standalone-driver.js +139 -0
- package/framework/js/engagement/engagement-trackers.js +38 -13
- package/framework/js/engagement/requirement-strategies.js +5 -1
- package/framework/js/main.js +7 -0
- package/framework/js/managers/assessment-manager.js +16 -1
- package/framework/js/managers/audio-manager.js +50 -16
- package/framework/js/managers/flag-manager.js +5 -1
- package/framework/js/managers/objective-manager.js +15 -7
- package/framework/js/managers/score-manager.js +27 -6
- package/framework/js/managers/video-manager.js +149 -70
- package/framework/js/navigation/NavigationActions.js +18 -4
- package/framework/js/navigation/document-gallery.js +7 -2
- package/framework/js/navigation/navigation-validators.js +3 -2
- package/framework/js/state/lms-connection.js +41 -16
- package/framework/js/state/state-commits.js +10 -5
- package/framework/js/state/state-manager.js +95 -9
- package/framework/js/state/state-validation.js +44 -11
- package/framework/js/utilities/course-helpers.js +3 -2
- package/framework/js/utilities/media-utils.js +28 -0
- package/framework/js/utilities/portable-assets.js +131 -0
- package/framework/js/utilities/ui-initializer.js +79 -5
- package/framework/js/utilities/utilities.js +32 -20
- package/framework/js/utilities/view-manager.js +16 -1
- package/framework/js/validation/scorm-validators.js +69 -0
- package/framework/version.json +2 -2
- package/lib/authoring-api.js +37 -18
- package/lib/build-packaging.js +49 -5
- package/lib/build.js +1 -1
- package/lib/cloud.js +40 -11
- package/lib/convert.js +30 -2
- package/lib/create.js +28 -3
- package/lib/dev.js +1 -1
- package/lib/headless-browser.js +66 -14
- package/lib/manifest/cmi5-manifest.js +26 -4
- package/lib/manifest/lti-tool-config.js +7 -2
- package/lib/manifest/manifest-factory.d.ts +1 -1
- package/lib/manifest/manifest-factory.js +3 -2
- package/lib/manifest/scorm-12-manifest.js +2 -2
- package/lib/manifest/scorm-2004-manifest.js +3 -28
- package/lib/manifest/scorm-proxy-manifest.js +37 -32
- package/lib/manifest/xml-utils.js +10 -0
- package/lib/narration.js +2 -2
- package/lib/portable-html.js +196 -0
- package/lib/preview-export.js +1 -1
- package/lib/preview-server.js +27 -6
- package/lib/project-utils.js +9 -1
- package/lib/proxy-templates/proxy.html +4 -1
- package/lib/proxy-templates/scorm-bridge.js +82 -10
- package/lib/scaffold.js +9 -4
- package/lib/stub-player/lms-api.js +63 -8
- package/package.json +6 -2
- package/schemas/adlcp_rootv1p2.xsd +110 -0
- package/schemas/coursecode_scorm12_package.xsd +5 -0
- package/schemas/coursecode_scorm2004_package.xsd +8 -0
- package/schemas/imscp_rootv1p1p2.xsd +304 -0
- package/template/package.json +1 -1
- package/template/vite.config.js +50 -22
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<!-- edited with XMLSPY v5 rel. 4 U (http://www.xmlspy.com) by Pascal FERTON (AISAKOS) -->
|
|
3
|
+
<!-- edited with XML Spy v4.4 U (http://www.xmlspy.com) by sa (li) -->
|
|
4
|
+
<!-- filename=ims_cp_rootv1p1p2.xsd -->
|
|
5
|
+
<!-- Copyright (2) 2001 IMS Global Learning Consortium, Inc. -->
|
|
6
|
+
<!-- edited by Thomas Wason -->
|
|
7
|
+
<!-- Conforms to w3c http://www.w3.org/TR/xmlschema-1/ 2000-10-24-->
|
|
8
|
+
<xsd:schema targetNamespace="http://www.imsproject.org/xsd/imscp_rootv1p1p2" xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" version="IMS CP 1.1.2">
|
|
9
|
+
<!-- ******************** -->
|
|
10
|
+
<!-- ** Change History ** -->
|
|
11
|
+
<!-- ******************** -->
|
|
12
|
+
<xsd:annotation>
|
|
13
|
+
<xsd:documentation xml:lang="en">DRAFT XSD for IMS Content Packaging version 1.1 DRAFT</xsd:documentation>
|
|
14
|
+
<xsd:documentation> Copyright (c) 2001 IMS GLC, Inc. </xsd:documentation>
|
|
15
|
+
<xsd:documentation>2000-04-21, Adjustments by T.D. Wason from CP 1.0.</xsd:documentation>
|
|
16
|
+
<xsd:documentation>2001-02-22, T.D.Wason: Modify for 2000-10-24 XML-Schema version. Modified to support extension.</xsd:documentation>
|
|
17
|
+
<xsd:documentation>2001-03-12, T.D.Wason: Change filename, target and meta-data namespaces and meta-data fielname. Add meta-data to itemType, fileType and organizationType.</xsd:documentation>
|
|
18
|
+
<xsd:documentation>Do not define namespaces for xml in XML instances generated from this xsd.</xsd:documentation>
|
|
19
|
+
<xsd:documentation>Imports IMS meta-data xsd, lower case element names. </xsd:documentation>
|
|
20
|
+
<xsd:documentation>This XSD provides a reference to the IMS meta-data root element as imsmd:record</xsd:documentation>
|
|
21
|
+
<xsd:documentation>If the IMS meta-data is to be used in the XML instance then the instance must define an IMS meta-data prefix with a namespace. The meta-data targetNamespace should be used. </xsd:documentation>
|
|
22
|
+
<xsd:documentation>2001-03-20, Thor Anderson: Remove manifestref, change resourceref back to identifierref, change manifest back to contained by manifest. --Tom Wason: manifest may contain _none_ or more manifests.</xsd:documentation>
|
|
23
|
+
<xsd:documentation>2001-04-13 Tom Wason: corrected attirbute name structure. Was misnamed type. </xsd:documentation>
|
|
24
|
+
<xsd:documentation>2001-05-14 Schawn Thropp: Made all complexType extensible with the group.any</xsd:documentation>
|
|
25
|
+
<xsd:documentation>Added the anyAttribute to all complexTypes. Changed the href attribute on the fileType and resourceType to xsd:string</xsd:documentation>
|
|
26
|
+
<xsd:documentation>Changed the maxLength of the href, identifierref, parameters, structure attributes to match the Information model.</xsd:documentation>
|
|
27
|
+
<xsd:documentation>2001-07-25 Schawn Thropp: Changed the namespace for the Schema of Schemas to the 5/2/2001 W3C XML Schema</xsd:documentation>
|
|
28
|
+
<xsd:documentation>Recommendation. attributeGroup attr.imsmd deleted, was not used anywhere. Any attribute declarations that have</xsd:documentation>
|
|
29
|
+
<xsd:documentation>use = "default" changed to use="optional" - attr.structure.req.</xsd:documentation>
|
|
30
|
+
<xsd:documentation>Any attribute declarations that have value="somevalue" changed to default="somevalue",</xsd:documentation>
|
|
31
|
+
<xsd:documentation>attr.structure.req (hierarchical). Removed references to IMS MD Version 1.1.</xsd:documentation>
|
|
32
|
+
<xsd:documentation>Modified attribute group "attr.resourcetype.req" to change use from optional</xsd:documentation>
|
|
33
|
+
<xsd:documentation>to required to match the information model. As a result the default value also needed to be removed</xsd:documentation>
|
|
34
|
+
<xsd:documentation>Name change for XSD. Changed to match version of CP Spec </xsd:documentation>
|
|
35
|
+
</xsd:annotation>
|
|
36
|
+
<xsd:annotation>
|
|
37
|
+
<xsd:documentation>Inclusions and Imports</xsd:documentation>
|
|
38
|
+
</xsd:annotation>
|
|
39
|
+
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
|
|
40
|
+
<xsd:annotation>
|
|
41
|
+
<xsd:documentation>Attribute Declarations</xsd:documentation>
|
|
42
|
+
</xsd:annotation>
|
|
43
|
+
<!-- **************************** -->
|
|
44
|
+
<!-- ** Attribute Declarations ** -->
|
|
45
|
+
<!-- **************************** -->
|
|
46
|
+
<xsd:attributeGroup name="attr.base">
|
|
47
|
+
<xsd:attribute ref="xml:base" use="optional"/>
|
|
48
|
+
</xsd:attributeGroup>
|
|
49
|
+
<xsd:attributeGroup name="attr.default">
|
|
50
|
+
<xsd:attribute name="default" type="xsd:IDREF" use="optional"/>
|
|
51
|
+
</xsd:attributeGroup>
|
|
52
|
+
<xsd:attributeGroup name="attr.href">
|
|
53
|
+
<xsd:attribute name="href" use="optional">
|
|
54
|
+
<xsd:simpleType>
|
|
55
|
+
<xsd:restriction base="xsd:anyURI">
|
|
56
|
+
<xsd:maxLength value="2000"/>
|
|
57
|
+
</xsd:restriction>
|
|
58
|
+
</xsd:simpleType>
|
|
59
|
+
</xsd:attribute>
|
|
60
|
+
</xsd:attributeGroup>
|
|
61
|
+
<xsd:attributeGroup name="attr.href.req">
|
|
62
|
+
<xsd:attribute name="href" use="required">
|
|
63
|
+
<xsd:simpleType>
|
|
64
|
+
<xsd:restriction base="xsd:anyURI">
|
|
65
|
+
<xsd:maxLength value="2000"/>
|
|
66
|
+
</xsd:restriction>
|
|
67
|
+
</xsd:simpleType>
|
|
68
|
+
</xsd:attribute>
|
|
69
|
+
</xsd:attributeGroup>
|
|
70
|
+
<xsd:attributeGroup name="attr.identifier.req">
|
|
71
|
+
<xsd:attribute name="identifier" type="xsd:ID" use="required"/>
|
|
72
|
+
</xsd:attributeGroup>
|
|
73
|
+
<xsd:attributeGroup name="attr.identifier">
|
|
74
|
+
<xsd:attribute name="identifier" type="xsd:ID" use="optional"/>
|
|
75
|
+
</xsd:attributeGroup>
|
|
76
|
+
<xsd:attributeGroup name="attr.isvisible">
|
|
77
|
+
<xsd:attribute name="isvisible" type="xsd:boolean" use="optional"/>
|
|
78
|
+
</xsd:attributeGroup>
|
|
79
|
+
<xsd:attributeGroup name="attr.parameters">
|
|
80
|
+
<xsd:attribute name="parameters" use="optional">
|
|
81
|
+
<xsd:simpleType>
|
|
82
|
+
<xsd:restriction base="xsd:string">
|
|
83
|
+
<xsd:maxLength value="1000"/>
|
|
84
|
+
</xsd:restriction>
|
|
85
|
+
</xsd:simpleType>
|
|
86
|
+
</xsd:attribute>
|
|
87
|
+
</xsd:attributeGroup>
|
|
88
|
+
<xsd:attributeGroup name="attr.identifierref">
|
|
89
|
+
<xsd:attribute name="identifierref" use="optional">
|
|
90
|
+
<xsd:simpleType>
|
|
91
|
+
<xsd:restriction base="xsd:string">
|
|
92
|
+
<xsd:maxLength value="2000"/>
|
|
93
|
+
</xsd:restriction>
|
|
94
|
+
</xsd:simpleType>
|
|
95
|
+
</xsd:attribute>
|
|
96
|
+
</xsd:attributeGroup>
|
|
97
|
+
<xsd:attributeGroup name="attr.identifierref.req">
|
|
98
|
+
<xsd:attribute name="identifierref" use="required">
|
|
99
|
+
<xsd:simpleType>
|
|
100
|
+
<xsd:restriction base="xsd:string">
|
|
101
|
+
<xsd:maxLength value="2000"/>
|
|
102
|
+
</xsd:restriction>
|
|
103
|
+
</xsd:simpleType>
|
|
104
|
+
</xsd:attribute>
|
|
105
|
+
</xsd:attributeGroup>
|
|
106
|
+
<xsd:attributeGroup name="attr.resourcetype.req">
|
|
107
|
+
<xsd:attribute name="type" use="required">
|
|
108
|
+
<xsd:simpleType>
|
|
109
|
+
<xsd:restriction base="xsd:string">
|
|
110
|
+
<xsd:maxLength value="1000"/>
|
|
111
|
+
</xsd:restriction>
|
|
112
|
+
</xsd:simpleType>
|
|
113
|
+
</xsd:attribute>
|
|
114
|
+
</xsd:attributeGroup>
|
|
115
|
+
<xsd:attributeGroup name="attr.structure.req">
|
|
116
|
+
<xsd:attribute name="structure" use="optional" default="hierarchical">
|
|
117
|
+
<xsd:simpleType>
|
|
118
|
+
<xsd:restriction base="xsd:string">
|
|
119
|
+
<xsd:maxLength value="200"/>
|
|
120
|
+
</xsd:restriction>
|
|
121
|
+
</xsd:simpleType>
|
|
122
|
+
</xsd:attribute>
|
|
123
|
+
</xsd:attributeGroup>
|
|
124
|
+
<xsd:attributeGroup name="attr.version">
|
|
125
|
+
<xsd:attribute name="version" use="optional">
|
|
126
|
+
<xsd:simpleType>
|
|
127
|
+
<xsd:restriction base="xsd:string">
|
|
128
|
+
<xsd:maxLength value="20"/>
|
|
129
|
+
</xsd:restriction>
|
|
130
|
+
</xsd:simpleType>
|
|
131
|
+
</xsd:attribute>
|
|
132
|
+
</xsd:attributeGroup>
|
|
133
|
+
<xsd:annotation>
|
|
134
|
+
<xsd:documentation>element groups</xsd:documentation>
|
|
135
|
+
</xsd:annotation>
|
|
136
|
+
<xsd:group name="grp.any">
|
|
137
|
+
<xsd:annotation>
|
|
138
|
+
<xsd:documentation>Any namespaced element from any namespace may be included within an "any" element. The namespace for the imported element must be defined in the instance, and the schema must be imported. </xsd:documentation>
|
|
139
|
+
</xsd:annotation>
|
|
140
|
+
<xsd:sequence>
|
|
141
|
+
<xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
|
|
142
|
+
</xsd:sequence>
|
|
143
|
+
</xsd:group>
|
|
144
|
+
<!-- ************************** -->
|
|
145
|
+
<!-- ** Element Declarations ** -->
|
|
146
|
+
<!-- ************************** -->
|
|
147
|
+
<xsd:element name="dependency" type="dependencyType"/>
|
|
148
|
+
<xsd:element name="file" type="fileType"/>
|
|
149
|
+
<xsd:element name="item" type="itemType"/>
|
|
150
|
+
<xsd:element name="manifest" type="manifestType"/>
|
|
151
|
+
<xsd:element name="metadata" type="metadataType"/>
|
|
152
|
+
<xsd:element name="organization" type="organizationType"/>
|
|
153
|
+
<xsd:element name="organizations" type="organizationsType"/>
|
|
154
|
+
<xsd:element name="resource" type="resourceType"/>
|
|
155
|
+
<xsd:element name="resources" type="resourcesType"/>
|
|
156
|
+
<xsd:element name="schema" type="schemaType"/>
|
|
157
|
+
<xsd:element name="schemaversion" type="schemaversionType"/>
|
|
158
|
+
<xsd:element name="title" type="titleType"/>
|
|
159
|
+
<!-- ******************* -->
|
|
160
|
+
<!-- ** Complex Types ** -->
|
|
161
|
+
<!-- ******************* -->
|
|
162
|
+
<!-- **************** -->
|
|
163
|
+
<!-- ** dependency ** -->
|
|
164
|
+
<!-- **************** -->
|
|
165
|
+
<xsd:complexType name="dependencyType">
|
|
166
|
+
<xsd:sequence>
|
|
167
|
+
<xsd:group ref="grp.any"/>
|
|
168
|
+
</xsd:sequence>
|
|
169
|
+
<xsd:attributeGroup ref="attr.identifierref.req"/>
|
|
170
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
171
|
+
</xsd:complexType>
|
|
172
|
+
<!-- ********** -->
|
|
173
|
+
<!-- ** file ** -->
|
|
174
|
+
<!-- ********** -->
|
|
175
|
+
<xsd:complexType name="fileType">
|
|
176
|
+
<xsd:sequence>
|
|
177
|
+
<xsd:element ref="metadata" minOccurs="0"/>
|
|
178
|
+
<xsd:group ref="grp.any"/>
|
|
179
|
+
</xsd:sequence>
|
|
180
|
+
<xsd:attributeGroup ref="attr.href.req"/>
|
|
181
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
182
|
+
</xsd:complexType>
|
|
183
|
+
<!-- ********** -->
|
|
184
|
+
<!-- ** item ** -->
|
|
185
|
+
<!-- ********** -->
|
|
186
|
+
<xsd:complexType name="itemType">
|
|
187
|
+
<xsd:sequence>
|
|
188
|
+
<xsd:element ref="title" minOccurs="0"/>
|
|
189
|
+
<xsd:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
|
|
190
|
+
<xsd:element ref="metadata" minOccurs="0"/>
|
|
191
|
+
<xsd:group ref="grp.any"/>
|
|
192
|
+
</xsd:sequence>
|
|
193
|
+
<xsd:attributeGroup ref="attr.identifier.req"/>
|
|
194
|
+
<xsd:attributeGroup ref="attr.identifierref"/>
|
|
195
|
+
<xsd:attributeGroup ref="attr.isvisible"/>
|
|
196
|
+
<xsd:attributeGroup ref="attr.parameters"/>
|
|
197
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
198
|
+
</xsd:complexType>
|
|
199
|
+
<!-- ************** -->
|
|
200
|
+
<!-- ** manifest ** -->
|
|
201
|
+
<!-- ************** -->
|
|
202
|
+
<xsd:complexType name="manifestType">
|
|
203
|
+
<xsd:sequence>
|
|
204
|
+
<xsd:element ref="metadata" minOccurs="0"/>
|
|
205
|
+
<xsd:element ref="organizations"/>
|
|
206
|
+
<xsd:element ref="resources"/>
|
|
207
|
+
<xsd:element ref="manifest" minOccurs="0" maxOccurs="unbounded"/>
|
|
208
|
+
<xsd:group ref="grp.any"/>
|
|
209
|
+
</xsd:sequence>
|
|
210
|
+
<xsd:attributeGroup ref="attr.identifier.req"/>
|
|
211
|
+
<xsd:attributeGroup ref="attr.version"/>
|
|
212
|
+
<xsd:attribute ref="xml:base"/>
|
|
213
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
214
|
+
</xsd:complexType>
|
|
215
|
+
<!-- ************** -->
|
|
216
|
+
<!-- ** metadata ** -->
|
|
217
|
+
<!-- ************** -->
|
|
218
|
+
<xsd:complexType name="metadataType">
|
|
219
|
+
<xsd:sequence>
|
|
220
|
+
<xsd:element ref="schema" minOccurs="0"/>
|
|
221
|
+
<xsd:element ref="schemaversion" minOccurs="0"/>
|
|
222
|
+
<xsd:group ref="grp.any"/>
|
|
223
|
+
</xsd:sequence>
|
|
224
|
+
</xsd:complexType>
|
|
225
|
+
<!-- ******************* -->
|
|
226
|
+
<!-- ** organizations ** -->
|
|
227
|
+
<!-- ******************* -->
|
|
228
|
+
<xsd:complexType name="organizationsType">
|
|
229
|
+
<xsd:sequence>
|
|
230
|
+
<xsd:element ref="organization" minOccurs="0" maxOccurs="unbounded"/>
|
|
231
|
+
<xsd:group ref="grp.any"/>
|
|
232
|
+
</xsd:sequence>
|
|
233
|
+
<xsd:attributeGroup ref="attr.default"/>
|
|
234
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
235
|
+
</xsd:complexType>
|
|
236
|
+
<!-- ****************** -->
|
|
237
|
+
<!-- ** organization ** -->
|
|
238
|
+
<!-- ****************** -->
|
|
239
|
+
<xsd:complexType name="organizationType">
|
|
240
|
+
<xsd:sequence>
|
|
241
|
+
<xsd:element ref="title" minOccurs="0"/>
|
|
242
|
+
<xsd:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
|
|
243
|
+
<xsd:element ref="metadata" minOccurs="0"/>
|
|
244
|
+
<xsd:group ref="grp.any"/>
|
|
245
|
+
</xsd:sequence>
|
|
246
|
+
<xsd:attributeGroup ref="attr.identifier.req"/>
|
|
247
|
+
<xsd:attributeGroup ref="attr.structure.req"/>
|
|
248
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
249
|
+
</xsd:complexType>
|
|
250
|
+
<!-- *************** -->
|
|
251
|
+
<!-- ** resources ** -->
|
|
252
|
+
<!-- *************** -->
|
|
253
|
+
<xsd:complexType name="resourcesType">
|
|
254
|
+
<xsd:sequence>
|
|
255
|
+
<xsd:element ref="resource" minOccurs="0" maxOccurs="unbounded"/>
|
|
256
|
+
<xsd:group ref="grp.any"/>
|
|
257
|
+
</xsd:sequence>
|
|
258
|
+
<xsd:attributeGroup ref="attr.base"/>
|
|
259
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
260
|
+
</xsd:complexType>
|
|
261
|
+
<!-- ************** -->
|
|
262
|
+
<!-- ** resource ** -->
|
|
263
|
+
<!-- ************** -->
|
|
264
|
+
<xsd:complexType name="resourceType">
|
|
265
|
+
<xsd:sequence>
|
|
266
|
+
<xsd:element ref="metadata" minOccurs="0"/>
|
|
267
|
+
<xsd:element ref="file" minOccurs="0" maxOccurs="unbounded"/>
|
|
268
|
+
<xsd:element ref="dependency" minOccurs="0" maxOccurs="unbounded"/>
|
|
269
|
+
<xsd:group ref="grp.any"/>
|
|
270
|
+
</xsd:sequence>
|
|
271
|
+
<xsd:attributeGroup ref="attr.identifier.req"/>
|
|
272
|
+
<xsd:attributeGroup ref="attr.resourcetype.req"/>
|
|
273
|
+
<xsd:attributeGroup ref="attr.base"/>
|
|
274
|
+
<xsd:attributeGroup ref="attr.href"/>
|
|
275
|
+
<xsd:anyAttribute namespace="##other" processContents="strict"/>
|
|
276
|
+
</xsd:complexType>
|
|
277
|
+
<!-- ****************** -->
|
|
278
|
+
<!-- ** Simple Types ** -->
|
|
279
|
+
<!-- ****************** -->
|
|
280
|
+
<!-- ************ -->
|
|
281
|
+
<!-- ** schema ** -->
|
|
282
|
+
<!-- ************ -->
|
|
283
|
+
<xsd:simpleType name="schemaType">
|
|
284
|
+
<xsd:restriction base="xsd:string">
|
|
285
|
+
<xsd:maxLength value="100"/>
|
|
286
|
+
</xsd:restriction>
|
|
287
|
+
</xsd:simpleType>
|
|
288
|
+
<!-- ******************* -->
|
|
289
|
+
<!-- ** schemaversion ** -->
|
|
290
|
+
<!-- ******************* -->
|
|
291
|
+
<xsd:simpleType name="schemaversionType">
|
|
292
|
+
<xsd:restriction base="xsd:string">
|
|
293
|
+
<xsd:maxLength value="20"/>
|
|
294
|
+
</xsd:restriction>
|
|
295
|
+
</xsd:simpleType>
|
|
296
|
+
<!-- *********** -->
|
|
297
|
+
<!-- ** title ** -->
|
|
298
|
+
<!-- *********** -->
|
|
299
|
+
<xsd:simpleType name="titleType">
|
|
300
|
+
<xsd:restriction base="xsd:string">
|
|
301
|
+
<xsd:maxLength value="200"/>
|
|
302
|
+
</xsd:restriction>
|
|
303
|
+
</xsd:simpleType>
|
|
304
|
+
</xsd:schema>
|
package/template/package.json
CHANGED
package/template/vite.config.js
CHANGED
|
@@ -10,10 +10,13 @@ let createStandardPackage;
|
|
|
10
10
|
let createExternalPackagesForClients;
|
|
11
11
|
let validateExternalHostingConfig;
|
|
12
12
|
let loadExternalAccessConfig;
|
|
13
|
+
let createPortableHtmlPlugin;
|
|
13
14
|
|
|
14
15
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
16
|
const ROOT_DIR = path.resolve(__dirname);
|
|
16
|
-
const
|
|
17
|
+
const BUILD_OUTPUT = process.env.COURSECODE_OUT_DIR || 'dist';
|
|
18
|
+
const DIST_DIR = path.resolve(ROOT_DIR, BUILD_OUTPUT);
|
|
19
|
+
const PORTABLE_HTML = process.env.COURSECODE_PORTABLE_HTML === 'true';
|
|
17
20
|
const SUPPORTED_BROWSER_TARGETS = ['chrome111', 'edge111', 'firefox114', 'safari16.4'];
|
|
18
21
|
|
|
19
22
|
function directoryContainsFiles(directory) {
|
|
@@ -23,6 +26,14 @@ function directoryContainsFiles(directory) {
|
|
|
23
26
|
));
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
function escapeHtmlAttribute(value) {
|
|
30
|
+
return String(value)
|
|
31
|
+
.replace(/&/g, '&')
|
|
32
|
+
.replace(/"/g, '"')
|
|
33
|
+
.replace(/</g, '<')
|
|
34
|
+
.replace(/>/g, '>');
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
async function loadBuildUtils() {
|
|
27
38
|
if (
|
|
28
39
|
generateManifest &&
|
|
@@ -30,7 +41,8 @@ async function loadBuildUtils() {
|
|
|
30
41
|
createStandardPackage &&
|
|
31
42
|
createExternalPackagesForClients &&
|
|
32
43
|
validateExternalHostingConfig &&
|
|
33
|
-
loadExternalAccessConfig
|
|
44
|
+
loadExternalAccessConfig &&
|
|
45
|
+
createPortableHtmlPlugin
|
|
34
46
|
) {
|
|
35
47
|
return;
|
|
36
48
|
}
|
|
@@ -44,6 +56,7 @@ async function loadBuildUtils() {
|
|
|
44
56
|
loadExternalAccessConfig
|
|
45
57
|
} = await import('coursecode/build-packaging'));
|
|
46
58
|
({ default: contentDiscoveryPlugin } = await import('coursecode/vite-plugin-content-discovery'));
|
|
59
|
+
({ createPortableHtmlPlugin } = await import('coursecode/portable-html'));
|
|
47
60
|
} catch {
|
|
48
61
|
// Fallback for npm link / local dev — preview-server provides COURSECODE_LIB_DIR
|
|
49
62
|
const libDir = process.env.COURSECODE_LIB_DIR;
|
|
@@ -57,6 +70,7 @@ async function loadBuildUtils() {
|
|
|
57
70
|
loadExternalAccessConfig
|
|
58
71
|
} = await import(toUrl('build-packaging.js')));
|
|
59
72
|
({ default: contentDiscoveryPlugin } = await import(toUrl('vite-plugin-content-discovery.js')));
|
|
73
|
+
({ createPortableHtmlPlugin } = await import(toUrl('portable-html.js')));
|
|
60
74
|
}
|
|
61
75
|
}
|
|
62
76
|
|
|
@@ -75,8 +89,13 @@ function validatePackage(format = 'scorm2004') {
|
|
|
75
89
|
} else if (format === 'lti') {
|
|
76
90
|
requiredFiles = ['lti-tool-config.json', 'index.html'];
|
|
77
91
|
} else if (format === 'scorm1.2') {
|
|
78
|
-
requiredFiles = [
|
|
79
|
-
|
|
92
|
+
requiredFiles = [
|
|
93
|
+
'imsmanifest.xml',
|
|
94
|
+
'index.html',
|
|
95
|
+
'imscp_rootv1p1p2.xsd',
|
|
96
|
+
'adlcp_rootv1p2.xsd',
|
|
97
|
+
'ims_xml.xsd'
|
|
98
|
+
];
|
|
80
99
|
} else {
|
|
81
100
|
// SCORM 2004 default
|
|
82
101
|
requiredFiles = [
|
|
@@ -199,6 +218,7 @@ async function loadCourseConfig() {
|
|
|
199
218
|
lmsFormat,
|
|
200
219
|
externalUrl: process.env.LTI_EXTERNAL_URL || config.externalUrl || null,
|
|
201
220
|
masteryScore: masteryScore ?? null,
|
|
221
|
+
moveOn: config.lms?.moveOn || null,
|
|
202
222
|
accessControl: loadExternalAccessConfig(ROOT_DIR, config),
|
|
203
223
|
galleryConfig: config.navigation?.documentGallery || null
|
|
204
224
|
};
|
|
@@ -276,7 +296,7 @@ function scormPostBuild(isDev, { isWatchBuild }) {
|
|
|
276
296
|
// Stamp LMS format meta tag for runtime driver selection
|
|
277
297
|
indexContent = indexContent.replace(
|
|
278
298
|
'<meta charset="UTF-8" />',
|
|
279
|
-
`<meta charset="UTF-8" />\n <meta name="lms-format" content="${config.lmsFormat}" />`
|
|
299
|
+
`<meta charset="UTF-8" />\n <meta name="lms-format" content="${config.lmsFormat}" />\n <meta name="coursecode-id" content="${escapeHtmlAttribute(`${config.title}:${config.version}`)}" />`
|
|
280
300
|
);
|
|
281
301
|
|
|
282
302
|
fs.writeFileSync(indexDest, indexContent, 'utf-8');
|
|
@@ -287,6 +307,11 @@ function scormPostBuild(isDev, { isWatchBuild }) {
|
|
|
287
307
|
}
|
|
288
308
|
}
|
|
289
309
|
|
|
310
|
+
if (PORTABLE_HTML) {
|
|
311
|
+
if (!isDev) console.log('✓ Portable runtime assembled (LMS package files omitted)');
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
290
315
|
// Generate manifest using factory
|
|
291
316
|
const files = isDev ? ['index.html'] : scanDistFiles();
|
|
292
317
|
const manifestOptions = { externalUrl: config.externalUrl };
|
|
@@ -333,6 +358,17 @@ export default defineConfig(async ({ mode }) => {
|
|
|
333
358
|
const isDev = mode === 'development';
|
|
334
359
|
const isWatchBuild = process.argv.includes('--watch');
|
|
335
360
|
const courseConfig = await loadCourseConfig();
|
|
361
|
+
const staticCopyTargets = [
|
|
362
|
+
...(!PORTABLE_HTML ? [
|
|
363
|
+
{ src: 'schemas/*.{xml,xsd,dtd}', dest: '.', rename: { stripBase: 1 } },
|
|
364
|
+
{ src: 'schemas/common/*', dest: 'common', rename: { stripBase: 2 } },
|
|
365
|
+
{ src: 'framework/js/vendor/**/*', dest: 'js/vendor', rename: { stripBase: 3 } }
|
|
366
|
+
] : []),
|
|
367
|
+
// Publish runtime assets only. Authoring source stays out of every output.
|
|
368
|
+
...(directoryContainsFiles(path.join(ROOT_DIR, 'course', 'assets'))
|
|
369
|
+
? [{ src: 'course/assets', dest: 'course', rename: { stripBase: 1 } }]
|
|
370
|
+
: [])
|
|
371
|
+
];
|
|
336
372
|
|
|
337
373
|
return {
|
|
338
374
|
root: '.',
|
|
@@ -356,7 +392,7 @@ export default defineConfig(async ({ mode }) => {
|
|
|
356
392
|
},
|
|
357
393
|
|
|
358
394
|
build: {
|
|
359
|
-
outDir:
|
|
395
|
+
outDir: BUILD_OUTPUT,
|
|
360
396
|
emptyOutDir: !isWatchBuild,
|
|
361
397
|
// Stable browser contract for LMS launches. SCORM defines the LMS API,
|
|
362
398
|
// not an obsolete browser requirement; IE11/SystemJS is unsupported.
|
|
@@ -372,9 +408,9 @@ export default defineConfig(async ({ mode }) => {
|
|
|
372
408
|
// LTI OIDC/JWT validation remains server-side, so no browser crypto
|
|
373
409
|
// verification dependency is required here.
|
|
374
410
|
output: {
|
|
375
|
-
entryFileNames: 'assets/[name].js',
|
|
376
|
-
chunkFileNames: 'assets/[name].js',
|
|
377
|
-
assetFileNames: 'assets/[name].[ext]'
|
|
411
|
+
entryFileNames: 'assets/[name]-[hash].js',
|
|
412
|
+
chunkFileNames: 'assets/[name]-[hash].js',
|
|
413
|
+
assetFileNames: 'assets/[name]-[hash].[ext]'
|
|
378
414
|
}
|
|
379
415
|
}
|
|
380
416
|
},
|
|
@@ -383,20 +419,12 @@ export default defineConfig(async ({ mode }) => {
|
|
|
383
419
|
// Content discovery - generates manifest at build time
|
|
384
420
|
contentDiscoveryPlugin({ galleryConfig: courseConfig.galleryConfig }),
|
|
385
421
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
// Publish runtime assets only. Never ship authoring references,
|
|
391
|
-
// configuration source, assessment source, or hidden project files.
|
|
392
|
-
// A blank course is valid and may not contain any assets yet.
|
|
393
|
-
...(directoryContainsFiles(path.join(ROOT_DIR, 'course', 'assets'))
|
|
394
|
-
? [{ src: 'course/assets', dest: 'course', rename: { stripBase: 1 } }]
|
|
395
|
-
: []),
|
|
396
|
-
{ src: 'framework/js/vendor/**/*', dest: 'js/vendor', rename: { stripBase: 3 } }
|
|
397
|
-
],
|
|
422
|
+
...(PORTABLE_HTML ? [createPortableHtmlPlugin()] : []),
|
|
423
|
+
|
|
424
|
+
...(staticCopyTargets.length > 0 ? [viteStaticCopy({
|
|
425
|
+
targets: staticCopyTargets,
|
|
398
426
|
watch: isDev ? { rerun: true } : undefined
|
|
399
|
-
}),
|
|
427
|
+
})] : []),
|
|
400
428
|
|
|
401
429
|
scormPostBuild(isDev, { isWatchBuild })
|
|
402
430
|
]
|