coursecode 0.1.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/LICENSE +21 -0
- package/README.md +322 -0
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/bin/cli.js +331 -0
- package/framework/assets/logo-coursecode-black.svg +14 -0
- package/framework/assets/logo-coursecode-white.svg +14 -0
- package/framework/assets/logo-coursecode.svg +14 -0
- package/framework/css/01-base.css +160 -0
- package/framework/css/02-layout.css +499 -0
- package/framework/css/accessibility.css +834 -0
- package/framework/css/components/accordions.css +710 -0
- package/framework/css/components/assessments.css +520 -0
- package/framework/css/components/audio-player.css +570 -0
- package/framework/css/components/badges.css +80 -0
- package/framework/css/components/breadcrumbs.css +87 -0
- package/framework/css/components/buttons.css +707 -0
- package/framework/css/components/callouts.css +1280 -0
- package/framework/css/components/cards.css +475 -0
- package/framework/css/components/carousel.css +193 -0
- package/framework/css/components/checkbox-group.css +123 -0
- package/framework/css/components/checklist.css +203 -0
- package/framework/css/components/collapse.css +96 -0
- package/framework/css/components/comparison.css +33 -0
- package/framework/css/components/content-image.css +36 -0
- package/framework/css/components/document-gallery.css +425 -0
- package/framework/css/components/dropdown.css +115 -0
- package/framework/css/components/embed-frame.css +142 -0
- package/framework/css/components/engagement.css +412 -0
- package/framework/css/components/features.css +35 -0
- package/framework/css/components/flip-cards.css +253 -0
- package/framework/css/components/footer.css +353 -0
- package/framework/css/components/forms.css +294 -0
- package/framework/css/components/hero.css +216 -0
- package/framework/css/components/images.css +528 -0
- package/framework/css/components/interactive-timeline.css +274 -0
- package/framework/css/components/intro-cards.css +30 -0
- package/framework/css/components/lightbox.css +666 -0
- package/framework/css/components/loading.css +65 -0
- package/framework/css/components/modals.css +235 -0
- package/framework/css/components/notifications.css +107 -0
- package/framework/css/components/quote.css +150 -0
- package/framework/css/components/sidebar.css +684 -0
- package/framework/css/components/slide-header.css +52 -0
- package/framework/css/components/spinner.css +62 -0
- package/framework/css/components/stats.css +44 -0
- package/framework/css/components/steps.css +232 -0
- package/framework/css/components/tables.css +90 -0
- package/framework/css/components/tabs.css +347 -0
- package/framework/css/components/timeline.css +154 -0
- package/framework/css/components/toggle.css +95 -0
- package/framework/css/components/tooltip.css +226 -0
- package/framework/css/components/video-player.css +438 -0
- package/framework/css/design-tokens.css +707 -0
- package/framework/css/framework.css +86 -0
- package/framework/css/interactions/accessibility.css +75 -0
- package/framework/css/interactions/base.css +92 -0
- package/framework/css/interactions/drag-drop.css +295 -0
- package/framework/css/interactions/fill-in-the-blank.css +236 -0
- package/framework/css/interactions/hotspots.css +69 -0
- package/framework/css/interactions/index.css +45 -0
- package/framework/css/interactions/interactive-image.css +359 -0
- package/framework/css/interactions/likert.css +126 -0
- package/framework/css/interactions/matching.css +354 -0
- package/framework/css/interactions/numeric-input.css +78 -0
- package/framework/css/interactions/sequencing.css +378 -0
- package/framework/css/interactions/true-false.css +177 -0
- package/framework/css/layouts/article.css +258 -0
- package/framework/css/layouts/base.css +30 -0
- package/framework/css/layouts/canvas.css +38 -0
- package/framework/css/layouts/focused.css +236 -0
- package/framework/css/layouts/index.css +29 -0
- package/framework/css/layouts/presentation.css +191 -0
- package/framework/css/layouts/traditional.css +52 -0
- package/framework/css/responsive.css +439 -0
- package/framework/css/utilities/accessibility-utils.css +59 -0
- package/framework/css/utilities/animations.css +419 -0
- package/framework/css/utilities/borders.css +72 -0
- package/framework/css/utilities/colors.css +76 -0
- package/framework/css/utilities/container.css +46 -0
- package/framework/css/utilities/decorative.css +442 -0
- package/framework/css/utilities/display.css +257 -0
- package/framework/css/utilities/flexbox.css +80 -0
- package/framework/css/utilities/grid.css +69 -0
- package/framework/css/utilities/icons.css +534 -0
- package/framework/css/utilities/lists.css +190 -0
- package/framework/css/utilities/spacing.css +167 -0
- package/framework/css/utilities/tables.css +81 -0
- package/framework/css/utilities/typography.css +159 -0
- package/framework/css/utilities/visibility.css +117 -0
- package/framework/docs/COURSE_AUTHORING_GUIDE.md +1773 -0
- package/framework/docs/COURSE_OUTLINE_GUIDE.md +725 -0
- package/framework/docs/COURSE_OUTLINE_TEMPLATE.md +161 -0
- package/framework/docs/DATA_MODEL.md +409 -0
- package/framework/docs/FRAMEWORK_GUIDE.md +1088 -0
- package/framework/docs/USER_GUIDE.md +583 -0
- package/framework/docs/examples/cloudflare-channel-relay.js +169 -0
- package/framework/docs/examples/cloudflare-data-worker.js +102 -0
- package/framework/docs/examples/cloudflare-error-worker.js +228 -0
- package/framework/index.html +175 -0
- package/framework/js/app/AppActions.js +410 -0
- package/framework/js/app/AppState.js +225 -0
- package/framework/js/app/AppUI.js +616 -0
- package/framework/js/assessment/AssessmentActions.js +615 -0
- package/framework/js/assessment/AssessmentFactory.js +471 -0
- package/framework/js/assessment/AssessmentState.js +322 -0
- package/framework/js/assessment/AssessmentUI.js +451 -0
- package/framework/js/automation/api-engagement.js +196 -0
- package/framework/js/automation/api-interactions.js +167 -0
- package/framework/js/automation/api.js +242 -0
- package/framework/js/automation/index.js +41 -0
- package/framework/js/components/interactions/drag-drop.js +884 -0
- package/framework/js/components/interactions/fill-in.js +535 -0
- package/framework/js/components/interactions/hotspot.js +702 -0
- package/framework/js/components/interactions/interaction-base.js +511 -0
- package/framework/js/components/interactions/likert.js +301 -0
- package/framework/js/components/interactions/matching.js +699 -0
- package/framework/js/components/interactions/multiple-choice.js +377 -0
- package/framework/js/components/interactions/numeric.js +271 -0
- package/framework/js/components/interactions/sequencing.js +423 -0
- package/framework/js/components/interactions/true-false.js +241 -0
- package/framework/js/components/ui-components/accordion.js +442 -0
- package/framework/js/components/ui-components/alert.js +88 -0
- package/framework/js/components/ui-components/audio-player.js +1193 -0
- package/framework/js/components/ui-components/callout.js +121 -0
- package/framework/js/components/ui-components/carousel.js +145 -0
- package/framework/js/components/ui-components/checkbox-group.js +87 -0
- package/framework/js/components/ui-components/checklist.js +40 -0
- package/framework/js/components/ui-components/collapse.js +114 -0
- package/framework/js/components/ui-components/comparison.js +30 -0
- package/framework/js/components/ui-components/conditional-display.js +150 -0
- package/framework/js/components/ui-components/content-image.js +41 -0
- package/framework/js/components/ui-components/dropdown.js +262 -0
- package/framework/js/components/ui-components/embed-frame.js +274 -0
- package/framework/js/components/ui-components/features.js +33 -0
- package/framework/js/components/ui-components/flip-card.js +230 -0
- package/framework/js/components/ui-components/form-validator.js +76 -0
- package/framework/js/components/ui-components/hero.js +49 -0
- package/framework/js/components/ui-components/index.js +12 -0
- package/framework/js/components/ui-components/interactive-image.js +235 -0
- package/framework/js/components/ui-components/interactive-timeline.js +285 -0
- package/framework/js/components/ui-components/intro-cards.js +35 -0
- package/framework/js/components/ui-components/lightbox.js +652 -0
- package/framework/js/components/ui-components/modal.js +386 -0
- package/framework/js/components/ui-components/notifications.js +145 -0
- package/framework/js/components/ui-components/progress.js +88 -0
- package/framework/js/components/ui-components/quote.js +41 -0
- package/framework/js/components/ui-components/stats.js +33 -0
- package/framework/js/components/ui-components/steps.js +41 -0
- package/framework/js/components/ui-components/tabs.js +255 -0
- package/framework/js/components/ui-components/timeline.js +42 -0
- package/framework/js/components/ui-components/toggle-group.js +73 -0
- package/framework/js/components/ui-components/tooltip.js +458 -0
- package/framework/js/components/ui-components/value-display.js +133 -0
- package/framework/js/components/ui-components/video-player.js +686 -0
- package/framework/js/core/component-catalog.js +121 -0
- package/framework/js/core/event-bus.js +178 -0
- package/framework/js/core/interaction-catalog.js +149 -0
- package/framework/js/dev/runtime-linter.js +1725 -0
- package/framework/js/drivers/cmi5-driver.js +768 -0
- package/framework/js/drivers/driver-factory.js +77 -0
- package/framework/js/drivers/driver-interface.js +110 -0
- package/framework/js/drivers/http-driver-base.js +241 -0
- package/framework/js/drivers/lti-driver.js +508 -0
- package/framework/js/drivers/proxy-driver.js +444 -0
- package/framework/js/drivers/scorm-12-driver.js +560 -0
- package/framework/js/drivers/scorm-2004-driver.js +775 -0
- package/framework/js/drivers/scorm-driver-base.js +112 -0
- package/framework/js/engagement/engagement-manager.js +404 -0
- package/framework/js/engagement/engagement-progress.js +191 -0
- package/framework/js/engagement/engagement-trackers.js +215 -0
- package/framework/js/engagement/requirement-strategies.js +268 -0
- package/framework/js/main.js +727 -0
- package/framework/js/managers/accessibility-manager.js +499 -0
- package/framework/js/managers/assessment-manager.js +230 -0
- package/framework/js/managers/audio-manager.js +944 -0
- package/framework/js/managers/comment-manager.js +88 -0
- package/framework/js/managers/flag-manager.js +86 -0
- package/framework/js/managers/interaction-manager.js +254 -0
- package/framework/js/managers/interaction-registry.js +96 -0
- package/framework/js/managers/objective-manager.js +423 -0
- package/framework/js/managers/score-manager.js +441 -0
- package/framework/js/managers/video-manager.js +536 -0
- package/framework/js/navigation/Breadcrumbs.js +234 -0
- package/framework/js/navigation/NavigationActions.js +1132 -0
- package/framework/js/navigation/NavigationState.js +276 -0
- package/framework/js/navigation/NavigationUI.js +574 -0
- package/framework/js/navigation/document-gallery.js +357 -0
- package/framework/js/navigation/navigation-helpers.js +175 -0
- package/framework/js/navigation/navigation-validators.js +174 -0
- package/framework/js/state/index.js +8 -0
- package/framework/js/state/lms-connection.js +482 -0
- package/framework/js/state/lms-error-utils.js +58 -0
- package/framework/js/state/state-commits.js +200 -0
- package/framework/js/state/state-domains.js +86 -0
- package/framework/js/state/state-manager.js +502 -0
- package/framework/js/state/state-validation.js +311 -0
- package/framework/js/state/transaction-log.js +41 -0
- package/framework/js/state/xapi-statement-service.js +325 -0
- package/framework/js/utilities/access-control.js +99 -0
- package/framework/js/utilities/breakpoint-manager.js +315 -0
- package/framework/js/utilities/canvas-slide.js +35 -0
- package/framework/js/utilities/conditional-display.js +388 -0
- package/framework/js/utilities/course-channel.js +214 -0
- package/framework/js/utilities/course-helpers.js +420 -0
- package/framework/js/utilities/data-reporter.js +273 -0
- package/framework/js/utilities/error-reporter.js +313 -0
- package/framework/js/utilities/hotspot-helper.js +341 -0
- package/framework/js/utilities/icons.js +348 -0
- package/framework/js/utilities/logger.js +92 -0
- package/framework/js/utilities/markdown-renderer.js +45 -0
- package/framework/js/utilities/scroll-tracker.js +68 -0
- package/framework/js/utilities/ui-initializer.js +146 -0
- package/framework/js/utilities/utilities.js +293 -0
- package/framework/js/utilities/view-manager.js +227 -0
- package/framework/js/validation/html-validators.js +422 -0
- package/framework/js/validation/scorm-validators.js +438 -0
- package/framework/js/vendor/pipwerks.js +931 -0
- package/framework/scripts/generate-narration.js +629 -0
- package/framework/scripts/tts-providers/azure-provider.js +178 -0
- package/framework/scripts/tts-providers/base-provider.js +81 -0
- package/framework/scripts/tts-providers/deepgram-provider.js +135 -0
- package/framework/scripts/tts-providers/elevenlabs-provider.js +148 -0
- package/framework/scripts/tts-providers/google-provider.js +272 -0
- package/framework/scripts/tts-providers/index.js +158 -0
- package/framework/scripts/tts-providers/openai-provider.js +143 -0
- package/framework/version.json +63 -0
- package/lib/authoring-api.js +919 -0
- package/lib/build-linter.js +450 -0
- package/lib/build-packaging.js +186 -0
- package/lib/build.js +88 -0
- package/lib/cloud.js +691 -0
- package/lib/convert.js +341 -0
- package/lib/course-parser.js +936 -0
- package/lib/course-writer.js +258 -0
- package/lib/create.js +248 -0
- package/lib/css-index.js +237 -0
- package/lib/dev.js +51 -0
- package/lib/export-content.js +1246 -0
- package/lib/headless-browser.js +413 -0
- package/lib/import.js +377 -0
- package/lib/index.js +80 -0
- package/lib/info.js +79 -0
- package/lib/interaction-formatters.js +568 -0
- package/lib/manifest/cmi5-manifest.js +63 -0
- package/lib/manifest/lti-tool-config.js +53 -0
- package/lib/manifest/manifest-factory.js +99 -0
- package/lib/manifest/scorm-12-manifest.js +61 -0
- package/lib/manifest/scorm-2004-manifest.js +94 -0
- package/lib/manifest/scorm-proxy-manifest.js +104 -0
- package/lib/manifest-parser.js +96 -0
- package/lib/mcp-prompts.js +753 -0
- package/lib/mcp-server.js +316 -0
- package/lib/narration.js +53 -0
- package/lib/pdf-structure.js +142 -0
- package/lib/preview-export.js +231 -0
- package/lib/preview-routes-api.js +662 -0
- package/lib/preview-routes-editing.js +159 -0
- package/lib/preview-routes-lms.js +230 -0
- package/lib/preview-server.js +564 -0
- package/lib/project-utils.js +269 -0
- package/lib/proxy-templates/proxy.html +68 -0
- package/lib/proxy-templates/scorm-bridge.js +112 -0
- package/lib/scaffold.js +193 -0
- package/lib/schema-extractor.js +361 -0
- package/lib/slide-source-editor.js +586 -0
- package/lib/stub-player/app-viewer.js +195 -0
- package/lib/stub-player/app.js +370 -0
- package/lib/stub-player/catalog-panel.js +312 -0
- package/lib/stub-player/config-panel.js +1303 -0
- package/lib/stub-player/content-generator.js +586 -0
- package/lib/stub-player/content-viewer.js +173 -0
- package/lib/stub-player/debug-panel.js +420 -0
- package/lib/stub-player/edit-mode.js +922 -0
- package/lib/stub-player/edit-utils.js +400 -0
- package/lib/stub-player/header-bar.js +354 -0
- package/lib/stub-player/interaction-editor.js +210 -0
- package/lib/stub-player/interactions-panel.js +565 -0
- package/lib/stub-player/lms-api.js +1094 -0
- package/lib/stub-player/login-screen.js +74 -0
- package/lib/stub-player/outline-mode.js +689 -0
- package/lib/stub-player/styles/_assessments-panel.css +245 -0
- package/lib/stub-player/styles/_base.css +89 -0
- package/lib/stub-player/styles/_catalog-icons.css +96 -0
- package/lib/stub-player/styles/_catalog-panel.css +291 -0
- package/lib/stub-player/styles/_config-panel.css +636 -0
- package/lib/stub-player/styles/_content-viewer.css +834 -0
- package/lib/stub-player/styles/_debug-panel.css +576 -0
- package/lib/stub-player/styles/_edit-mode.css +128 -0
- package/lib/stub-player/styles/_header-bar.css +343 -0
- package/lib/stub-player/styles/_interaction-editor.css +140 -0
- package/lib/stub-player/styles/_interactions-panel.css +1038 -0
- package/lib/stub-player/styles/_login-screen.css +102 -0
- package/lib/stub-player/styles/_outline-mode.css +752 -0
- package/lib/stub-player/styles.css +15 -0
- package/lib/stub-player.js +160 -0
- package/lib/test-data-reporting.js +176 -0
- package/lib/test-error-reporting.js +146 -0
- package/lib/token.js +86 -0
- package/lib/upgrade.js +257 -0
- package/lib/validation-rules.js +517 -0
- package/lib/vite-plugin-content-discovery.js +296 -0
- package/package.json +108 -0
- package/schemas/XMLSchema.dtd +402 -0
- package/schemas/adlcp_v1p3.xsd +111 -0
- package/schemas/adlnav_v1p3.xsd +61 -0
- package/schemas/adlseq_v1p3.xsd +93 -0
- package/schemas/common/anyElement.xsd +27 -0
- package/schemas/common/dataTypes.xsd +138 -0
- package/schemas/common/elementNames.xsd +767 -0
- package/schemas/common/elementTypes.xsd +786 -0
- package/schemas/common/rootElement.xsd +31 -0
- package/schemas/common/vocabTypes.xsd +345 -0
- package/schemas/common/vocabValues.xsd +257 -0
- package/schemas/datatypes.dtd +203 -0
- package/schemas/ims_xml.xsd +35 -0
- package/schemas/imscp_v1p1.xsd +368 -0
- package/schemas/imsss_v1p0.xsd +67 -0
- package/schemas/imsss_v1p0auxresource.xsd +19 -0
- package/schemas/imsss_v1p0control.xsd +20 -0
- package/schemas/imsss_v1p0delivery.xsd +17 -0
- package/schemas/imsss_v1p0limit.xsd +47 -0
- package/schemas/imsss_v1p0objective.xsd +67 -0
- package/schemas/imsss_v1p0random.xsd +16 -0
- package/schemas/imsss_v1p0rollup.xsd +46 -0
- package/schemas/imsss_v1p0seqrule.xsd +108 -0
- package/schemas/imsss_v1p0util.xsd +94 -0
- package/schemas/license.txt +17 -0
- package/schemas/lom.xsd +102 -0
- package/schemas/lomCustom.xsd +62 -0
- package/schemas/lomLoose.xsd +62 -0
- package/schemas/lomStrict.xsd +62 -0
- package/schemas/xml.xsd +81 -0
- package/template/.env.example +92 -0
- package/template/course/assets/audio/example-intro.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--compact-player.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--demo-modal.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--full-player.mp3 +0 -0
- package/template/course/assets/docs/example_md_1.md +39 -0
- package/template/course/assets/docs/example_md_2.md +41 -0
- package/template/course/assets/docs/example_pdf_1_thumbnail.png +0 -0
- package/template/course/assets/docs/example_pdf_2.pdf +0 -0
- package/template/course/assets/images/course-architecture.svg +36 -0
- package/template/course/assets/images/logo.svg +14 -0
- package/template/course/assets/widgets/counter-demo.html +190 -0
- package/template/course/assets/widgets/gravity-painter.html +384 -0
- package/template/course/course-config.js +539 -0
- package/template/course/icons.js +19 -0
- package/template/course/interactions/PLUGIN_GUIDE.md +97 -0
- package/template/course/slides/example-course-structure.js +138 -0
- package/template/course/slides/example-final-exam.js +144 -0
- package/template/course/slides/example-finishing.js +127 -0
- package/template/course/slides/example-interactions-showcase.js +615 -0
- package/template/course/slides/example-preview-tour.js +129 -0
- package/template/course/slides/example-remedial.js +143 -0
- package/template/course/slides/example-summary.js +103 -0
- package/template/course/slides/example-ui-showcase.js +1805 -0
- package/template/course/slides/example-welcome.js +123 -0
- package/template/course/slides/example-workflow.js +140 -0
- package/template/course/theme.css +165 -0
- package/template/eslint.config.js +47 -0
- package/template/package.json +28 -0
- package/template/vite.config.js +339 -0
|
@@ -0,0 +1,931 @@
|
|
|
1
|
+
/*global define, module */
|
|
2
|
+
|
|
3
|
+
/* ===========================================================
|
|
4
|
+
|
|
5
|
+
pipwerks SCORM Wrapper for JavaScript
|
|
6
|
+
v1.1.20180906
|
|
7
|
+
|
|
8
|
+
Created by Philip Hutchison, January 2008-2018
|
|
9
|
+
https://github.com/pipwerks/scorm-api-wrapper
|
|
10
|
+
|
|
11
|
+
Copyright (c) Philip Hutchison
|
|
12
|
+
MIT-style license: http://pipwerks.mit-license.org/
|
|
13
|
+
|
|
14
|
+
This wrapper works with both SCORM 1.2 and SCORM 2004.
|
|
15
|
+
|
|
16
|
+
Inspired by APIWrapper.js, created by the ADL and
|
|
17
|
+
Concurrent Technologies Corporation, distributed by
|
|
18
|
+
the ADL (http://www.adlnet.gov/scorm).
|
|
19
|
+
|
|
20
|
+
SCORM.API.find() and SCORM.API.get() functions based
|
|
21
|
+
on ADL code, modified by Mike Rustici
|
|
22
|
+
(http://www.scorm.com/resources/apifinder/SCORMAPIFinder.htm),
|
|
23
|
+
further modified by Philip Hutchison
|
|
24
|
+
|
|
25
|
+
=============================================================== */
|
|
26
|
+
|
|
27
|
+
(function (root, factory) {
|
|
28
|
+
|
|
29
|
+
"use strict";
|
|
30
|
+
|
|
31
|
+
if (typeof define === 'function' && define.amd) {
|
|
32
|
+
// AMD. Register as an anonymous module.
|
|
33
|
+
define([], factory);
|
|
34
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
35
|
+
// Node. Does not work with strict CommonJS, but
|
|
36
|
+
// only CommonJS-like environments that support module.exports,
|
|
37
|
+
// like Node.
|
|
38
|
+
module.exports = factory();
|
|
39
|
+
} else {
|
|
40
|
+
// Browser globals (root is window)
|
|
41
|
+
root.pipwerks = factory();
|
|
42
|
+
}
|
|
43
|
+
}(typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : this, function () {
|
|
44
|
+
|
|
45
|
+
"use strict";
|
|
46
|
+
|
|
47
|
+
var pipwerks = {}; //pipwerks 'namespace' helps ensure no conflicts with possible other "SCORM" variables
|
|
48
|
+
pipwerks.UTILS = {}; //For holding UTILS functions
|
|
49
|
+
pipwerks.debug = { isActive: true }; //Enable (true) or disable (false) for debug mode
|
|
50
|
+
|
|
51
|
+
pipwerks.SCORM = { //Define the SCORM object
|
|
52
|
+
version: null, //Store SCORM version.
|
|
53
|
+
handleCompletionStatus: true, //Whether or not the wrapper should automatically handle the initial completion status
|
|
54
|
+
handleExitMode: true, //Whether or not the wrapper should automatically handle the exit mode
|
|
55
|
+
API: {
|
|
56
|
+
handle: null,
|
|
57
|
+
isFound: false
|
|
58
|
+
}, //Create API child object
|
|
59
|
+
connection: { isActive: false }, //Create connection child object
|
|
60
|
+
data: {
|
|
61
|
+
completionStatus: null,
|
|
62
|
+
exitStatus: null
|
|
63
|
+
}, //Create data child object
|
|
64
|
+
debug: {} //Create debug child object
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/* --------------------------------------------------------------------------------
|
|
68
|
+
pipwerks.SCORM.isAvailable
|
|
69
|
+
A simple function to allow Flash ExternalInterface to confirm
|
|
70
|
+
presence of JS wrapper before attempting any LMS communication.
|
|
71
|
+
|
|
72
|
+
Parameters: none
|
|
73
|
+
Returns: Boolean (true)
|
|
74
|
+
----------------------------------------------------------------------------------- */
|
|
75
|
+
|
|
76
|
+
pipwerks.SCORM.isAvailable = function () {
|
|
77
|
+
return true;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
// ------------------------------------------------------------------------- //
|
|
82
|
+
// --- SCORM.API functions ------------------------------------------------- //
|
|
83
|
+
// ------------------------------------------------------------------------- //
|
|
84
|
+
|
|
85
|
+
/* -------------------------------------------------------------------------
|
|
86
|
+
pipwerks.SCORM.API.find(window)
|
|
87
|
+
Looks for an object named API in parent and opener windows
|
|
88
|
+
|
|
89
|
+
Parameters: window (the browser window object).
|
|
90
|
+
Returns: Object if API is found, null if no API found
|
|
91
|
+
---------------------------------------------------------------------------- */
|
|
92
|
+
|
|
93
|
+
pipwerks.SCORM.API.find = function (win) {
|
|
94
|
+
|
|
95
|
+
var API = null,
|
|
96
|
+
findAttempts = 0,
|
|
97
|
+
findAttemptLimit = 500,
|
|
98
|
+
traceMsgPrefix = "SCORM.API.find",
|
|
99
|
+
trace = pipwerks.UTILS.trace,
|
|
100
|
+
scorm = pipwerks.SCORM;
|
|
101
|
+
|
|
102
|
+
while ((!win.API && !win.API_1484_11) &&
|
|
103
|
+
(win.parent) &&
|
|
104
|
+
(win.parent != win) &&
|
|
105
|
+
(findAttempts <= findAttemptLimit)) {
|
|
106
|
+
|
|
107
|
+
findAttempts++;
|
|
108
|
+
win = win.parent;
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//If SCORM version is specified by user, look for specific API
|
|
113
|
+
if (scorm.version) {
|
|
114
|
+
|
|
115
|
+
switch (scorm.version) {
|
|
116
|
+
|
|
117
|
+
case "2004":
|
|
118
|
+
|
|
119
|
+
if (win.API_1484_11) {
|
|
120
|
+
|
|
121
|
+
API = win.API_1484_11;
|
|
122
|
+
|
|
123
|
+
} else {
|
|
124
|
+
|
|
125
|
+
trace(traceMsgPrefix + ": SCORM version 2004 was specified by user, but API_1484_11 cannot be found.");
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
break;
|
|
130
|
+
|
|
131
|
+
case "1.2":
|
|
132
|
+
|
|
133
|
+
if (win.API) {
|
|
134
|
+
|
|
135
|
+
API = win.API;
|
|
136
|
+
|
|
137
|
+
} else {
|
|
138
|
+
|
|
139
|
+
trace(traceMsgPrefix + ": SCORM version 1.2 was specified by user, but API cannot be found.");
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
break;
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
} else { //If SCORM version not specified by user, look for APIs
|
|
148
|
+
|
|
149
|
+
if (win.API_1484_11) { //SCORM 2004-specific API.
|
|
150
|
+
|
|
151
|
+
scorm.version = "2004"; //Set version
|
|
152
|
+
API = win.API_1484_11;
|
|
153
|
+
|
|
154
|
+
} else if (win.API) { //SCORM 1.2-specific API
|
|
155
|
+
|
|
156
|
+
scorm.version = "1.2"; //Set version
|
|
157
|
+
API = win.API;
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (API) {
|
|
164
|
+
|
|
165
|
+
trace(traceMsgPrefix + ": API found. Version: " + scorm.version);
|
|
166
|
+
trace("API: " + API);
|
|
167
|
+
|
|
168
|
+
} else {
|
|
169
|
+
|
|
170
|
+
trace(traceMsgPrefix + ": Error finding API. \nFind attempts: " + findAttempts + ". \nFind attempt limit: " + findAttemptLimit);
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return API;
|
|
175
|
+
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
/* -------------------------------------------------------------------------
|
|
180
|
+
pipwerks.SCORM.API.get()
|
|
181
|
+
Looks for an object named API, first in the current window's frame
|
|
182
|
+
hierarchy and then, if necessary, in the current window's opener window
|
|
183
|
+
hierarchy (if there is an opener window).
|
|
184
|
+
|
|
185
|
+
Parameters: None.
|
|
186
|
+
Returns: Object if API found, null if no API found
|
|
187
|
+
---------------------------------------------------------------------------- */
|
|
188
|
+
|
|
189
|
+
pipwerks.SCORM.API.get = function () {
|
|
190
|
+
|
|
191
|
+
var API = null,
|
|
192
|
+
win = window,
|
|
193
|
+
scorm = pipwerks.SCORM,
|
|
194
|
+
find = scorm.API.find,
|
|
195
|
+
trace = pipwerks.UTILS.trace;
|
|
196
|
+
|
|
197
|
+
API = find(win);
|
|
198
|
+
|
|
199
|
+
if (!API && win.parent && win.parent != win) {
|
|
200
|
+
API = find(win.parent);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!API && win.top && win.top.opener) {
|
|
204
|
+
API = find(win.top.opener);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//Special handling for Plateau
|
|
208
|
+
//Thanks to Joseph Venditti for the patch
|
|
209
|
+
if (!API && win.top && win.top.opener && win.top.opener.document) {
|
|
210
|
+
API = find(win.top.opener.document);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (API) {
|
|
214
|
+
scorm.API.isFound = true;
|
|
215
|
+
} else {
|
|
216
|
+
trace("API.get failed: Can't find the API!");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return API;
|
|
220
|
+
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
/* -------------------------------------------------------------------------
|
|
225
|
+
pipwerks.SCORM.API.getHandle()
|
|
226
|
+
Returns the handle to API object if it was previously set
|
|
227
|
+
|
|
228
|
+
Parameters: None.
|
|
229
|
+
Returns: Object (the pipwerks.SCORM.API.handle variable).
|
|
230
|
+
---------------------------------------------------------------------------- */
|
|
231
|
+
|
|
232
|
+
pipwerks.SCORM.API.getHandle = function () {
|
|
233
|
+
|
|
234
|
+
var API = pipwerks.SCORM.API;
|
|
235
|
+
|
|
236
|
+
if (!API.handle && !API.isFound) {
|
|
237
|
+
|
|
238
|
+
API.handle = API.get();
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return API.handle;
|
|
243
|
+
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
// ------------------------------------------------------------------------- //
|
|
248
|
+
// --- pipwerks.SCORM.connection functions --------------------------------- //
|
|
249
|
+
// ------------------------------------------------------------------------- //
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
/* -------------------------------------------------------------------------
|
|
253
|
+
pipwerks.SCORM.connection.initialize()
|
|
254
|
+
Tells the LMS to initiate the communication session.
|
|
255
|
+
|
|
256
|
+
Parameters: None
|
|
257
|
+
Returns: Boolean
|
|
258
|
+
---------------------------------------------------------------------------- */
|
|
259
|
+
|
|
260
|
+
pipwerks.SCORM.connection.initialize = function () {
|
|
261
|
+
|
|
262
|
+
var success = false,
|
|
263
|
+
scorm = pipwerks.SCORM,
|
|
264
|
+
completionStatus = scorm.data.completionStatus,
|
|
265
|
+
trace = pipwerks.UTILS.trace,
|
|
266
|
+
makeBoolean = pipwerks.UTILS.StringToBoolean,
|
|
267
|
+
debug = scorm.debug,
|
|
268
|
+
traceMsgPrefix = "SCORM.connection.initialize ";
|
|
269
|
+
|
|
270
|
+
trace("connection.initialize called.");
|
|
271
|
+
|
|
272
|
+
if (!scorm.connection.isActive) {
|
|
273
|
+
|
|
274
|
+
var API = scorm.API.getHandle(),
|
|
275
|
+
errorCode = 0;
|
|
276
|
+
|
|
277
|
+
if (API) {
|
|
278
|
+
|
|
279
|
+
switch (scorm.version) {
|
|
280
|
+
case "1.2":
|
|
281
|
+
success = makeBoolean(API.LMSInitialize(""));
|
|
282
|
+
break;
|
|
283
|
+
case "2004":
|
|
284
|
+
success = makeBoolean(API.Initialize(""));
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (success) {
|
|
289
|
+
|
|
290
|
+
//Double-check that connection is active and working before returning 'true' boolean
|
|
291
|
+
errorCode = debug.getCode();
|
|
292
|
+
|
|
293
|
+
if (errorCode !== null && errorCode === 0) {
|
|
294
|
+
|
|
295
|
+
scorm.connection.isActive = true;
|
|
296
|
+
|
|
297
|
+
if (scorm.handleCompletionStatus) {
|
|
298
|
+
|
|
299
|
+
//Automatically set new launches to incomplete
|
|
300
|
+
completionStatus = scorm.status("get");
|
|
301
|
+
|
|
302
|
+
if (completionStatus) {
|
|
303
|
+
|
|
304
|
+
switch (completionStatus) {
|
|
305
|
+
|
|
306
|
+
//Both SCORM 1.2 and 2004
|
|
307
|
+
case "not attempted":
|
|
308
|
+
scorm.status("set", "incomplete");
|
|
309
|
+
break;
|
|
310
|
+
|
|
311
|
+
//SCORM 2004 only
|
|
312
|
+
case "unknown":
|
|
313
|
+
scorm.status("set", "incomplete");
|
|
314
|
+
break;
|
|
315
|
+
|
|
316
|
+
//Additional options, presented here in case you'd like to use them
|
|
317
|
+
//case "completed" : break;
|
|
318
|
+
//case "incomplete" : break;
|
|
319
|
+
//case "passed" : break; //SCORM 1.2 only
|
|
320
|
+
//case "failed" : break; //SCORM 1.2 only
|
|
321
|
+
//case "browsed" : break; //SCORM 1.2 only
|
|
322
|
+
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
//Commit changes
|
|
326
|
+
scorm.save();
|
|
327
|
+
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
} else {
|
|
333
|
+
|
|
334
|
+
success = false;
|
|
335
|
+
trace(traceMsgPrefix + "failed. \nError code: " + errorCode + " \nError info: " + debug.getInfo(errorCode));
|
|
336
|
+
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
} else {
|
|
340
|
+
|
|
341
|
+
errorCode = debug.getCode();
|
|
342
|
+
|
|
343
|
+
if (errorCode !== null && errorCode !== 0) {
|
|
344
|
+
|
|
345
|
+
trace(traceMsgPrefix + "failed. \nError code: " + errorCode + " \nError info: " + debug.getInfo(errorCode));
|
|
346
|
+
|
|
347
|
+
} else {
|
|
348
|
+
|
|
349
|
+
trace(traceMsgPrefix + "failed: No response from server.");
|
|
350
|
+
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
} else {
|
|
355
|
+
|
|
356
|
+
trace(traceMsgPrefix + "failed: API is null.");
|
|
357
|
+
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
} else {
|
|
361
|
+
|
|
362
|
+
trace(traceMsgPrefix + "aborted: Connection already active.");
|
|
363
|
+
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return success;
|
|
367
|
+
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
/* -------------------------------------------------------------------------
|
|
372
|
+
pipwerks.SCORM.connection.terminate()
|
|
373
|
+
Tells the LMS to terminate the communication session
|
|
374
|
+
|
|
375
|
+
Parameters: None
|
|
376
|
+
Returns: Boolean
|
|
377
|
+
---------------------------------------------------------------------------- */
|
|
378
|
+
|
|
379
|
+
pipwerks.SCORM.connection.terminate = function () {
|
|
380
|
+
|
|
381
|
+
var success = false,
|
|
382
|
+
scorm = pipwerks.SCORM,
|
|
383
|
+
exitStatus = scorm.data.exitStatus,
|
|
384
|
+
completionStatus = scorm.data.completionStatus,
|
|
385
|
+
trace = pipwerks.UTILS.trace,
|
|
386
|
+
makeBoolean = pipwerks.UTILS.StringToBoolean,
|
|
387
|
+
debug = scorm.debug,
|
|
388
|
+
traceMsgPrefix = "SCORM.connection.terminate ";
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
if (scorm.connection.isActive) {
|
|
392
|
+
|
|
393
|
+
var API = scorm.API.getHandle(),
|
|
394
|
+
errorCode = 0;
|
|
395
|
+
|
|
396
|
+
if (API) {
|
|
397
|
+
|
|
398
|
+
if (scorm.handleExitMode && !exitStatus) {
|
|
399
|
+
|
|
400
|
+
if (completionStatus !== "completed" && completionStatus !== "passed") {
|
|
401
|
+
|
|
402
|
+
switch (scorm.version) {
|
|
403
|
+
case "1.2":
|
|
404
|
+
success = scorm.set("cmi.core.exit", "suspend");
|
|
405
|
+
break;
|
|
406
|
+
case "2004":
|
|
407
|
+
success = scorm.set("cmi.exit", "suspend");
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
} else {
|
|
412
|
+
|
|
413
|
+
switch (scorm.version) {
|
|
414
|
+
case "1.2":
|
|
415
|
+
success = scorm.set("cmi.core.exit", "logout");
|
|
416
|
+
break;
|
|
417
|
+
case "2004":
|
|
418
|
+
success = scorm.set("cmi.exit", "normal");
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
//Ensure we persist the data for 1.2 - not required for 2004 where an implicit commit is applied during the Terminate
|
|
427
|
+
success = (scorm.version === "1.2") ? scorm.save() : true;
|
|
428
|
+
|
|
429
|
+
if (success) {
|
|
430
|
+
|
|
431
|
+
switch (scorm.version) {
|
|
432
|
+
case "1.2":
|
|
433
|
+
success = makeBoolean(API.LMSFinish(""));
|
|
434
|
+
break;
|
|
435
|
+
case "2004":
|
|
436
|
+
success = makeBoolean(API.Terminate(""));
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (success) {
|
|
441
|
+
|
|
442
|
+
scorm.connection.isActive = false;
|
|
443
|
+
|
|
444
|
+
} else {
|
|
445
|
+
|
|
446
|
+
errorCode = debug.getCode();
|
|
447
|
+
trace(traceMsgPrefix + "failed. \nError code: " + errorCode + " \nError info: " + debug.getInfo(errorCode));
|
|
448
|
+
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
} else {
|
|
454
|
+
|
|
455
|
+
trace(traceMsgPrefix + "failed: API is null.");
|
|
456
|
+
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
} else {
|
|
460
|
+
|
|
461
|
+
trace(traceMsgPrefix + "aborted: Connection already terminated.");
|
|
462
|
+
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return success;
|
|
466
|
+
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
// ------------------------------------------------------------------------- //
|
|
471
|
+
// --- pipwerks.SCORM.data functions --------------------------------------- //
|
|
472
|
+
// ------------------------------------------------------------------------- //
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
/* -------------------------------------------------------------------------
|
|
476
|
+
pipwerks.SCORM.data.get(parameter)
|
|
477
|
+
Requests information from the LMS.
|
|
478
|
+
|
|
479
|
+
Parameter: parameter (string, name of the SCORM data model element)
|
|
480
|
+
Returns: string (the value of the specified data model element)
|
|
481
|
+
---------------------------------------------------------------------------- */
|
|
482
|
+
|
|
483
|
+
pipwerks.SCORM.data.get = function (parameter) {
|
|
484
|
+
|
|
485
|
+
var value = null,
|
|
486
|
+
scorm = pipwerks.SCORM,
|
|
487
|
+
trace = pipwerks.UTILS.trace,
|
|
488
|
+
debug = scorm.debug,
|
|
489
|
+
traceMsgPrefix = "SCORM.data.get('" + parameter + "') ";
|
|
490
|
+
|
|
491
|
+
if (scorm.connection.isActive) {
|
|
492
|
+
|
|
493
|
+
var API = scorm.API.getHandle(),
|
|
494
|
+
errorCode = 0;
|
|
495
|
+
|
|
496
|
+
if (API) {
|
|
497
|
+
|
|
498
|
+
switch (scorm.version) {
|
|
499
|
+
case "1.2":
|
|
500
|
+
value = API.LMSGetValue(parameter);
|
|
501
|
+
break;
|
|
502
|
+
case "2004":
|
|
503
|
+
value = API.GetValue(parameter);
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
errorCode = debug.getCode();
|
|
508
|
+
|
|
509
|
+
//GetValue returns an empty string on errors
|
|
510
|
+
//If value is an empty string, check errorCode to make sure there are no errors
|
|
511
|
+
if (value !== "" || errorCode === 0) {
|
|
512
|
+
|
|
513
|
+
//GetValue is successful.
|
|
514
|
+
//If parameter is lesson_status/completion_status or exit status, let's
|
|
515
|
+
//grab the value and cache it so we can check it during connection.terminate()
|
|
516
|
+
switch (parameter) {
|
|
517
|
+
|
|
518
|
+
case "cmi.core.lesson_status":
|
|
519
|
+
case "cmi.completion_status":
|
|
520
|
+
scorm.data.completionStatus = value;
|
|
521
|
+
break;
|
|
522
|
+
|
|
523
|
+
case "cmi.core.exit":
|
|
524
|
+
case "cmi.exit":
|
|
525
|
+
scorm.data.exitStatus = value;
|
|
526
|
+
break;
|
|
527
|
+
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
} else {
|
|
531
|
+
|
|
532
|
+
trace(traceMsgPrefix + "failed. \nError code: " + errorCode + "\nError info: " + debug.getInfo(errorCode));
|
|
533
|
+
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
} else {
|
|
537
|
+
|
|
538
|
+
trace(traceMsgPrefix + "failed: API is null.");
|
|
539
|
+
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
} else {
|
|
543
|
+
|
|
544
|
+
trace(traceMsgPrefix + "failed: API connection is inactive.");
|
|
545
|
+
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
trace(traceMsgPrefix + " value: " + value);
|
|
549
|
+
|
|
550
|
+
return String(value);
|
|
551
|
+
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
/* -------------------------------------------------------------------------
|
|
556
|
+
pipwerks.SCORM.data.set()
|
|
557
|
+
Tells the LMS to assign the value to the named data model element.
|
|
558
|
+
Also stores the SCO's completion status in a variable named
|
|
559
|
+
pipwerks.SCORM.data.completionStatus. This variable is checked whenever
|
|
560
|
+
pipwerks.SCORM.connection.terminate() is invoked.
|
|
561
|
+
|
|
562
|
+
Parameters: parameter (string). The data model element
|
|
563
|
+
value (string). The value for the data model element
|
|
564
|
+
Returns: Boolean
|
|
565
|
+
---------------------------------------------------------------------------- */
|
|
566
|
+
|
|
567
|
+
pipwerks.SCORM.data.set = function (parameter, value) {
|
|
568
|
+
|
|
569
|
+
var success = false,
|
|
570
|
+
scorm = pipwerks.SCORM,
|
|
571
|
+
trace = pipwerks.UTILS.trace,
|
|
572
|
+
makeBoolean = pipwerks.UTILS.StringToBoolean,
|
|
573
|
+
debug = scorm.debug,
|
|
574
|
+
traceMsgPrefix = "SCORM.data.set('" + parameter + "') ";
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
if (scorm.connection.isActive) {
|
|
578
|
+
|
|
579
|
+
var API = scorm.API.getHandle(),
|
|
580
|
+
errorCode = 0;
|
|
581
|
+
|
|
582
|
+
if (API) {
|
|
583
|
+
|
|
584
|
+
switch (scorm.version) {
|
|
585
|
+
case "1.2":
|
|
586
|
+
success = makeBoolean(API.LMSSetValue(parameter, value));
|
|
587
|
+
break;
|
|
588
|
+
case "2004":
|
|
589
|
+
success = makeBoolean(API.SetValue(parameter, value));
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (success) {
|
|
594
|
+
|
|
595
|
+
if (parameter === "cmi.core.lesson_status" || parameter === "cmi.completion_status") {
|
|
596
|
+
|
|
597
|
+
scorm.data.completionStatus = value;
|
|
598
|
+
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
} else {
|
|
602
|
+
|
|
603
|
+
errorCode = debug.getCode();
|
|
604
|
+
|
|
605
|
+
trace(traceMsgPrefix + "failed. \nError code: " + errorCode + ". \nError info: " + debug.getInfo(errorCode));
|
|
606
|
+
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
} else {
|
|
610
|
+
|
|
611
|
+
trace(traceMsgPrefix + "failed: API is null.");
|
|
612
|
+
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
} else {
|
|
616
|
+
|
|
617
|
+
trace(traceMsgPrefix + "failed: API connection is inactive.");
|
|
618
|
+
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
trace(traceMsgPrefix + " value: " + value);
|
|
622
|
+
|
|
623
|
+
return success;
|
|
624
|
+
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
/* -------------------------------------------------------------------------
|
|
629
|
+
pipwerks.SCORM.data.save()
|
|
630
|
+
Instructs the LMS to persist all data to this point in the session
|
|
631
|
+
|
|
632
|
+
Parameters: None
|
|
633
|
+
Returns: Boolean
|
|
634
|
+
---------------------------------------------------------------------------- */
|
|
635
|
+
|
|
636
|
+
pipwerks.SCORM.data.save = function () {
|
|
637
|
+
|
|
638
|
+
var success = false,
|
|
639
|
+
scorm = pipwerks.SCORM,
|
|
640
|
+
trace = pipwerks.UTILS.trace,
|
|
641
|
+
makeBoolean = pipwerks.UTILS.StringToBoolean,
|
|
642
|
+
traceMsgPrefix = "SCORM.data.save failed";
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
if (scorm.connection.isActive) {
|
|
646
|
+
|
|
647
|
+
var API = scorm.API.getHandle();
|
|
648
|
+
|
|
649
|
+
if (API) {
|
|
650
|
+
|
|
651
|
+
switch (scorm.version) {
|
|
652
|
+
case "1.2":
|
|
653
|
+
success = makeBoolean(API.LMSCommit(""));
|
|
654
|
+
break;
|
|
655
|
+
case "2004":
|
|
656
|
+
success = makeBoolean(API.Commit(""));
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
} else {
|
|
661
|
+
|
|
662
|
+
trace(traceMsgPrefix + ": API is null.");
|
|
663
|
+
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
} else {
|
|
667
|
+
|
|
668
|
+
trace(traceMsgPrefix + ": API connection is inactive.");
|
|
669
|
+
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
return success;
|
|
673
|
+
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
pipwerks.SCORM.status = function (action, status) {
|
|
678
|
+
|
|
679
|
+
var success = false,
|
|
680
|
+
scorm = pipwerks.SCORM,
|
|
681
|
+
trace = pipwerks.UTILS.trace,
|
|
682
|
+
traceMsgPrefix = "SCORM.getStatus failed",
|
|
683
|
+
cmi = "";
|
|
684
|
+
|
|
685
|
+
if (action !== null) {
|
|
686
|
+
|
|
687
|
+
switch (scorm.version) {
|
|
688
|
+
case "1.2":
|
|
689
|
+
cmi = "cmi.core.lesson_status";
|
|
690
|
+
break;
|
|
691
|
+
case "2004":
|
|
692
|
+
cmi = "cmi.completion_status";
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
switch (action) {
|
|
697
|
+
|
|
698
|
+
case "get":
|
|
699
|
+
success = scorm.data.get(cmi);
|
|
700
|
+
break;
|
|
701
|
+
|
|
702
|
+
case "set":
|
|
703
|
+
if (status !== null) {
|
|
704
|
+
|
|
705
|
+
success = scorm.data.set(cmi, status);
|
|
706
|
+
|
|
707
|
+
} else {
|
|
708
|
+
|
|
709
|
+
success = false;
|
|
710
|
+
trace(traceMsgPrefix + ": status was not specified.");
|
|
711
|
+
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
break;
|
|
715
|
+
|
|
716
|
+
default:
|
|
717
|
+
success = false;
|
|
718
|
+
trace(traceMsgPrefix + ": no valid action was specified.");
|
|
719
|
+
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
} else {
|
|
723
|
+
|
|
724
|
+
trace(traceMsgPrefix + ": action was not specified.");
|
|
725
|
+
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
return success;
|
|
729
|
+
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
// ------------------------------------------------------------------------- //
|
|
734
|
+
// --- pipwerks.SCORM.debug functions -------------------------------------- //
|
|
735
|
+
// ------------------------------------------------------------------------- //
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
/* -------------------------------------------------------------------------
|
|
739
|
+
pipwerks.SCORM.debug.getCode
|
|
740
|
+
Requests the error code for the current error state from the LMS
|
|
741
|
+
|
|
742
|
+
Parameters: None
|
|
743
|
+
Returns: Integer (the last error code).
|
|
744
|
+
---------------------------------------------------------------------------- */
|
|
745
|
+
|
|
746
|
+
pipwerks.SCORM.debug.getCode = function () {
|
|
747
|
+
|
|
748
|
+
var scorm = pipwerks.SCORM,
|
|
749
|
+
API = scorm.API.getHandle(),
|
|
750
|
+
trace = pipwerks.UTILS.trace,
|
|
751
|
+
code = 0;
|
|
752
|
+
|
|
753
|
+
if (API) {
|
|
754
|
+
|
|
755
|
+
switch (scorm.version) {
|
|
756
|
+
case "1.2":
|
|
757
|
+
code = parseInt(API.LMSGetLastError(), 10);
|
|
758
|
+
break;
|
|
759
|
+
case "2004":
|
|
760
|
+
code = parseInt(API.GetLastError(), 10);
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
} else {
|
|
765
|
+
|
|
766
|
+
trace("SCORM.debug.getCode failed: API is null.");
|
|
767
|
+
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return code;
|
|
771
|
+
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
/* -------------------------------------------------------------------------
|
|
776
|
+
pipwerks.SCORM.debug.getInfo()
|
|
777
|
+
"Used by a SCO to request the textual description for the error code
|
|
778
|
+
specified by the value of [errorCode]."
|
|
779
|
+
|
|
780
|
+
Parameters: errorCode (integer).
|
|
781
|
+
Returns: String.
|
|
782
|
+
----------------------------------------------------------------------------- */
|
|
783
|
+
|
|
784
|
+
pipwerks.SCORM.debug.getInfo = function (errorCode) {
|
|
785
|
+
|
|
786
|
+
var scorm = pipwerks.SCORM,
|
|
787
|
+
API = scorm.API.getHandle(),
|
|
788
|
+
trace = pipwerks.UTILS.trace,
|
|
789
|
+
result = "";
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
if (API) {
|
|
793
|
+
|
|
794
|
+
switch (scorm.version) {
|
|
795
|
+
case "1.2":
|
|
796
|
+
result = API.LMSGetErrorString(errorCode.toString());
|
|
797
|
+
break;
|
|
798
|
+
case "2004":
|
|
799
|
+
result = API.GetErrorString(errorCode.toString());
|
|
800
|
+
break;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
} else {
|
|
804
|
+
|
|
805
|
+
trace("SCORM.debug.getInfo failed: API is null.");
|
|
806
|
+
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return String(result);
|
|
810
|
+
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
/* -------------------------------------------------------------------------
|
|
815
|
+
pipwerks.SCORM.debug.getDiagnosticInfo
|
|
816
|
+
"Exists for LMS specific use. It allows the LMS to define additional
|
|
817
|
+
diagnostic information through the API Instance."
|
|
818
|
+
|
|
819
|
+
Parameters: errorCode (integer).
|
|
820
|
+
Returns: String (Additional diagnostic information about the given error code).
|
|
821
|
+
---------------------------------------------------------------------------- */
|
|
822
|
+
|
|
823
|
+
pipwerks.SCORM.debug.getDiagnosticInfo = function (errorCode) {
|
|
824
|
+
|
|
825
|
+
var scorm = pipwerks.SCORM,
|
|
826
|
+
API = scorm.API.getHandle(),
|
|
827
|
+
trace = pipwerks.UTILS.trace,
|
|
828
|
+
result = "";
|
|
829
|
+
|
|
830
|
+
if (API) {
|
|
831
|
+
|
|
832
|
+
switch (scorm.version) {
|
|
833
|
+
case "1.2":
|
|
834
|
+
result = API.LMSGetDiagnostic(errorCode);
|
|
835
|
+
break;
|
|
836
|
+
case "2004":
|
|
837
|
+
result = API.GetDiagnostic(errorCode);
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
} else {
|
|
842
|
+
|
|
843
|
+
trace("SCORM.debug.getDiagnosticInfo failed: API is null.");
|
|
844
|
+
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return String(result);
|
|
848
|
+
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
// ------------------------------------------------------------------------- //
|
|
853
|
+
// --- Shortcuts! ---------------------------------------------------------- //
|
|
854
|
+
// ------------------------------------------------------------------------- //
|
|
855
|
+
|
|
856
|
+
// Because nobody likes typing verbose code.
|
|
857
|
+
|
|
858
|
+
pipwerks.SCORM.init = pipwerks.SCORM.connection.initialize;
|
|
859
|
+
pipwerks.SCORM.get = pipwerks.SCORM.data.get;
|
|
860
|
+
pipwerks.SCORM.set = pipwerks.SCORM.data.set;
|
|
861
|
+
pipwerks.SCORM.save = pipwerks.SCORM.data.save;
|
|
862
|
+
pipwerks.SCORM.quit = pipwerks.SCORM.connection.terminate;
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
// ------------------------------------------------------------------------- //
|
|
867
|
+
// --- pipwerks.UTILS functions -------------------------------------------- //
|
|
868
|
+
// ------------------------------------------------------------------------- //
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
/* -------------------------------------------------------------------------
|
|
872
|
+
pipwerks.UTILS.StringToBoolean()
|
|
873
|
+
Converts 'boolean strings' into actual valid booleans.
|
|
874
|
+
|
|
875
|
+
(Most values returned from the API are the strings "true" and "false".)
|
|
876
|
+
|
|
877
|
+
Parameters: String
|
|
878
|
+
Returns: Boolean
|
|
879
|
+
---------------------------------------------------------------------------- */
|
|
880
|
+
|
|
881
|
+
pipwerks.UTILS.StringToBoolean = function (value) {
|
|
882
|
+
var t = typeof value;
|
|
883
|
+
switch (t) {
|
|
884
|
+
//typeof new String("true") === "object", so handle objects as string via fall-through.
|
|
885
|
+
//See https://github.com/pipwerks/scorm-api-wrapper/issues/3
|
|
886
|
+
case "object":
|
|
887
|
+
case "string":
|
|
888
|
+
return (/(true|1)/i).test(value);
|
|
889
|
+
case "number":
|
|
890
|
+
return !!value;
|
|
891
|
+
case "boolean":
|
|
892
|
+
return value;
|
|
893
|
+
case "undefined":
|
|
894
|
+
return null;
|
|
895
|
+
default:
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
/* -------------------------------------------------------------------------
|
|
902
|
+
pipwerks.UTILS.trace()
|
|
903
|
+
Displays error messages when in debug mode.
|
|
904
|
+
|
|
905
|
+
Parameters: msg (string)
|
|
906
|
+
Return: None
|
|
907
|
+
---------------------------------------------------------------------------- */
|
|
908
|
+
|
|
909
|
+
pipwerks.UTILS.trace = function (msg) {
|
|
910
|
+
|
|
911
|
+
if (pipwerks.debug.isActive) {
|
|
912
|
+
|
|
913
|
+
if (window.console && window.console.log) {
|
|
914
|
+
window.console.log(msg);
|
|
915
|
+
} else {
|
|
916
|
+
//alert(msg);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
return pipwerks;
|
|
923
|
+
|
|
924
|
+
}));
|
|
925
|
+
|
|
926
|
+
// =============================================================================
|
|
927
|
+
// ESM Export for Vite/modern bundlers
|
|
928
|
+
// Added to enable ES module imports while keeping original UMD intact
|
|
929
|
+
// =============================================================================
|
|
930
|
+
export default (typeof window !== 'undefined' && window.pipwerks) || (typeof global !== 'undefined' && global.pipwerks);
|
|
931
|
+
export const SCORM = (typeof window !== 'undefined' && window.pipwerks?.SCORM) || (typeof global !== 'undefined' && global.pipwerks?.SCORM);
|