@citolab/qti-components 7.0.4 → 7.0.5
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/cdn/chunks/chunk-4UJBK6JO.js +1 -0
- package/cdn/chunks/chunk-5FCXUJAG.js +23 -0
- package/cdn/chunks/chunk-5O3Z7TDV.js +1 -0
- package/cdn/chunks/chunk-65LFT33L.js +8 -0
- package/cdn/chunks/chunk-6D25UFJR.js +8 -0
- package/cdn/chunks/chunk-6DMSHH5X.js +0 -0
- package/cdn/chunks/chunk-6UGPNL7M.js +1 -0
- package/cdn/chunks/chunk-CFXQCNG6.js +3523 -0
- package/cdn/chunks/chunk-CSUKVUZF.js +3 -0
- package/cdn/chunks/chunk-CSY3WI5A.js +1 -0
- package/cdn/chunks/chunk-DAZR7RUI.js +0 -0
- package/cdn/chunks/chunk-EHK76KRT.js +1 -0
- package/cdn/chunks/chunk-EOPEMJS3.js +0 -0
- package/cdn/chunks/chunk-G5O7EN45.js +5 -0
- package/cdn/chunks/chunk-GEFUIFM7.js +0 -0
- package/cdn/chunks/chunk-JLNHEMQG.js +1 -0
- package/cdn/chunks/chunk-LPWIM7QJ.js +902 -0
- package/cdn/chunks/chunk-M3YRM3AV.js +1 -0
- package/cdn/chunks/chunk-M6BOWL2U.js +1 -0
- package/cdn/chunks/chunk-P5IE36FO.js +8 -0
- package/cdn/chunks/chunk-PXH5KN5O.js +1 -0
- package/cdn/chunks/chunk-RBEI6NIF.js +1 -0
- package/cdn/chunks/chunk-SMKIYFFI.js +1 -0
- package/cdn/chunks/chunk-SRLMW23F.js +0 -0
- package/cdn/chunks/chunk-T3YDLD2H.js +11 -0
- package/cdn/chunks/chunk-T4HD2C4F.js +1 -0
- package/cdn/chunks/chunk-T6IXJ4W4.js +1 -0
- package/cdn/chunks/chunk-TFAUBGP2.js +0 -0
- package/cdn/chunks/chunk-UIEC4LXR.js +17 -0
- package/cdn/chunks/chunk-V44O3GTW.js +0 -0
- package/cdn/chunks/chunk-V6B54FQW.js +5 -0
- package/cdn/chunks/chunk-V6KX6BQN.js +1 -0
- package/cdn/chunks/chunk-VYANBI35.js +1 -0
- package/cdn/chunks/chunk-XUJ7TXHW.js +1 -0
- package/cdn/chunks/chunk-ZIZLFFSG.js +0 -0
- package/cdn/index.css +1 -0
- package/cdn/index.global.js +45 -45
- package/cdn/index.js +196 -476
- package/cdn/qti-components/index.global.js +226 -0
- package/cdn/qti-components/index.js +924 -0
- package/cdn/qti-item/components/index.css +1 -0
- package/cdn/qti-item/components/index.global.js +149 -0
- package/cdn/qti-item/components/index.js +3549 -0
- package/cdn/qti-item/components/item-container.css +1 -0
- package/cdn/qti-item/components/item-container.global.js +149 -0
- package/cdn/qti-item/components/item-container.js +3549 -0
- package/cdn/qti-item/index.css +1 -0
- package/cdn/qti-item/index.global.js +149 -0
- package/cdn/qti-item/index.js +3549 -0
- package/cdn/qti-item/qti-item.global.js +114 -0
- package/cdn/qti-item/qti-item.js +1 -0
- package/cdn/qti-loader/index.global.js +1 -0
- package/cdn/qti-loader/index.js +23 -0
- package/cdn/qti-test/components/index.css +1 -0
- package/cdn/qti-test/components/index.global.js +242 -0
- package/cdn/qti-test/components/index.js +3598 -0
- package/cdn/qti-test/components/styles.global.js +44 -0
- package/cdn/qti-test/components/styles.js +17 -0
- package/cdn/qti-test/components/test-component.abstract.global.js +170 -0
- package/cdn/qti-test/components/test-component.abstract.js +1 -0
- package/cdn/qti-test/components/test-container.css +1 -0
- package/cdn/qti-test/components/test-container.global.js +149 -0
- package/cdn/qti-test/components/test-container.js +3549 -0
- package/cdn/qti-test/components/test-item-link.global.js +170 -0
- package/cdn/qti-test/components/test-item-link.js +24 -0
- package/cdn/qti-test/components/test-next.global.js +170 -0
- package/cdn/qti-test/components/test-next.js +24 -0
- package/cdn/qti-test/components/test-next.spec.css +1 -0
- package/cdn/qti-test/components/test-next.spec.global.js +297 -0
- package/cdn/qti-test/components/test-next.spec.js +5215 -0
- package/cdn/qti-test/components/test-paging-buttons-stamp.global.js +207 -0
- package/cdn/qti-test/components/test-paging-buttons-stamp.js +3 -0
- package/cdn/qti-test/components/test-prev.global.js +170 -0
- package/cdn/qti-test/components/test-prev.js +24 -0
- package/cdn/qti-test/components/test-view.global.js +170 -0
- package/cdn/qti-test/components/test-view.js +11 -0
- package/cdn/qti-test/context/index.global.js +58 -0
- package/cdn/qti-test/context/index.js +1 -0
- package/cdn/qti-test/context/test.context.global.js +58 -0
- package/cdn/qti-test/context/test.context.js +1 -0
- package/cdn/qti-test/index.css +1 -0
- package/cdn/qti-test/index.global.js +242 -0
- package/cdn/qti-test/index.js +3598 -0
- package/cdn/qti-test/mixins/index.global.js +1 -0
- package/cdn/qti-test/mixins/index.js +23 -0
- package/cdn/qti-test/mixins/test-loader.mixin.global.js +1 -0
- package/cdn/qti-test/mixins/test-loader.mixin.js +23 -0
- package/cdn/qti-test/mixins/test-navigation.mixin.global.js +1 -0
- package/cdn/qti-test/mixins/test-navigation.mixin.js +1 -0
- package/cdn/qti-test/mixins/test-view.mixin.global.js +1 -0
- package/cdn/qti-test/mixins/test-view.mixin.js +1 -0
- package/cdn/qti-test/qti-assessment-test/index.global.js +170 -0
- package/cdn/qti-test/qti-assessment-test/index.js +1 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-item-ref.global.js +170 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-item-ref.js +1 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-section.global.js +170 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-section.js +1 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-test.global.js +170 -0
- package/cdn/qti-test/qti-assessment-test/qti-assessment-test.js +1 -0
- package/cdn/qti-test/qti-assessment-test/qti-test-part.global.js +114 -0
- package/cdn/qti-test/qti-assessment-test/qti-test-part.js +1 -0
- package/cdn/qti-test/qti-test.global.js +170 -0
- package/cdn/qti-test/qti-test.js +23 -0
- package/cdn/qti-test/test-base.global.js +170 -0
- package/cdn/qti-test/test-base.js +1 -0
- package/cdn/qti-transformers/index.global.js +1 -0
- package/cdn/qti-transformers/index.js +23 -0
- package/dist/chunks/chunk-3G2DDBJW.js +44 -0
- package/dist/chunks/chunk-3G2DDBJW.js.map +1 -0
- package/dist/chunks/chunk-3NLCJYSX.js +1 -0
- package/dist/chunks/chunk-3NLCJYSX.js.map +1 -0
- package/dist/chunks/chunk-3OXGDCSU.js +6253 -0
- package/dist/chunks/chunk-3OXGDCSU.js.map +1 -0
- package/dist/chunks/chunk-3ROZMGAN.js +43 -0
- package/dist/chunks/chunk-3ROZMGAN.js.map +1 -0
- package/dist/chunks/chunk-4O5F7WV7.js +30 -0
- package/dist/chunks/chunk-4O5F7WV7.js.map +1 -0
- package/dist/chunks/chunk-6YE2KJ4C.js +55 -0
- package/dist/chunks/chunk-6YE2KJ4C.js.map +1 -0
- package/dist/chunks/chunk-AAQCM2FP.js +56 -0
- package/dist/chunks/chunk-AAQCM2FP.js.map +1 -0
- package/dist/chunks/chunk-D3RGDWKP.js +37 -0
- package/dist/chunks/chunk-D3RGDWKP.js.map +1 -0
- package/dist/chunks/chunk-DJLE6EV2.js +36 -0
- package/dist/chunks/chunk-DJLE6EV2.js.map +1 -0
- package/dist/chunks/chunk-ELDMXTUQ.js +31 -0
- package/dist/chunks/chunk-ELDMXTUQ.js.map +1 -0
- package/dist/chunks/chunk-EW5CTHAD.js +1 -0
- package/dist/chunks/chunk-EW5CTHAD.js.map +1 -0
- package/dist/chunks/chunk-HWA4A3SR.js +50 -0
- package/dist/chunks/chunk-HWA4A3SR.js.map +1 -0
- package/dist/chunks/chunk-IKZWK2C5.js +1 -0
- package/dist/chunks/chunk-IKZWK2C5.js.map +1 -0
- package/dist/chunks/chunk-IP7JSYO6.js +1 -0
- package/dist/chunks/chunk-IP7JSYO6.js.map +1 -0
- package/dist/chunks/chunk-JE6BMXZU.js +94 -0
- package/dist/chunks/chunk-JE6BMXZU.js.map +1 -0
- package/dist/chunks/chunk-JSPJGWGT.js +20 -0
- package/dist/chunks/chunk-JSPJGWGT.js.map +1 -0
- package/dist/chunks/chunk-LKINC6JO.js +118 -0
- package/dist/chunks/chunk-LKINC6JO.js.map +1 -0
- package/dist/chunks/chunk-LROTNPC2.js +94 -0
- package/dist/chunks/chunk-LROTNPC2.js.map +1 -0
- package/dist/chunks/chunk-MTMT2RMF.js +63 -0
- package/dist/chunks/chunk-MTMT2RMF.js.map +1 -0
- package/dist/chunks/chunk-NDJZGJUR.js +65 -0
- package/dist/chunks/chunk-NDJZGJUR.js.map +1 -0
- package/dist/chunks/chunk-OE2LFIH2.js +1 -0
- package/dist/chunks/chunk-OE2LFIH2.js.map +1 -0
- package/dist/chunks/chunk-OJ2XGDWK.js +1 -0
- package/dist/chunks/chunk-OJ2XGDWK.js.map +1 -0
- package/dist/chunks/chunk-PUBGXXTM.js +50 -0
- package/dist/chunks/chunk-PUBGXXTM.js.map +1 -0
- package/dist/chunks/chunk-QRCUNRP5.js +75 -0
- package/dist/chunks/chunk-QRCUNRP5.js.map +1 -0
- package/dist/chunks/chunk-S6JJYCO7.js +51 -0
- package/dist/chunks/chunk-S6JJYCO7.js.map +1 -0
- package/dist/chunks/chunk-U3AALKEP.js +1 -0
- package/dist/chunks/chunk-U3AALKEP.js.map +1 -0
- package/dist/chunks/chunk-UCQFSRYF.js +34 -0
- package/dist/chunks/chunk-UCQFSRYF.js.map +1 -0
- package/dist/chunks/chunk-URGVQ64M.js +1 -0
- package/dist/chunks/chunk-URGVQ64M.js.map +1 -0
- package/dist/chunks/chunk-V4FXK4TP.js +128 -0
- package/dist/chunks/chunk-V4FXK4TP.js.map +1 -0
- package/dist/chunks/chunk-W4B23OIP.js +72 -0
- package/dist/chunks/chunk-W4B23OIP.js.map +1 -0
- package/dist/chunks/chunk-XDFXD3BI.js +10 -0
- package/dist/chunks/chunk-XDFXD3BI.js.map +1 -0
- package/dist/chunks/chunk-XDMSEAYC.js +294 -0
- package/dist/chunks/chunk-XPDS72XY.js +29 -0
- package/dist/chunks/chunk-XPDS72XY.js.map +1 -0
- package/dist/chunks/chunk-Y6UWSECL.js +3529 -0
- package/dist/chunks/chunk-Y6UWSECL.js.map +1 -0
- package/dist/chunks/chunk-ZEFOMZNY.js +78 -0
- package/dist/chunks/chunk-ZEFOMZNY.js.map +1 -0
- package/dist/index-Cvrd4KQA.d.ts +109 -0
- package/dist/index.d.ts +18 -503
- package/dist/index.js +1666 -4206
- package/dist/index.js.map +1 -1
- package/dist/item.css +10 -10
- package/dist/qti-components/index.d.ts +150 -0
- package/dist/qti-components/index.js +6525 -0
- package/dist/qti-components/index.js.map +1 -0
- package/dist/qti-components-jsx.d.ts +93 -147
- package/dist/qti-item/components/index.d.ts +3 -0
- package/dist/qti-item/components/index.js +3856 -0
- package/dist/qti-item/components/index.js.map +1 -0
- package/dist/qti-item/components/item-container.d.ts +40 -0
- package/dist/qti-item/components/item-container.js +3856 -0
- package/dist/qti-item/components/item-container.js.map +1 -0
- package/dist/qti-item/index.d.ts +4 -0
- package/dist/qti-item/index.js +3869 -0
- package/dist/qti-item/index.js.map +1 -0
- package/dist/qti-item/qti-item.d.ts +25 -0
- package/dist/qti-item/qti-item.js +26 -0
- package/dist/qti-item/qti-item.js.map +1 -0
- package/dist/{loader → qti-loader}/index.d.ts +1 -1
- package/dist/{qti-simple-choice-D0GiMrqD.d.ts → qti-simple-choice-DxWcdKHi.d.ts} +30 -40
- package/dist/qti-test/components/index.d.ts +13 -0
- package/dist/qti-test/components/index.js +4144 -0
- package/dist/qti-test/components/index.js.map +1 -0
- package/dist/qti-test/components/styles.d.ts +8 -0
- package/dist/qti-test/components/styles.js +29 -0
- package/dist/qti-test/components/styles.js.map +1 -0
- package/dist/qti-test/components/test-component.abstract.d.ts +23 -0
- package/dist/qti-test/components/test-component.abstract.js +149 -0
- package/dist/qti-test/components/test-component.abstract.js.map +1 -0
- package/dist/qti-test/components/test-container.d.ts +37 -0
- package/dist/qti-test/components/test-container.js +3782 -0
- package/dist/qti-test/components/test-container.js.map +1 -0
- package/dist/qti-test/components/test-item-link.d.ts +21 -0
- package/dist/qti-test/components/test-item-link.js +202 -0
- package/dist/qti-test/components/test-item-link.js.map +1 -0
- package/dist/qti-test/components/test-next.d.ts +32 -0
- package/dist/qti-test/components/test-next.js +209 -0
- package/dist/qti-test/components/test-next.js.map +1 -0
- package/dist/qti-test/components/test-next.spec.d.ts +16 -0
- package/dist/qti-test/components/test-next.spec.js +56915 -0
- package/dist/qti-test/components/test-next.spec.js.map +1 -0
- package/dist/qti-test/components/test-paging-buttons-stamp.d.ts +22 -0
- package/dist/qti-test/components/test-paging-buttons-stamp.js +218 -0
- package/dist/qti-test/components/test-paging-buttons-stamp.js.map +1 -0
- package/dist/qti-test/components/test-prev.d.ts +32 -0
- package/dist/qti-test/components/test-prev.js +209 -0
- package/dist/qti-test/components/test-prev.js.map +1 -0
- package/dist/qti-test/components/test-view.d.ts +27 -0
- package/dist/qti-test/components/test-view.js +209 -0
- package/dist/qti-test/components/test-view.js.map +1 -0
- package/dist/qti-test/context/index.d.ts +6 -0
- package/dist/qti-test/context/index.js +9 -0
- package/dist/qti-test/context/index.js.map +1 -0
- package/dist/qti-test/context/test.context.d.ts +6 -0
- package/dist/qti-test/context/test.context.js +9 -0
- package/dist/qti-test/context/test.context.js.map +1 -0
- package/dist/qti-test/index.d.ts +14 -0
- package/dist/qti-test/index.js +4746 -0
- package/dist/qti-test/index.js.map +1 -0
- package/dist/qti-test/mixins/index.d.ts +8 -0
- package/dist/qti-test/mixins/index.js +350 -0
- package/dist/qti-test/mixins/index.js.map +1 -0
- package/dist/qti-test/mixins/test-loader.mixin.d.ts +8 -0
- package/dist/qti-test/mixins/test-loader.mixin.js +240 -0
- package/dist/qti-test/mixins/test-loader.mixin.js.map +1 -0
- package/dist/qti-test/mixins/test-navigation.mixin.d.ts +22 -0
- package/dist/qti-test/mixins/test-navigation.mixin.js +64 -0
- package/dist/qti-test/mixins/test-navigation.mixin.js.map +1 -0
- package/dist/qti-test/mixins/test-view.mixin.d.ts +6 -0
- package/dist/qti-test/mixins/test-view.mixin.js +50 -0
- package/dist/qti-test/mixins/test-view.mixin.js.map +1 -0
- package/dist/qti-test/qti-assessment-test/index.d.ts +6 -0
- package/dist/qti-test/qti-assessment-test/index.js +221 -0
- package/dist/qti-test/qti-assessment-test/index.js.map +1 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-item-ref.d.ts +6 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-item-ref.js +85 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-item-ref.js.map +1 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-section.d.ts +6 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-section.js +73 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-section.js.map +1 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-test.d.ts +6 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-test.js +54 -0
- package/dist/qti-test/qti-assessment-test/qti-assessment-test.js.map +1 -0
- package/dist/qti-test/qti-assessment-test/qti-test-part.d.ts +19 -0
- package/dist/qti-test/qti-assessment-test/qti-test-part.js +62 -0
- package/dist/qti-test/qti-assessment-test/qti-test-part.js.map +1 -0
- package/dist/qti-test/qti-test.d.ts +68 -0
- package/dist/qti-test/qti-test.js +500 -0
- package/dist/qti-test/qti-test.js.map +1 -0
- package/dist/qti-test/test-base.d.ts +6 -0
- package/dist/qti-test/test-base.js +137 -0
- package/dist/qti-test/test-base.js.map +1 -0
- package/dist/qti-transformers/index.js.map +1 -0
- package/dist/test-base-BJwG9Ie8.d.ts +109 -0
- package/dist/vscode.html-custom-data.json +49 -38
- package/package.json +28 -51
- package/dist/custom-element-eslint-rules.js +0 -329
- package/dist/custom-elements.json +0 -27271
- package/dist/qti-simple-choice-CfgBEvdI.d.ts +0 -1143
- package/dist/qti-simple-choice-UTrFa_RQ.d.ts +0 -1177
- package/dist/qti-simple-choice-zEsDq3c0.d.ts +0 -1147
- /package/dist/{transformers/index.js.map → chunks/chunk-XDMSEAYC.js.map} +0 -0
- /package/dist/{loader → qti-loader}/index.js +0 -0
- /package/dist/{loader → qti-loader}/index.js.map +0 -0
- /package/dist/{transformers → qti-transformers}/index.d.ts +0 -0
- /package/dist/{transformers → qti-transformers}/index.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-test/mixins/test-loader.mixin.ts"],"sourcesContent":["import { LitElement } from 'lit';\nimport { qtiTransformItem } from '../../qti-transformers';\n\n// const setSessionData = <T>(key: string, value?: T): void => sessionStorage.setItem(key, JSON.stringify(value));\n// const getSessionData = <T>(key: string): T | null => (sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key)!) : null);\n\ntype Constructor<T = {}> = abstract new (...args: any[]) => T;\n\ndeclare class TestLoaderInterface {}\nexport const TestLoaderMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n abstract class TestLoaderClass extends superClass {\n // private testURL = '';\n\n constructor(...args: any[]) {\n super(...args);\n\n // this.addEventListener('qti-load-test-request', (e: CustomEvent /* 1. Request the test */) => {\n // const { testURL } = e.detail;\n // if (!testURL) {\n // console.warn(\n // 'No test found, there should be an attribute test-url with the path to the test on the test-container'\n // );\n // } else {\n // this.testURL = testURL;\n // }\n\n // e.detail.promise = (async () => {\n // e.preventDefault(); /* indicates that the event was catched and handled */\n // const api = await qtiTransformTest().load(`${this.testURL}`); /* 6. load the item */\n // return api.htmlDoc(); /* 3. Return html version of the assessment.xml */\n // })();\n // });\n\n this.addEventListener('qti-assessment-test-connected', () => {\n // this.context = getSessionData(`testcontext-${this.testURL}`); /* 4. Set the context */\n });\n\n this.addEventListener('qti-load-item-request' /* 5. Request the item */, ({ detail }: CustomEvent) => {\n // if (!this.testURL) return;\n detail.promise = (async () => {\n const api = await qtiTransformItem().load(\n `${detail.href}`,\n detail.cancelPreviousRequest\n ); /* 6. load the item */\n return api.htmlDoc(); /* 7. Return HTML version of the item.xml */\n })();\n });\n\n this.addEventListener('qti-interaction-changed', _e => {\n /* 8. Interaction changed */\n // const scoreOutcomeIdentifier = qtiAssessmentItem.variables.find(v => v.identifier === 'SCORE') as OutcomeVariable;\n // if (scoreOutcomeIdentifier.externalScored === null && qtiAssessmentItem.adaptive === 'false') {\n // qtiAssessmentItem.processResponse(); /* 9. Process the response */\n // }\n // setSessionData(`testcontext-${this.testURL}`, this.context); /* 10. Update the context */\n });\n\n this.addEventListener('qti-outcome-changed', () => {\n // setSessionData(`testcontext-${this.testURL}`, this.context); /* 10. Update the context */\n });\n }\n }\n\n return TestLoaderClass as Constructor<TestLoaderInterface> & T;\n};\n"],"mappings":";;;;;AASO,IAAM,kBAAkB,CAAoC,eAAkB;AAAA,EACnF,MAAe,wBAAwB,WAAW;AAAA;AAAA,IAGhD,eAAe,MAAa;AAC1B,YAAM,GAAG,IAAI;AAmBb,WAAK,iBAAiB,iCAAiC,MAAM;AAAA,MAE7D,CAAC;AAED,WAAK,iBAAiB,yBAAmD,CAAC,EAAE,OAAO,MAAmB;AAEpG,eAAO,WAAW,YAAY;AAC5B,gBAAM,MAAM,MAAM,iBAAiB,EAAE;AAAA,YACnC,GAAG,OAAO,IAAI;AAAA,YACd,OAAO;AAAA,UACT;AACA,iBAAO,IAAI,QAAQ;AAAA,QACrB,GAAG;AAAA,MACL,CAAC;AAED,WAAK,iBAAiB,2BAA2B,QAAM;AAAA,MAOvD,CAAC;AAED,WAAK,iBAAiB,uBAAuB,MAAM;AAAA,MAEnD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-URGVQ64M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
testContext,
|
|
3
|
+
testElement
|
|
4
|
+
} from "./chunk-XDFXD3BI.js";
|
|
5
|
+
import {
|
|
6
|
+
__decorateClass
|
|
7
|
+
} from "./chunk-6YE2KJ4C.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/qti-test/test-base.ts
|
|
10
|
+
import { provide } from "@lit/context";
|
|
11
|
+
import { LitElement } from "lit";
|
|
12
|
+
import { state } from "lit/decorators.js";
|
|
13
|
+
var TestBase = class extends LitElement {
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this._testContext = { items: [], testOutcomeVariables: [] };
|
|
17
|
+
this.testElement = { el: null };
|
|
18
|
+
/**
|
|
19
|
+
* Updates the variables of an assessment item in the test context.
|
|
20
|
+
* - Matches the assessment item with the corresponding test context item.
|
|
21
|
+
* - If the item is not found, logs a warning.
|
|
22
|
+
* - Updates variables in the test context if exactly one variable exists.
|
|
23
|
+
* - Otherwise, syncs the assessment item's variables with the test context.
|
|
24
|
+
*
|
|
25
|
+
* @param assessmentItem - The assessment item to update.
|
|
26
|
+
*/
|
|
27
|
+
this._updateItemInTestContext = (assessmentItem) => {
|
|
28
|
+
const { identifier, variables } = assessmentItem;
|
|
29
|
+
const itemContext = this._testContext.items.find((i) => i?.identifier === identifier);
|
|
30
|
+
if (!itemContext) {
|
|
31
|
+
console.warn(`Item IDs between assessment.xml and item.xml should match: ${identifier} is not found!`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (itemContext.variables?.length === 1) {
|
|
35
|
+
this._updateItemVariablesInTestContext(identifier, variables);
|
|
36
|
+
} else {
|
|
37
|
+
assessmentItem.variables = [...itemContext.variables || []];
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.addEventListener("qti-assessment-test-connected", (e) => {
|
|
41
|
+
const qtiAssessmentTest = e.detail;
|
|
42
|
+
const items = Array.from(qtiAssessmentTest.querySelectorAll("qti-assessment-item-ref")).map(
|
|
43
|
+
(itemRef) => ({
|
|
44
|
+
href: itemRef.href,
|
|
45
|
+
identifier: itemRef.identifier,
|
|
46
|
+
category: itemRef.category,
|
|
47
|
+
variables: [{ identifier: "completionStatus", value: "not_attempted", type: "outcome" }]
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
this.testElement = { el: qtiAssessmentTest };
|
|
51
|
+
this._testContext = { ...this._testContext, items };
|
|
52
|
+
});
|
|
53
|
+
this.addEventListener("qti-assessment-item-connected", (e) => {
|
|
54
|
+
this._updateItemInTestContext(e.detail);
|
|
55
|
+
});
|
|
56
|
+
this.addEventListener("qti-outcome-changed", (e) => {
|
|
57
|
+
const assessmentitem = e.composedPath()[0];
|
|
58
|
+
this._updateItemVariablesInTestContext(assessmentitem.identifier, assessmentitem.variables);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
get context() {
|
|
62
|
+
return this._testContext;
|
|
63
|
+
}
|
|
64
|
+
// /* restores the context by updating existing items and adding new items from the "contextToRestore" parameter into the "this._context.items" array. */
|
|
65
|
+
set context(testContext2) {
|
|
66
|
+
if (testContext2 === null || testContext2 === void 0) return;
|
|
67
|
+
this._testContext = { ...testContext2 };
|
|
68
|
+
testContext2.items?.forEach((itemContext) => {
|
|
69
|
+
const existingItemContext = this._testContext.items.find((i) => i.identifier === itemContext.identifier);
|
|
70
|
+
if (existingItemContext) {
|
|
71
|
+
existingItemContext.variables = itemContext.variables;
|
|
72
|
+
} else {
|
|
73
|
+
this._testContext.items.push(itemContext);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
_updateItemVariablesInTestContext(identifier, variables) {
|
|
78
|
+
this._testContext = {
|
|
79
|
+
...this._testContext,
|
|
80
|
+
// Spread existing test context properties
|
|
81
|
+
items: this._testContext.items.map((itemContext) => {
|
|
82
|
+
if (itemContext.identifier !== identifier) {
|
|
83
|
+
return itemContext;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
...itemContext,
|
|
87
|
+
// Keep other properties of the item context
|
|
88
|
+
variables: variables.map((variable) => {
|
|
89
|
+
const matchingVariable = itemContext.variables.find((v) => v.identifier === variable.identifier);
|
|
90
|
+
return matchingVariable ? { ...matchingVariable, ...variable } : variable;
|
|
91
|
+
})
|
|
92
|
+
};
|
|
93
|
+
})
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// private _addItemToTestContext(
|
|
97
|
+
// e: CustomEvent<{ href: string; identifier: string; category: string }> & { target: QtiAssessmentItemRef }
|
|
98
|
+
// ): void {
|
|
99
|
+
// const { href, identifier, category } = e.detail;
|
|
100
|
+
// // Update test context items, adding a new item if the identifier is not already in the list
|
|
101
|
+
// if (!this._testContext.items.some(item => item.identifier === identifier)) {
|
|
102
|
+
// this._testContext.items.push({
|
|
103
|
+
// href,
|
|
104
|
+
// identifier,
|
|
105
|
+
// category,
|
|
106
|
+
// variables: [{ identifier: 'completionStatus', value: 'not_attempted', type: 'outcome' }]
|
|
107
|
+
// // category: e.target.category
|
|
108
|
+
// });
|
|
109
|
+
// }
|
|
110
|
+
// }
|
|
111
|
+
connectedCallback() {
|
|
112
|
+
super.connectedCallback();
|
|
113
|
+
this.setAttribute("qti-test", "");
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
__decorateClass([
|
|
117
|
+
state(),
|
|
118
|
+
provide({ context: testContext })
|
|
119
|
+
], TestBase.prototype, "_testContext", 2);
|
|
120
|
+
__decorateClass([
|
|
121
|
+
state(),
|
|
122
|
+
provide({ context: testElement })
|
|
123
|
+
], TestBase.prototype, "testElement", 2);
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
TestBase
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=chunk-V4FXK4TP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-test/test-base.ts"],"sourcesContent":["import { provide } from '@lit/context';\nimport { LitElement } from 'lit';\nimport { state } from 'lit/decorators.js';\nimport { TestContext, testContext, TestElement, testElement } from './context';\nimport { QtiAssessmentTest } from './qti-assessment-test';\nimport { ItemContext, QtiAssessmentItem, VariableValue } from '../qti-components';\n\nexport abstract class TestBase extends LitElement {\n @state()\n @provide({ context: testContext })\n protected _testContext: Readonly<TestContext> = { items: [], testOutcomeVariables: [] };\n\n @state()\n @provide({ context: testElement })\n protected testElement: TestElement = { el: null };\n\n constructor() {\n super();\n\n this.addEventListener('qti-assessment-test-connected', (e: CustomEvent<QtiAssessmentTest>) => {\n const qtiAssessmentTest = e.detail;\n\n const items = Array.from(qtiAssessmentTest.querySelectorAll('qti-assessment-item-ref')).map(\n (itemRef): ItemContext & { category: string } => ({\n href: itemRef.href,\n identifier: itemRef.identifier,\n category: itemRef.category,\n variables: [{ identifier: 'completionStatus', value: 'not_attempted', type: 'outcome' }]\n })\n );\n this.testElement = { el: qtiAssessmentTest };\n this._testContext = { ...this._testContext, items };\n });\n this.addEventListener('qti-assessment-item-connected', (e: CustomEvent<QtiAssessmentItem>) => {\n this._updateItemInTestContext(e.detail);\n });\n this.addEventListener('qti-outcome-changed', e => {\n const assessmentitem = e.composedPath()[0] as QtiAssessmentItem;\n this._updateItemVariablesInTestContext(assessmentitem.identifier, assessmentitem.variables);\n });\n\n // this.addEventListener(\n // 'qti-assessment-item-ref-connected',\n // (e: CustomEvent<{ href: string; identifier: string; category: string }> & { target: QtiAssessmentItemRef }) => {\n // this._addItemToTestContext(e);\n // }\n // );\n }\n\n get context(): TestContext {\n return this._testContext;\n }\n\n // /* restores the context by updating existing items and adding new items from the \"contextToRestore\" parameter into the \"this._context.items\" array. */\n set context(testContext: TestContext) {\n if (testContext === null || testContext === undefined) return;\n this._testContext = { ...testContext }; // Clone the context to avoid modifying the original object\n // // append the items that are not yet in the context and replace the ones that are\n testContext.items?.forEach(itemContext => {\n const existingItemContext = this._testContext.items.find(i => i.identifier === itemContext.identifier);\n if (existingItemContext) {\n existingItemContext.variables = itemContext.variables;\n } else {\n this._testContext.items.push(itemContext);\n }\n });\n }\n\n private _updateItemVariablesInTestContext(\n identifier: string,\n variables: VariableValue<string | string[] | null>[]\n ): void {\n // Update the test context with modified variables for the specified item\n this._testContext = {\n ...this._testContext, // Spread existing test context properties\n items: this._testContext.items.map(itemContext => {\n // If the item identifier doesn't match, keep it unchanged\n if (itemContext.identifier !== identifier) {\n return itemContext;\n }\n\n // Update the matching item with new variables\n return {\n ...itemContext, // Keep other properties of the item context\n variables: variables.map(variable => {\n // Find a matching variable in the current item context\n const matchingVariable = itemContext.variables.find(v => v.identifier === variable.identifier);\n\n // Merge matching variable with the new one, or use the new variable if no match\n return matchingVariable ? { ...matchingVariable, ...variable } : variable;\n })\n };\n })\n };\n }\n\n /**\n * Updates the variables of an assessment item in the test context.\n * - Matches the assessment item with the corresponding test context item.\n * - If the item is not found, logs a warning.\n * - Updates variables in the test context if exactly one variable exists.\n * - Otherwise, syncs the assessment item's variables with the test context.\n *\n * @param assessmentItem - The assessment item to update.\n */\n private _updateItemInTestContext = (assessmentItem: QtiAssessmentItem): void => {\n const { identifier, variables } = assessmentItem;\n\n // console.log(this._testContext);\n\n // Find the corresponding item in the test context by identifier\n const itemContext = this._testContext.items.find(i => i?.identifier === identifier);\n\n if (!itemContext) {\n console.warn(`Item IDs between assessment.xml and item.xml should match: ${identifier} is not found!`);\n return;\n }\n\n // Update variables in the test context or sync them to the assessment item\n if (itemContext.variables?.length === 1) {\n // The loaded qti-assessment-item itself has variables which are not in test context yet.\n this._updateItemVariablesInTestContext(identifier, variables);\n } else {\n // Sync the assessment item's variables with the test context\n assessmentItem.variables = [...(itemContext.variables || [])];\n }\n };\n\n // private _addItemToTestContext(\n // e: CustomEvent<{ href: string; identifier: string; category: string }> & { target: QtiAssessmentItemRef }\n // ): void {\n // const { href, identifier, category } = e.detail;\n\n // // Update test context items, adding a new item if the identifier is not already in the list\n // if (!this._testContext.items.some(item => item.identifier === identifier)) {\n // this._testContext.items.push({\n // href,\n // identifier,\n // category,\n // variables: [{ identifier: 'completionStatus', value: 'not_attempted', type: 'outcome' }]\n // // category: e.target.category\n // });\n // }\n // }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('qti-test', '');\n }\n}\n"],"mappings":"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","names":["testContext"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TestComponent
|
|
3
|
+
} from "./chunk-LKINC6JO.js";
|
|
4
|
+
import {
|
|
5
|
+
watch
|
|
6
|
+
} from "./chunk-ELDMXTUQ.js";
|
|
7
|
+
import {
|
|
8
|
+
__decorateClass
|
|
9
|
+
} from "./chunk-6YE2KJ4C.js";
|
|
10
|
+
|
|
11
|
+
// src/lib/qti-test/components/test-view.ts
|
|
12
|
+
import { html } from "lit";
|
|
13
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
14
|
+
var TestView = class extends TestComponent {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.label = "view";
|
|
18
|
+
this._handleViewOptionsChange = () => {
|
|
19
|
+
this.updateViewOptions();
|
|
20
|
+
};
|
|
21
|
+
this._viewOptions = TestView.DEFAULT_VIEW_OPTIONS;
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
super.connectedCallback();
|
|
25
|
+
this.updateViewOptions();
|
|
26
|
+
}
|
|
27
|
+
updateViewOptions() {
|
|
28
|
+
if (this.viewOptions) {
|
|
29
|
+
const options = this.viewOptions.split(",").map((opt) => opt.trim());
|
|
30
|
+
this._viewOptions = options.filter((opt) => TestView.DEFAULT_VIEW_OPTIONS.includes(opt));
|
|
31
|
+
} else {
|
|
32
|
+
this._viewOptions = TestView.DEFAULT_VIEW_OPTIONS;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
render() {
|
|
36
|
+
return html`
|
|
37
|
+
<label part="label" for="viewSelect">${this.label}</label>
|
|
38
|
+
<select
|
|
39
|
+
part="select"
|
|
40
|
+
id="viewSelect"
|
|
41
|
+
.disabled=${this.disabled}
|
|
42
|
+
@change=${(e) => {
|
|
43
|
+
const el = e.target;
|
|
44
|
+
this._switchView(el.value);
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
${this._viewOptions.map((v) => html`<option value="${v}" ?selected=${v === this.view}>${v}</option>`)}
|
|
48
|
+
</select>
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
TestView.DEFAULT_VIEW_OPTIONS = ["author", "candidate", "proctor", "scorer", "testConstructor", "tutor"];
|
|
53
|
+
__decorateClass([
|
|
54
|
+
property({ type: String })
|
|
55
|
+
], TestView.prototype, "label", 2);
|
|
56
|
+
__decorateClass([
|
|
57
|
+
property({ type: String, attribute: "view-options" })
|
|
58
|
+
], TestView.prototype, "viewOptions", 2);
|
|
59
|
+
__decorateClass([
|
|
60
|
+
watch("viewOptions", { waitUntilFirstUpdate: true })
|
|
61
|
+
], TestView.prototype, "_handleViewOptionsChange", 2);
|
|
62
|
+
__decorateClass([
|
|
63
|
+
state()
|
|
64
|
+
], TestView.prototype, "_viewOptions", 2);
|
|
65
|
+
TestView = __decorateClass([
|
|
66
|
+
customElement("test-view")
|
|
67
|
+
], TestView);
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
TestView
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=chunk-W4B23OIP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-test/components/test-view.ts"],"sourcesContent":["import { html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { TestComponent } from './test-component.abstract';\nimport { watch } from '../../decorators/watch';\n\n@customElement('test-view')\nexport class TestView extends TestComponent {\n static DEFAULT_VIEW_OPTIONS = ['author', 'candidate', 'proctor', 'scorer', 'testConstructor', 'tutor'];\n\n /** label accompanying the select view dropdown */\n @property({ type: String })\n label = 'view';\n\n /** The options to display in the dropdown, default: ['author', 'candidate', 'proctor', 'scorer', 'testConstructor', 'tutor'] */\n @property({ type: String, attribute: 'view-options' }) viewOptions;\n @watch('viewOptions', { waitUntilFirstUpdate: true })\n protected _handleViewOptionsChange = () => {\n this.updateViewOptions();\n };\n\n connectedCallback(): void {\n super.connectedCallback();\n this.updateViewOptions();\n }\n\n @state()\n private _viewOptions: string[] = TestView.DEFAULT_VIEW_OPTIONS;\n\n private updateViewOptions() {\n if (this.viewOptions) {\n const options = this.viewOptions.split(',').map(opt => opt.trim());\n this._viewOptions = options.filter(opt => TestView.DEFAULT_VIEW_OPTIONS.includes(opt));\n } else {\n this._viewOptions = TestView.DEFAULT_VIEW_OPTIONS;\n }\n }\n\n render() {\n return html`\n <label part=\"label\" for=\"viewSelect\">${this.label}</label>\n <select\n part=\"select\"\n id=\"viewSelect\"\n .disabled=${this.disabled}\n @change=${(e: Event) => {\n const el = e.target as HTMLSelectElement;\n this._switchView(el.value);\n }}\n >\n ${this._viewOptions.map(v => html`<option value=\"${v}\" ?selected=${v === this.view}>${v}</option>`)}\n </select>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'test-view': TestView;\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,YAAY;AACrB,SAAS,eAAe,UAAU,aAAa;AAKxC,IAAM,WAAN,cAAuB,cAAc;AAAA,EAArC;AAAA;AAKL,iBAAQ;AAKR,SAAU,2BAA2B,MAAM;AACzC,WAAK,kBAAkB;AAAA,IACzB;AAQA,SAAQ,eAAyB,SAAS;AAAA;AAAA,EAN1C,oBAA0B;AACxB,UAAM,kBAAkB;AACxB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAKQ,oBAAoB;AAC1B,QAAI,KAAK,aAAa;AACpB,YAAM,UAAU,KAAK,YAAY,MAAM,GAAG,EAAE,IAAI,SAAO,IAAI,KAAK,CAAC;AACjE,WAAK,eAAe,QAAQ,OAAO,SAAO,SAAS,qBAAqB,SAAS,GAAG,CAAC;AAAA,IACvF,OAAO;AACL,WAAK,eAAe,SAAS;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,6CACkC,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,oBAInC,KAAK,QAAQ;AAAA,kBACf,CAAC,MAAa;AACtB,YAAM,KAAK,EAAE;AACb,WAAK,YAAY,GAAG,KAAK;AAAA,IAC3B,CAAC;AAAA;AAAA,UAEC,KAAK,aAAa,IAAI,OAAK,sBAAsB,CAAC,eAAe,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC;AAAA;AAAA;AAAA,EAGzG;AACF;AA/Ca,SACJ,uBAAuB,CAAC,UAAU,aAAa,WAAW,UAAU,mBAAmB,OAAO;AAIrG;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAJf,SAKX;AAGuD;AAAA,EAAtD,SAAS,EAAE,MAAM,QAAQ,WAAW,eAAe,CAAC;AAAA,GAR1C,SAQ4C;AAE7C;AAAA,EADT,MAAM,eAAe,EAAE,sBAAsB,KAAK,CAAC;AAAA,GATzC,SAUD;AAUF;AAAA,EADP,MAAM;AAAA,GAnBI,SAoBH;AApBG,WAAN;AAAA,EADN,cAAc,WAAW;AAAA,GACb;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/lib/qti-test/context/test.context.ts
|
|
2
|
+
import { createContext } from "@lit/context";
|
|
3
|
+
var testContext = createContext(Symbol("test"));
|
|
4
|
+
var testElement = createContext(Symbol("testElement"));
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
testContext,
|
|
8
|
+
testElement
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=chunk-XDFXD3BI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-test/context/test.context.ts"],"sourcesContent":["import { createContext } from '@lit/context';\nimport { QtiAssessmentTest } from '../qti-assessment-test';\nimport { ItemContext, VariableDeclaration } from '../../qti-components';\nimport { View } from '../mixins/test-view.mixin';\n\nexport interface TestContext {\n items: (ItemContext & { category?: string })[];\n testOutcomeVariables: VariableDeclaration<string | string[]>[];\n navPartId?: string | null;\n navSectionId?: string | null;\n navItemId?: string | null;\n navItemLoading?: boolean;\n navTestLoading?: boolean;\n view?: View;\n}\n\nexport const testContext = createContext<Readonly<TestContext>>(Symbol('test'));\n\nexport type TestElement = {\n el: QtiAssessmentTest;\n};\n\nexport const testElement = createContext<Readonly<TestElement>>(Symbol('testElement'));\n"],"mappings":";AAAA,SAAS,qBAAqB;AAgBvB,IAAM,cAAc,cAAqC,OAAO,MAAM,CAAC;AAMvE,IAAM,cAAc,cAAqC,OAAO,aAAa,CAAC;","names":[]}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// src/lib/qti-transformers/qti-transformers.ts
|
|
2
|
+
var xml = String.raw;
|
|
3
|
+
var xmlToHTML = xml`<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
|
4
|
+
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes" />
|
|
5
|
+
<xsl:template match="@*|node()">
|
|
6
|
+
<xsl:copy>
|
|
7
|
+
<xsl:apply-templates select="@*|node()"/>
|
|
8
|
+
</xsl:copy>
|
|
9
|
+
</xsl:template>
|
|
10
|
+
|
|
11
|
+
<!-- remove existing namespaces -->
|
|
12
|
+
<xsl:template match="*">
|
|
13
|
+
<!-- remove element prefix -->
|
|
14
|
+
<xsl:element name="{local-name()}">
|
|
15
|
+
<!-- process attributes -->
|
|
16
|
+
<xsl:for-each select="@*">
|
|
17
|
+
<!-- remove attribute prefix -->
|
|
18
|
+
<xsl:attribute name="{local-name()}">
|
|
19
|
+
<xsl:value-of select="."/>
|
|
20
|
+
</xsl:attribute>
|
|
21
|
+
</xsl:for-each>
|
|
22
|
+
<xsl:apply-templates/>
|
|
23
|
+
</xsl:element>
|
|
24
|
+
</xsl:template>
|
|
25
|
+
</xsl:stylesheet>`;
|
|
26
|
+
function extendElementName(xmlFragment, tagName, extension) {
|
|
27
|
+
xmlFragment.querySelectorAll(tagName).forEach((element) => {
|
|
28
|
+
const newTagName = `${tagName}-${extension}`;
|
|
29
|
+
const newElement = createElementWithNewTagName(element, newTagName);
|
|
30
|
+
element.replaceWith(newElement);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function extendElementsWithClass(xmlFragment, classNamePattern) {
|
|
34
|
+
xmlFragment.querySelectorAll("*").forEach((element) => {
|
|
35
|
+
const classList = element.classList;
|
|
36
|
+
if (classList) {
|
|
37
|
+
classList.forEach((className) => {
|
|
38
|
+
if (className.startsWith(`${classNamePattern}:`)) {
|
|
39
|
+
const suffix = className.slice(`${classNamePattern}:`.length);
|
|
40
|
+
const newTagName = `${element.nodeName}-${suffix}`;
|
|
41
|
+
const newElement = createElementWithNewTagName(element, newTagName);
|
|
42
|
+
element.replaceWith(newElement);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function createElementWithNewTagName(element, newTagName) {
|
|
49
|
+
const newElement = document.createElement(newTagName);
|
|
50
|
+
for (const attr of element.attributes) {
|
|
51
|
+
newElement.setAttribute(attr.name, attr.value);
|
|
52
|
+
}
|
|
53
|
+
while (element.firstChild) {
|
|
54
|
+
newElement.appendChild(element.firstChild);
|
|
55
|
+
}
|
|
56
|
+
return newElement;
|
|
57
|
+
}
|
|
58
|
+
function itemsFromTest(xmlFragment) {
|
|
59
|
+
const items = [];
|
|
60
|
+
xmlFragment.querySelectorAll("qti-assessment-item-ref").forEach((el) => {
|
|
61
|
+
const identifier = el.getAttribute("identifier");
|
|
62
|
+
const href = el.getAttribute("href");
|
|
63
|
+
const category = el.getAttribute("category");
|
|
64
|
+
items.push({ identifier, href, category });
|
|
65
|
+
});
|
|
66
|
+
return items;
|
|
67
|
+
}
|
|
68
|
+
var currentRequest = null;
|
|
69
|
+
function loadXML(url, cancelPreviousRequest = false) {
|
|
70
|
+
if (cancelPreviousRequest && currentRequest !== null) {
|
|
71
|
+
currentRequest.abort();
|
|
72
|
+
}
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const xhr = new XMLHttpRequest();
|
|
75
|
+
currentRequest = xhr;
|
|
76
|
+
xhr.open("GET", url, true);
|
|
77
|
+
xhr.responseType = "document";
|
|
78
|
+
xhr.onload = () => {
|
|
79
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
80
|
+
resolve(xhr.responseXML);
|
|
81
|
+
} else {
|
|
82
|
+
reject(xhr.statusText);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
xhr.onerror = () => {
|
|
86
|
+
reject(xhr.statusText);
|
|
87
|
+
};
|
|
88
|
+
xhr.send();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function parseXML(xmlDocument) {
|
|
92
|
+
const parser = new DOMParser();
|
|
93
|
+
const xmlFragment = parser.parseFromString(xmlDocument, "text/xml");
|
|
94
|
+
return xmlFragment;
|
|
95
|
+
}
|
|
96
|
+
function toHTML(xmlFragment) {
|
|
97
|
+
const processor = new XSLTProcessor();
|
|
98
|
+
const xsltDocument = new DOMParser().parseFromString(xmlToHTML, "text/xml");
|
|
99
|
+
processor.importStylesheet(xsltDocument);
|
|
100
|
+
const itemHTMLFragment = processor.transformToFragment(xmlFragment, document);
|
|
101
|
+
return itemHTMLFragment;
|
|
102
|
+
}
|
|
103
|
+
function setLocation(xmlFragment, location) {
|
|
104
|
+
if (!location.endsWith("/")) {
|
|
105
|
+
location += "/";
|
|
106
|
+
}
|
|
107
|
+
xmlFragment.querySelectorAll("[src],[href],[primary-path]").forEach((elWithSrc) => {
|
|
108
|
+
let attr = "";
|
|
109
|
+
if (elWithSrc.getAttribute("src")) {
|
|
110
|
+
attr = "src";
|
|
111
|
+
}
|
|
112
|
+
if (elWithSrc.getAttribute("href")) {
|
|
113
|
+
attr = "href";
|
|
114
|
+
}
|
|
115
|
+
if (elWithSrc.getAttribute("primary-path")) {
|
|
116
|
+
attr = "primary-path";
|
|
117
|
+
}
|
|
118
|
+
const attrValue = elWithSrc.getAttribute(attr)?.trim();
|
|
119
|
+
if (!attrValue.startsWith("data:") && !attrValue.startsWith("http")) {
|
|
120
|
+
const newSrcValue = location + encodeURI(attrValue);
|
|
121
|
+
elWithSrc.setAttribute(attr, newSrcValue);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function convertCDATAtoComment(xmlFragment) {
|
|
126
|
+
const cdataElements = xmlFragment.querySelectorAll('qti-custom-operator[class="js.org"] > qti-base-value');
|
|
127
|
+
cdataElements.forEach((element) => {
|
|
128
|
+
const commentText = document.createComment(element.textContent);
|
|
129
|
+
element.replaceChild(commentText, element.firstChild);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function stripStyleSheets(xmlFragment) {
|
|
133
|
+
xmlFragment.querySelectorAll("qti-stylesheet").forEach((stylesheet) => stylesheet.remove());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/lib/qti-transformers/qti-transform-item.ts
|
|
137
|
+
var qtiTransformItem = () => {
|
|
138
|
+
let xmlFragment;
|
|
139
|
+
const api = {
|
|
140
|
+
async load(uri, cancelPreviousRequest = false) {
|
|
141
|
+
return new Promise((resolve) => {
|
|
142
|
+
loadXML(uri, cancelPreviousRequest).then((xml2) => {
|
|
143
|
+
xmlFragment = xml2;
|
|
144
|
+
api.path(uri.substring(0, uri.lastIndexOf("/")));
|
|
145
|
+
return resolve(api);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
parse(xmlString) {
|
|
150
|
+
xmlFragment = parseXML(xmlString);
|
|
151
|
+
return api;
|
|
152
|
+
},
|
|
153
|
+
path: (location) => {
|
|
154
|
+
setLocation(xmlFragment, location);
|
|
155
|
+
return api;
|
|
156
|
+
},
|
|
157
|
+
fn(fn) {
|
|
158
|
+
fn(xmlFragment);
|
|
159
|
+
return api;
|
|
160
|
+
},
|
|
161
|
+
pciHooks(uri) {
|
|
162
|
+
const attributes = ["hook", "module"];
|
|
163
|
+
const documentPath = uri.substring(0, uri.lastIndexOf("/"));
|
|
164
|
+
for (const attribute of attributes) {
|
|
165
|
+
const srcAttributes = xmlFragment.querySelectorAll("[" + attribute + "]");
|
|
166
|
+
srcAttributes.forEach((node) => {
|
|
167
|
+
const srcValue = node.getAttribute(attribute);
|
|
168
|
+
if (!srcValue.startsWith("data:") && !srcValue.startsWith("http")) {
|
|
169
|
+
node.setAttribute("base-url", uri);
|
|
170
|
+
node.setAttribute(
|
|
171
|
+
"module",
|
|
172
|
+
documentPath + "/" + encodeURI(srcValue + (srcValue.endsWith(".js") ? "" : ".js"))
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return api;
|
|
178
|
+
},
|
|
179
|
+
extendElementName: (tagName, extension) => {
|
|
180
|
+
extendElementName(xmlFragment, tagName, extension);
|
|
181
|
+
return api;
|
|
182
|
+
},
|
|
183
|
+
extendElementsWithClass: (param = "extend") => {
|
|
184
|
+
extendElementsWithClass(xmlFragment, param);
|
|
185
|
+
return api;
|
|
186
|
+
},
|
|
187
|
+
customInteraction(baseRef, baseItem) {
|
|
188
|
+
const qtiCustomInteraction = xmlFragment.querySelector("qti-custom-interaction");
|
|
189
|
+
const qtiCustomInteractionObject = qtiCustomInteraction.querySelector("object");
|
|
190
|
+
qtiCustomInteraction.setAttribute("data-base-ref", baseRef);
|
|
191
|
+
qtiCustomInteraction.setAttribute("data-base-item", baseRef + baseItem);
|
|
192
|
+
qtiCustomInteraction.setAttribute("data", qtiCustomInteractionObject.getAttribute("data"));
|
|
193
|
+
qtiCustomInteraction.setAttribute("width", qtiCustomInteractionObject.getAttribute("width"));
|
|
194
|
+
qtiCustomInteraction.setAttribute("height", qtiCustomInteractionObject.getAttribute("height"));
|
|
195
|
+
qtiCustomInteraction.removeChild(qtiCustomInteractionObject);
|
|
196
|
+
return api;
|
|
197
|
+
},
|
|
198
|
+
convertCDATAtoComment() {
|
|
199
|
+
convertCDATAtoComment(xmlFragment);
|
|
200
|
+
return api;
|
|
201
|
+
},
|
|
202
|
+
stripStyleSheets() {
|
|
203
|
+
stripStyleSheets(xmlFragment);
|
|
204
|
+
return api;
|
|
205
|
+
},
|
|
206
|
+
html() {
|
|
207
|
+
return new XMLSerializer().serializeToString(toHTML(xmlFragment));
|
|
208
|
+
},
|
|
209
|
+
xml() {
|
|
210
|
+
return new XMLSerializer().serializeToString(xmlFragment);
|
|
211
|
+
},
|
|
212
|
+
htmlDoc() {
|
|
213
|
+
return toHTML(xmlFragment);
|
|
214
|
+
},
|
|
215
|
+
xmlDoc() {
|
|
216
|
+
return xmlFragment;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
return api;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/lib/qti-transformers/qti-transform-manifest.ts
|
|
223
|
+
var qtiTransformManifest = () => {
|
|
224
|
+
let xmlFragment;
|
|
225
|
+
const api = {
|
|
226
|
+
async load(uri) {
|
|
227
|
+
return new Promise((resolve) => {
|
|
228
|
+
loadXML(uri).then((xml2) => {
|
|
229
|
+
xmlFragment = xml2;
|
|
230
|
+
return resolve(api);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
parse(xmlString) {
|
|
235
|
+
xmlFragment = parseXML(xmlString);
|
|
236
|
+
},
|
|
237
|
+
assessmentTest() {
|
|
238
|
+
const el = xmlFragment.querySelector('resource[type="imsqti_test_xmlv3p0"]');
|
|
239
|
+
return { href: el.getAttribute("href"), identifier: el.getAttribute("identifier") };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
return api;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/lib/qti-transformers/qti-transform-test.ts
|
|
246
|
+
var qtiTransformTest = () => {
|
|
247
|
+
let xmlFragment;
|
|
248
|
+
const api = {
|
|
249
|
+
async load(uri) {
|
|
250
|
+
return new Promise((resolve, _) => {
|
|
251
|
+
loadXML(uri).then((xml2) => {
|
|
252
|
+
xmlFragment = xml2;
|
|
253
|
+
api.path(uri.substring(0, uri.lastIndexOf("/")));
|
|
254
|
+
return resolve(api);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
parse(xmlString) {
|
|
259
|
+
xmlFragment = parseXML(xmlString);
|
|
260
|
+
return api;
|
|
261
|
+
},
|
|
262
|
+
path: (location) => {
|
|
263
|
+
setLocation(xmlFragment, location);
|
|
264
|
+
return api;
|
|
265
|
+
},
|
|
266
|
+
fn(fn) {
|
|
267
|
+
fn(xmlFragment);
|
|
268
|
+
return api;
|
|
269
|
+
},
|
|
270
|
+
items() {
|
|
271
|
+
return itemsFromTest(xmlFragment);
|
|
272
|
+
},
|
|
273
|
+
html() {
|
|
274
|
+
return new XMLSerializer().serializeToString(toHTML(xmlFragment));
|
|
275
|
+
},
|
|
276
|
+
xml() {
|
|
277
|
+
return new XMLSerializer().serializeToString(xmlFragment);
|
|
278
|
+
},
|
|
279
|
+
htmlDoc() {
|
|
280
|
+
return toHTML(xmlFragment);
|
|
281
|
+
},
|
|
282
|
+
xmlDoc() {
|
|
283
|
+
return xmlFragment;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
return api;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
export {
|
|
290
|
+
qtiTransformItem,
|
|
291
|
+
qtiTransformManifest,
|
|
292
|
+
qtiTransformTest
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=chunk-XDMSEAYC.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
qtiTransformItem,
|
|
3
|
+
qtiTransformManifest,
|
|
4
|
+
qtiTransformTest
|
|
5
|
+
} from "./chunk-XDMSEAYC.js";
|
|
6
|
+
|
|
7
|
+
// src/lib/qti-loader/qti-loader.ts
|
|
8
|
+
var getManifestInfo = async (manifestURL) => {
|
|
9
|
+
const baseURI = manifestURL.substring(0, manifestURL.lastIndexOf("/"));
|
|
10
|
+
const test = await qtiTransformManifest().load(`${manifestURL}`).then((api) => api.assessmentTest());
|
|
11
|
+
const testHTMLDoc = await qtiTransformTest().load(`${baseURI}/${test.href}`).then((api) => api.htmlDoc());
|
|
12
|
+
const items = await qtiTransformTest().load(`${baseURI}/${test.href}`).then((api) => api.items());
|
|
13
|
+
const testURL = `${baseURI}/${test.href}`;
|
|
14
|
+
const testURI = `${baseURI}/${test.href.substring(0, test.href.lastIndexOf("/"))}`;
|
|
15
|
+
return {
|
|
16
|
+
testHTMLDoc,
|
|
17
|
+
testURI,
|
|
18
|
+
testURL,
|
|
19
|
+
items,
|
|
20
|
+
testIdentifier: test.identifier
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
var getItemByUri = async (itemUri) => qtiTransformItem().load(itemUri).then((api) => api.htmlDoc().firstElementChild);
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
getManifestInfo,
|
|
27
|
+
getItemByUri
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=chunk-XPDS72XY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-loader/qti-loader.ts"],"sourcesContent":["import { QtiAssessmentItem } from '../qti-components';\nimport { qtiTransformItem, qtiTransformTest } from '../qti-transformers';\nimport { qtiTransformManifest } from '../qti-transformers/qti-transform-manifest';\n\nexport type ManifestInfo = {\n testIdentifier: string;\n testHTMLDoc: DocumentFragment;\n testURI: string;\n testURL: string;\n items: {\n identifier: string;\n href: string;\n category: string;\n }[];\n};\n\n// Utility function to ensure package URIs end with a '/'\n// const normalizeUri = (uri: string) => (uri.endsWith('/') ? uri : `${uri}/`);\n\n// Fetches assessment data from the manifest\nexport const getManifestInfo = async (manifestURL: string): Promise<ManifestInfo> => {\n const baseURI = manifestURL.substring(0, manifestURL.lastIndexOf('/'));\n\n const test = await qtiTransformManifest()\n .load(`${manifestURL}`)\n .then(api => api.assessmentTest());\n\n const testHTMLDoc = await qtiTransformTest()\n .load(`${baseURI}/${test.href}`)\n .then(api => api.htmlDoc());\n\n const items = await qtiTransformTest()\n .load(`${baseURI}/${test.href}`)\n .then(api => api.items());\n\n const testURL = `${baseURI}/${test.href}`;\n const testURI = `${baseURI}/${test.href.substring(0, test.href.lastIndexOf('/'))}`;\n\n return {\n testHTMLDoc,\n testURI,\n testURL,\n items,\n testIdentifier: test.identifier\n };\n};\n\n// Fetches a single item by URI\nexport const getItemByUri = async (itemUri: string): Promise<QtiAssessmentItem> =>\n qtiTransformItem()\n .load(itemUri)\n .then(api => api.htmlDoc().firstElementChild as QtiAssessmentItem);\n"],"mappings":";;;;;;;AAoBO,IAAM,kBAAkB,OAAO,gBAA+C;AACnF,QAAM,UAAU,YAAY,UAAU,GAAG,YAAY,YAAY,GAAG,CAAC;AAErE,QAAM,OAAO,MAAM,qBAAqB,EACrC,KAAK,GAAG,WAAW,EAAE,EACrB,KAAK,SAAO,IAAI,eAAe,CAAC;AAEnC,QAAM,cAAc,MAAM,iBAAiB,EACxC,KAAK,GAAG,OAAO,IAAI,KAAK,IAAI,EAAE,EAC9B,KAAK,SAAO,IAAI,QAAQ,CAAC;AAE5B,QAAM,QAAQ,MAAM,iBAAiB,EAClC,KAAK,GAAG,OAAO,IAAI,KAAK,IAAI,EAAE,EAC9B,KAAK,SAAO,IAAI,MAAM,CAAC;AAE1B,QAAM,UAAU,GAAG,OAAO,IAAI,KAAK,IAAI;AACvC,QAAM,UAAU,GAAG,OAAO,IAAI,KAAK,KAAK,UAAU,GAAG,KAAK,KAAK,YAAY,GAAG,CAAC,CAAC;AAEhF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK;AAAA,EACvB;AACF;AAGO,IAAM,eAAe,OAAO,YACjC,iBAAiB,EACd,KAAK,OAAO,EACZ,KAAK,SAAO,IAAI,QAAQ,EAAE,iBAAsC;","names":[]}
|