@qti-components/portable-custom-interaction 1.0.1
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.md +674 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/interface.d.ts +202 -0
- package/dist/interface.js +2 -0
- package/dist/interface.js.map +1 -0
- package/dist/qti-portable-custom-interaction.d.ts +115 -0
- package/dist/qti-portable-custom-interaction.js +1848 -0
- package/dist/qti-portable-custom-interaction.js.map +1 -0
- package/dist/qti-portable-custom-interaction.styles.d.ts +2 -0
- package/dist/qti-portable-custom-interaction.styles.js +15 -0
- package/dist/qti-portable-custom-interaction.styles.js.map +1 -0
- package/dist/qti-portable-custom-test-interaction.d.ts +84 -0
- package/dist/qti-portable-custom-test-interaction.js +492 -0
- package/dist/qti-portable-custom-test-interaction.js.map +1 -0
- package/dist/register.d.ts +1 -0
- package/dist/register.js +5 -0
- package/dist/register.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-portable-custom-interaction.js","sourceRoot":"","sources":["../src/qti-portable-custom-interaction.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\n\nimport { Interaction, itemContext, qtiContext, removeDoubleSlashes } from '@qti-components/base';\n\nimport styles from './qti-portable-custom-interaction.styles';\n\nimport type { CSSResultGroup } from 'lit';\nimport type { BaseType, Cardinality, ItemContext, QtiContext } from '@qti-components/base';\nimport type { QtiRecordItem, QtiVariableJSON, ResponseVariableType } from './interface';\n\nexport class QtiPortableCustomInteraction extends Interaction {\n #value: string | string[];\n\n protected _iframeLoaded = false;\n protected _pendingMessages: Array<{ method: string; params: any }> = [];\n protected iframe: HTMLIFrameElement;\n protected _iframeMessageOrigin: string | null = null;\n private _iframeObjectUrl: string | null = null;\n\n // This implementation always renders inside an iframe.\n static override styles: CSSResultGroup = [\n styles,\n css`\n :host {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n `\n ];\n\n @property({ type: String, attribute: 'module' })\n module: string;\n\n @property({ type: String, attribute: 'custom-interaction-type-identifier' })\n customInteractionTypeIdentifier: string;\n\n @property({ type: String, attribute: 'data-require-paths' })\n requirePathsJson: string = '';\n\n @property({ type: String, attribute: 'data-require-shim' })\n requireShimJson: string = '';\n\n @property({ type: String, attribute: 'data-require-js-url' })\n requireJsUrl: string = 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js';\n\n @property({ type: String, attribute: 'data-base-url' })\n baseUrl: string = '';\n\n @property({ type: Boolean, attribute: 'data-use-default-paths' })\n useDefaultPaths = false;\n\n @state()\n private _errorMessage: string = null;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n protected context?: ItemContext;\n\n @consume({ context: qtiContext, subscribe: true })\n @state()\n protected qtiContext?: QtiContext;\n\n @state() response: string | string[] | null = null;\n\n #parsedRequirePaths: Record<string, string | string[]> = null;\n #parsedRequireShim: Record<string, any> = null;\n #pciValidity: boolean | null = null;\n #pciCustomValidityMessage = '';\n\n /**\n * Parse the require paths JSON string into an object\n */\n #getRequirePaths(): Record<string, string | string[]> {\n if (this.#parsedRequirePaths === null && this.requirePathsJson) {\n try {\n const parsedJson = JSON.parse(this.requirePathsJson);\n if (Array.isArray(parsedJson) || !parsedJson || typeof parsedJson !== 'object') {\n throw new Error('Require paths must be a JSON object.');\n }\n this.#parsedRequirePaths = parsedJson;\n } catch (e) {\n console.error('Error parsing require paths JSON:', e);\n this._errorMessage = `Error parsing require paths JSON: ${e.message}`;\n this.#parsedRequirePaths = {};\n }\n }\n return this.#parsedRequirePaths || {};\n }\n\n /**\n * Parse the require shim JSON string into an object\n */\n #getRequireShim(): Record<string, any> {\n if (this.#parsedRequireShim === null && this.requireShimJson) {\n try {\n this.#parsedRequireShim = JSON.parse(this.requireShimJson);\n } catch (e) {\n console.error('Error parsing require shim JSON:', e);\n this._errorMessage = `Error parsing require shim JSON: ${e.message}`;\n this.#parsedRequireShim = {};\n }\n }\n return this.#parsedRequireShim || {};\n }\n\n /**\n * Get the final require paths by combining defaults with user-provided paths\n */\n #getFinalRequirePaths(): Record<string, string | string[]> {\n // Return only user-provided paths to keep PCI completely self-contained\n return this.#getRequirePaths();\n }\n\n /**\n * Get the final require shim\n */\n #getFinalRequireShim(): Record<string, any> {\n return this.#getRequireShim();\n }\n\n /**\n * Converts QtiVariableJSON to a string or string array\n */\n #convertQtiVariableJSON(input: QtiVariableJSON): string | string[] {\n for (const topLevelKey in input) {\n // eslint-disable-next-line no-prototype-builtins\n if (input.hasOwnProperty(topLevelKey)) {\n const nestedObject = input[topLevelKey as 'list' | 'base'];\n if (nestedObject) {\n for (const nestedKey in nestedObject) {\n // eslint-disable-next-line no-prototype-builtins\n if (nestedObject.hasOwnProperty(nestedKey)) {\n const value = nestedObject[nestedKey as keyof typeof nestedObject];\n if (Array.isArray(value)) {\n return value.map(String); // Convert each element in the array to string\n } else if (value !== undefined && value !== null) {\n return String(value); // Convert the single value to string\n }\n }\n }\n }\n }\n }\n return null;\n }\n\n /**\n * Get direct child elements by tag name\n */\n private getDirectChildrenByTag(tagName: string): Element[] {\n const needle = tagName.toLowerCase();\n return Array.from(this.children).filter(child => child.tagName.toLowerCase() === needle);\n }\n\n /**\n * Coerce a scalar value to the expected base-type when possible\n */\n private coerceBaseValue(value: unknown, baseType: BaseType): unknown {\n if (value === null || value === undefined) return value;\n\n switch (baseType) {\n case 'integer': {\n if (typeof value === 'number') return value;\n const parsed = parseInt(String(value), 10);\n return Number.isNaN(parsed) ? value : parsed;\n }\n case 'float':\n case 'duration': {\n if (typeof value === 'number') return value;\n const parsed = parseFloat(String(value));\n return Number.isNaN(parsed) ? value : parsed;\n }\n case 'boolean': {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') {\n const lowered = value.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n }\n return value;\n }\n case 'string':\n case 'identifier':\n default:\n return String(value);\n }\n }\n\n /**\n * Normalize an input into a list form\n */\n private normalizeListValue(value: unknown): unknown[] {\n if (value === null || value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n }\n\n /**\n * Convert a variable value to QtiVariableJSON\n */\n private variableToQtiVariableJSON(value: unknown, cardinality: Cardinality, baseType: BaseType): QtiVariableJSON {\n if (cardinality === 'record' || baseType === 'record') {\n return this.recordToQtiVariableJSON(value);\n }\n\n if (cardinality !== 'single') {\n const listValues = this.normalizeListValue(value).map(v => this.coerceBaseValue(v, baseType));\n return { list: { [baseType]: listValues } };\n }\n\n return { base: { [baseType]: this.coerceBaseValue(value, baseType) } };\n }\n\n /**\n * Convert a record object into QtiVariableJSON\n */\n private recordToQtiVariableJSON(value: unknown): QtiVariableJSON {\n if (!value || typeof value !== 'object') {\n return { record: [] };\n }\n\n const recordEntries: QtiRecordItem[] = [];\n for (const [name, entryValue] of Object.entries(value as Record<string, unknown>)) {\n recordEntries.push(this.recordEntryFromValue(name, entryValue));\n }\n\n return { record: recordEntries };\n }\n\n /**\n * Build a record entry from an arbitrary value\n */\n private recordEntryFromValue(name: string, entryValue: unknown): QtiRecordItem {\n if (Array.isArray(entryValue)) {\n const filtered = entryValue.filter(v => v !== null && v !== undefined);\n\n if (filtered.length && filtered.every(v => typeof v === 'boolean')) {\n return { name, list: { boolean: filtered as boolean[] } };\n }\n\n if (filtered.length && filtered.every(v => typeof v === 'number')) {\n const numbers = filtered as number[];\n const isIntegers = numbers.every(n => Number.isInteger(n));\n return { name, list: { [isIntegers ? 'integer' : 'float']: numbers } };\n }\n\n return { name, list: { string: entryValue.map(v => (v === null || v === undefined ? '' : String(v))) } };\n }\n\n if (typeof entryValue === 'boolean') {\n return { name, base: { boolean: entryValue } };\n }\n\n if (typeof entryValue === 'number') {\n if (Number.isInteger(entryValue)) return { name, base: { integer: entryValue } };\n return { name, base: { float: entryValue } };\n }\n\n if (entryValue === null || entryValue === undefined) {\n return { name, base: { string: '' } };\n }\n\n if (typeof entryValue === 'object') {\n try {\n return { name, base: { string: JSON.stringify(entryValue) } };\n } catch {\n return { name, base: { string: String(entryValue) } };\n }\n }\n\n return { name, base: { string: String(entryValue) } };\n }\n\n /**\n * Extract default QTI_CONTEXT values from qti-context-declaration elements\n */\n private getQtiContextDefaultsFromItem(): Record<string, unknown> {\n const itemElement = this.closest('qti-assessment-item');\n if (!itemElement) return {};\n\n const defaults: Record<string, unknown> = {};\n const contextDeclarations = itemElement.querySelectorAll('qti-context-declaration[identifier=\"QTI_CONTEXT\"]');\n\n contextDeclarations.forEach(declaration => {\n const defaultValueElement = declaration.querySelector('qti-default-value');\n if (!defaultValueElement) return;\n\n const valueElements = defaultValueElement.querySelectorAll('qti-value[field-identifier]');\n valueElements.forEach(valueElement => {\n const fieldIdentifier = valueElement.getAttribute('field-identifier');\n if (!fieldIdentifier) return;\n\n const baseType = (valueElement.getAttribute('base-type') || 'string') as BaseType;\n const textContent = valueElement.textContent?.trim() || '';\n defaults[fieldIdentifier] = this.coerceBaseValue(textContent, baseType);\n });\n });\n\n return defaults;\n }\n\n /**\n * Build a QTI_CONTEXT record for PCI consumption\n */\n private getQtiContextRecord(): QtiVariableJSON | null {\n const defaults = this.getQtiContextDefaultsFromItem();\n const runtime = this.qtiContext?.QTI_CONTEXT || {};\n const merged: Record<string, unknown> = { ...defaults, ...runtime };\n if (!Object.keys(merged).length) return null;\n\n const normalized = {\n candidateIdentifier: merged.candidateIdentifier ?? '',\n testIdentifier: merged.testIdentifier ?? '',\n environmentIdentifier: merged.environmentIdentifier ?? '',\n ...merged\n };\n\n return this.recordToQtiVariableJSON(normalized);\n }\n\n /**\n * Collect template variables referenced by qti-template-variable children\n */\n private getTemplateVariables(): Record<string, QtiVariableJSON> {\n const templateVariables: Record<string, QtiVariableJSON> = {};\n const templateVariableElements = this.getDirectChildrenByTag('qti-template-variable');\n if (!templateVariableElements.length) return templateVariables;\n\n templateVariableElements.forEach(el => {\n const identifier = el.getAttribute('template-identifier') || el.getAttribute('identifier') || '';\n if (!identifier) return;\n\n const variable = this.context?.variables?.find(v => v.identifier === identifier);\n if (!variable) return;\n\n const cardinality = (variable.cardinality || 'single') as Cardinality;\n const baseType = (variable.baseType || 'string') as BaseType;\n templateVariables[identifier] = this.variableToQtiVariableJSON(variable.value, cardinality, baseType);\n });\n\n return templateVariables;\n }\n\n /**\n * Collect context variables referenced by qti-context-variable children\n */\n private getContextVariables(): Record<string, QtiVariableJSON> {\n const contextVariables: Record<string, QtiVariableJSON> = {};\n const contextVariableElements = this.getDirectChildrenByTag('qti-context-variable');\n if (!contextVariableElements.length) return contextVariables;\n\n contextVariableElements.forEach(el => {\n const identifier = el.getAttribute('identifier') || '';\n if (!identifier) return;\n\n if (identifier === 'QTI_CONTEXT') {\n const record = this.getQtiContextRecord();\n if (record) contextVariables[identifier] = record;\n return;\n }\n\n const variable = this.context?.variables?.find(v => v.identifier === identifier);\n if (!variable) return;\n\n const cardinality = (variable.cardinality || 'single') as Cardinality;\n const baseType = (variable.baseType || 'string') as BaseType;\n contextVariables[identifier] = this.variableToQtiVariableJSON(variable.value, cardinality, baseType);\n });\n\n return contextVariables;\n }\n\n /**\n * Adds hyphenated versions of camelCase keys to properties object\n */\n #addHyphenatedKeys(properties: Record<string, any>): Record<string, any> {\n const updatedProperties = { ...properties };\n\n for (const key in properties) {\n if (Object.prototype.hasOwnProperty.call(properties, key)) {\n const hyphenatedKey = key.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`);\n updatedProperties[hyphenatedKey] = properties[key];\n }\n }\n\n return updatedProperties;\n }\n\n #toNestedProperties(properties: Record<string, any>): Record<string, any> {\n const nestedProperties = { ...properties };\n\n const setNestedValue = (root: Record<string, any>, path: string[], value: any): void => {\n let cursor = root;\n\n for (let i = 0; i < path.length; i += 1) {\n const segment = path[i];\n const isLast = i === path.length - 1;\n\n if (isLast) {\n cursor[segment] = value;\n return;\n }\n\n if (!cursor[segment] || typeof cursor[segment] !== 'object' || Array.isArray(cursor[segment])) {\n cursor[segment] = {};\n }\n\n cursor = cursor[segment];\n }\n };\n\n for (const [key, value] of Object.entries(properties)) {\n if (!key.includes('__')) continue;\n const path = key.split('__').filter(Boolean);\n if (path.length < 2) continue;\n setNestedValue(nestedProperties, path, value);\n }\n\n return nestedProperties;\n }\n\n /**\n * Converts response variables to QtiVariableJSON\n */\n protected responseVariablesToQtiVariableJSON(\n input: string | string[],\n cardinality: Cardinality,\n baseType: BaseType\n ): QtiVariableJSON {\n if (cardinality !== 'single') {\n const list = { list: {} };\n list.list[baseType] = input;\n return list;\n } else {\n const base = { base: {} };\n base.base[baseType] = input;\n return base;\n }\n }\n\n #hasNonEmptyResponse(): boolean {\n if (this.response === null || this.response === undefined) return false;\n if (Array.isArray(this.response)) {\n if (this.response.length === 0) return false;\n return this.response.some(v => v !== '' && v !== null && v !== undefined);\n }\n return this.response !== '';\n }\n\n #setInteractionValidity(isValid: boolean, customMessage?: string): void {\n const fallbackMessage = this.dataset.invalidresponsemessage || 'Invalid response.';\n const message = isValid ? '' : customMessage && customMessage.trim().length > 0 ? customMessage : fallbackMessage;\n this._internals.setValidity(isValid ? {} : { customError: true }, message);\n }\n\n validate(): boolean {\n const isValid = typeof this.#pciValidity === 'boolean' ? this.#pciValidity : this.#hasNonEmptyResponse();\n this.#setInteractionValidity(isValid, this.#pciCustomValidityMessage);\n return isValid;\n }\n\n override set value(v: string | null) {\n if (v === null) {\n this.#value = [];\n } else {\n this.#value = Array.isArray(v) ? v : v.split(',');\n }\n // PCI handles response setting via boundTo property during initialization\n // No need to call setResponse directly\n }\n\n override get value(): string | null {\n if (this.#value === null || this.#value === undefined) return null;\n return Array.isArray(this.#value) ? this.#value.join(',') : String(this.#value);\n }\n\n set boundTo(newValue: Record<string, ResponseVariableType>) {\n if (!newValue || !newValue[this.responseIdentifier]) {\n return;\n }\n\n const value = this.#convertQtiVariableJSON(newValue[this.responseIdentifier]);\n this.#value = value;\n\n // No direct call to setResponse - PCI will handle this during initialization\n // through the boundTo property in the config\n\n this.saveResponse(value);\n }\n\n get boundTo(): Record<string, QtiVariableJSON> {\n const responseVariable: Record<string, QtiVariableJSON> = {};\n const variable = this.context?.variables?.find(v => v.identifier === this.responseIdentifier);\n if (variable) {\n const cardinality =\n this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.cardinality || 'single';\n const baseType =\n this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.baseType || 'string';\n const value = this.context?.variables?.find(v => v.identifier === this.responseIdentifier)?.value || null;\n const responseVal = this.responseVariablesToQtiVariableJSON(value as string | string[], cardinality, baseType);\n responseVariable[this.responseIdentifier] = responseVal;\n }\n\n return responseVariable;\n }\n\n /**\n * Unescape HTML entities in a string\n */\n #unescapeHtml(str: string): string {\n if (!str) return str;\n\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(///g, '/')\n .replace(/`/g, '`')\n .replace(/=/g, '=');\n }\n\n /**\n * Unescape HTML entities in all values of an object\n */\n #unescapeDataAttributes(obj: Record<string, any>): Record<string, any> {\n const unescaped: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string') {\n unescaped[key] = this.#unescapeHtml(value);\n } else {\n unescaped[key] = value;\n }\n }\n\n return unescaped;\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('message', this.handleIframeMessage);\n if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\n }\n\n /**\n * IFRAME MODE: Send message to iframe\n */\n protected sendMessageToIframe(method: string, params: any) {\n const targetWindow = this.iframe?.contentWindow;\n if (!this._iframeLoaded || !targetWindow) {\n this._pendingMessages.push({ method, params });\n return;\n }\n targetWindow.postMessage(\n {\n source: 'qti-portable-custom-interaction',\n responseIdentifier: this.responseIdentifier,\n method,\n params\n },\n '*'\n );\n }\n\n /**\n * IFRAME MODE: Process pending messages\n */\n #processPendingMessages() {\n if (this._pendingMessages.length) {\n this._pendingMessages.forEach(message => {\n this.sendMessageToIframe(message.method, message.params);\n });\n this._pendingMessages = [];\n }\n }\n\n /**\n * IFRAME MODE: Handle iframe messages\n */\n protected handleIframeMessage = (event: MessageEvent) => {\n const { data } = event;\n // Ensure the message is from our iframe\n if (!data || data.source !== 'qti-pci-iframe') {\n return;\n }\n if (!this.iframe?.contentWindow || event.source !== this.iframe.contentWindow) {\n return;\n }\n if (data.responseIdentifier && data.responseIdentifier !== this.responseIdentifier) {\n return;\n }\n if (this._iframeMessageOrigin === null) {\n this._iframeMessageOrigin = event.origin;\n } else if (event.origin !== this._iframeMessageOrigin) {\n return;\n }\n switch (data.method) {\n case 'iframeReady':\n this.#initializeInteraction();\n this.#processPendingMessages();\n this.dispatchEvent(\n new CustomEvent('qti-portable-custom-interaction-loaded', {\n bubbles: true\n })\n );\n break;\n\n case 'resize':\n if (typeof data.height === 'number' && this.iframe) {\n this.iframe.style.height = `${data.height}px`;\n this.iframe.style.width = `${data.width}px`;\n }\n break;\n case 'console':\n this.dispatchEvent(\n new CustomEvent('qti-pci-console', {\n detail: {\n level: data.level,\n args: data.args\n },\n bubbles: true\n })\n );\n break;\n\n case 'interactionChanged': {\n const raw = data?.params?.value;\n const converted = raw && typeof raw === 'object' ? this.#convertQtiVariableJSON(raw as QtiVariableJSON) : null;\n const pciValid = typeof data?.params?.valid === 'boolean' ? (data.params.valid as boolean) : null;\n const pciCustomValidity =\n typeof data?.params?.customValidity === 'string' ? (data.params.customValidity as string) : null;\n if (pciValid !== null) {\n this.#pciValidity = pciValid;\n if (pciValid && pciCustomValidity === null) {\n this.#pciCustomValidityMessage = '';\n }\n }\n if (pciCustomValidity !== null) {\n this.#pciCustomValidityMessage = pciCustomValidity;\n }\n // PCI state \"should\" be an opaque string, but a lot of existing PCIs (including the\n // IMS conformance examples) return a structured object from getState().\n //\n // We store a string in itemContext.state, so we serialize non-string states with a\n // prefix to safely round-trip them without accidentally parsing user-provided strings.\n const stateRaw = data?.params?.state as unknown;\n let state: string | null | undefined;\n if (stateRaw === undefined) {\n state = undefined;\n } else if (stateRaw === null) {\n state = null;\n } else if (typeof stateRaw === 'string') {\n state = stateRaw;\n } else {\n try {\n state = `__qti_json__::${JSON.stringify(stateRaw)}`;\n } catch {\n state = null;\n }\n }\n\n // Treat null/undefined or unconvertible responses as \"cleared\".\n // The iframe side is responsible for not emitting an initial clear on load.\n if (converted === null) {\n const emptyResponse = this.responseVariable?.cardinality === 'single' ? '' : [];\n this.response = emptyResponse;\n this.validate();\n this.saveResponse(emptyResponse, state);\n break;\n }\n\n this.response = converted;\n this.validate();\n this.saveResponse(converted, state);\n break;\n }\n case 'error':\n this._errorMessage = data.params.message;\n console.error('Error from PCI iframe:', data.params.message);\n break;\n }\n };\n\n /**\n * IFRAME MODE: Create iframe element\n */\n protected createIframe() {\n if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\n this.iframe = document.createElement('iframe');\n this.iframe.id = `pci-iframe-${this.responseIdentifier}`;\n this.iframe.setAttribute('title', 'QTI PCI Iframe');\n this.iframe.setAttribute('aria-label', 'QTI PCI Iframe');\n this.iframe.setAttribute('aria-hidden', 'false');\n this.iframe.setAttribute('role', 'application');\n this.iframe.style.width = '100%';\n this.iframe.style.border = 'none';\n this.iframe.style.display = 'block';\n\n // Handle iframe load event\n this.iframe.onload = () => {\n this._iframeLoaded = true;\n if (this._iframeObjectUrl) {\n URL.revokeObjectURL(this._iframeObjectUrl);\n this._iframeObjectUrl = null;\n }\n this.#addMarkupToIframe();\n // Send initialization data to iframe\n this.#sendIframeInitData();\n };\n\n // Create a unique name for the iframe\n const iframeName = `qti-pci-${this.responseIdentifier}-${Date.now()}`;\n this.iframe.name = iframeName;\n\n // Generate iframe HTML content with all required scripts\n const iframeContent = this.generateIframeContent();\n\n // Prefer a same-origin blob URL to avoid postMessage target-origin mismatches (e.g. in Storybook).\n try {\n const blob = new Blob([iframeContent], { type: 'text/html' });\n this._iframeObjectUrl = URL.createObjectURL(blob);\n this.iframe.src = this._iframeObjectUrl;\n } catch {\n const encodedContent = encodeURIComponent(iframeContent);\n this.iframe.src = `data:text/html;charset=utf-8,${encodedContent}`;\n }\n\n // Append iframe to component\n this.appendChild(this.iframe);\n }\n\n /**\n * IFRAME MODE: Send initialization data to iframe\n */\n #sendIframeInitData() {\n // Once iframe is loaded, send initialization data\n const properties = this.#addHyphenatedKeys(\n this.#toNestedProperties(this.#unescapeDataAttributes({ ...this.dataset }))\n );\n const storedStateRaw = this.context?.state?.[this.responseIdentifier];\n const storedState = typeof storedStateRaw === 'string' && storedStateRaw.length > 0 ? storedStateRaw : null;\n const initData = {\n module: this.module,\n customInteractionTypeIdentifier: this.customInteractionTypeIdentifier,\n baseUrl: !this.baseUrl\n ? window.location.origin\n : this.baseUrl.startsWith('http') || this.baseUrl.startsWith('blob') || this.baseUrl.startsWith('base64')\n ? this.baseUrl\n : removeDoubleSlashes(`${window.location.origin}${this.baseUrl}`),\n responseIdentifier: this.responseIdentifier,\n properties,\n contextVariables: this.getContextVariables(),\n templateVariables: this.getTemplateVariables(),\n dataAttributes: { ...this.dataset },\n interactionModules: this.#getInteractionModules(),\n boundTo: storedState ? null : this.boundTo,\n state: storedState\n };\n\n this.sendMessageToIframe('initialize', initData);\n }\n\n /**\n * IFRAME MODE: Get interaction modules from DOM\n */\n #getInteractionModules() {\n const modules = [];\n const interactionModules = this.querySelector('qti-interaction-modules');\n\n if (interactionModules) {\n const moduleElements = interactionModules.querySelectorAll('qti-interaction-module');\n for (const module of moduleElements) {\n modules.push({\n id: module.getAttribute('id'),\n primaryPath: module.getAttribute('primary-path'),\n fallbackPath: module.getAttribute('fallback-path')\n });\n }\n }\n\n return modules;\n }\n\n /**\n * IFRAME MODE: Add markup, stylesheets, and properties to iframe\n */\n #addMarkupToIframe() {\n // Get interaction markup if any\n const markup = this.querySelector('qti-interaction-markup');\n if (markup) {\n this.sendMessageToIframe('setMarkup', markup.innerHTML);\n }\n\n const stylesheets = Array.from(this.querySelectorAll('qti-stylesheet'));\n if (stylesheets.length) {\n const stylesheetsHtml = stylesheets.map(sheet => sheet.outerHTML).join('\\n');\n this.sendMessageToIframe('setStylesheets', stylesheetsHtml);\n }\n\n // Get properties if any\n const properties = this.querySelector('properties');\n if (properties) {\n this.sendMessageToIframe('setProperties', properties.innerHTML);\n }\n }\n\n /**\n * IFRAME MODE: Initialize the interaction\n */\n #initializeInteraction() {\n // No explicit action needed, as the PCI will initialize\n // with the boundTo property already provided\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#pciValidity = null;\n this.#pciCustomValidityMessage = '';\n // Reflect any pre-existing response (e.g. restored session) for validation/completionStatus.\n this.response = (this.responseVariable?.value as string | string[] | null) ?? null;\n window.addEventListener('message', this.handleIframeMessage);\n this.createIframe();\n }\n\n /**\n * IFRAME MODE: Generate iframe HTML content\n */\n protected generateIframeContent(): string {\n const parentStyles = window.getComputedStyle(document.body);\n\n // Get the configured require paths and shim\n const requirePaths = JSON.stringify(this.#getFinalRequirePaths());\n const requireShim = JSON.stringify(this.#getFinalRequireShim());\n const iframeBaseUrl = this.dataset.baseUrl\n ? this.dataset.baseUrl.startsWith('/')\n ? `${window.location.origin}${this.dataset.baseUrl}`\n : this.dataset.baseUrl\n : '';\n const forwardConsole = this.dataset.forwardConsole === 'true';\n const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n const defaultComponentsCdnUrl = isLocalhost\n ? `${window.location.origin}/cdn/index.js`\n : 'https://unpkg.com/@citolab/qti-components/cdn';\n const defaultComponentsCssUrl = isLocalhost\n ? `${window.location.origin}/dist/item.css`\n : 'https://unpkg.com/@citolab/qti-components@latest/dist/item.css';\n const componentsCdnUrl = this.dataset.componentsCdnUrl || defaultComponentsCdnUrl;\n const componentsCssUrl = this.dataset.componentsCssUrl || defaultComponentsCssUrl;\n\n // Extract just the font-related properties you want to copy\n const fontStyles = `\n font-family: ${parentStyles.getPropertyValue('font-family')};\n font-size: ${parentStyles.getPropertyValue('font-size')};\n line-height: ${parentStyles.getPropertyValue('line-height')};\n font-weight: ${parentStyles.getPropertyValue('font-weight')};\n color: ${parentStyles.getPropertyValue('color')};\n `;\n\n return /* html */ `<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>QTI PCI Container</title>\n <base href=\"${window.location.origin}\" />\n <script type=\"module\">\n import '${componentsCdnUrl}';\n </script>\n <style>\n body, html {\n margin: 0;\n padding: 0;\n width: 100%;\n height: auto;\n overflow: hidden;\n /* Add the extracted font styles here */\n ${fontStyles}\n };\n .qti-customInteraction {\n width: 100%;\n height: 100%;\n }\n #pci-container {\n width: 100%;\n }\n qti-interaction-markup {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n </style>\n <link href=\"${componentsCssUrl}\" rel=\"stylesheet\" />\n <script src=\"${this.requireJsUrl}\"></script>\n <script>\n const forwardConsole = ${forwardConsole ? 'true' : 'false'};\n if (forwardConsole) {\n const originalLog = console.log.bind(console);\n const originalError = console.error.bind(console);\n const stringifyArgs = args =>\n args.map(arg => {\n if (typeof arg === 'string') return arg;\n try {\n return JSON.stringify(arg);\n } catch (e) {\n return String(arg);\n }\n });\n console.log = (...args) => {\n originalLog(...args);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'console',\n level: 'log',\n args: stringifyArgs(args)\n },\n '*'\n );\n };\n console.error = (...args) => {\n originalError(...args);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'console',\n level: 'error',\n args: stringifyArgs(args)\n },\n '*'\n );\n };\n }\n // Define standard paths and shims\n window.requirePaths = ${requirePaths};\n\n window.requireShim = ${requireShim};\n\n // Single initial RequireJS configuration with error handling\n window.requirejs.config({\n catchError: true,\n waitSeconds: 30,\n paths: window.requirePaths,\n baseUrl: '${iframeBaseUrl}',\n shim: window.requireShim,\n onNodeCreated: function (node, config, moduleName, url) {\n // Add error handler to script node\n node.addEventListener('error', function (evt) {\n console.error('Script load error for module:', moduleName, 'URL:', url, 'Event:', evt);\n });\n },\n onError: function (err) {\n console.error('RequireJS error:', {\n type: err.requireType,\n modules: err.requireModules,\n error: err\n });\n\n if (err.requireType === 'scripterror') {\n console.error('Script error usually indicates a network or CORS issue with:', err.requireModules);\n }\n\n // Notify parent window about the error\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: (window.PCIManager && window.PCIManager.responseIdentifier) || null,\n method: 'error',\n params: {\n message: 'RequireJS ' + err.requireType + ' error for modules: ' + err.requireModules,\n details: {\n type: err.requireType,\n modules: err.requireModules,\n error: err.toString()\n }\n }\n },\n '*'\n );\n }\n });\n\n // PCI Manager for iframe implementation\n window.PCIManager = {\n pciInstance: null,\n container: null,\n markupEl: null,\n propertiesEl: null,\n customInteractionTypeIdentifier: null,\n responseIdentifier: null,\n pendingBoundTo: null,\n pendingMarkup: null,\n pendingProperties: null,\n pendingState: null,\n pendingStylesheets: null,\n stylesheetKeys: {},\n interactionChangedViaEvent: false,\n eventBridgeAttached: false,\n lastResponseStr: null,\n hadResponse: false,\n\n initialize: function (config) {\n this.customInteractionTypeIdentifier = config.customInteractionTypeIdentifier;\n this.responseIdentifier = config.responseIdentifier;\n this.container = document.getElementById('pci-container');\n this.container.classList.add('qti-customInteraction');\n\n function qtiVariableHasValue(qtiVar) {\n if (!qtiVar) return false;\n if (qtiVar.base) {\n for (const k in qtiVar.base) {\n if (!Object.prototype.hasOwnProperty.call(qtiVar.base, k)) continue;\n const v = qtiVar.base[k];\n if (v !== null && v !== undefined && v !== '') return true;\n }\n }\n if (qtiVar.list) {\n for (const k in qtiVar.list) {\n if (!Object.prototype.hasOwnProperty.call(qtiVar.list, k)) continue;\n const v = qtiVar.list[k];\n if (Array.isArray(v) && v.some(x => x !== null && x !== undefined && x !== '')) return true;\n }\n }\n if (Array.isArray(qtiVar.record) && qtiVar.record.length > 0) return true;\n return false;\n }\n\n const initialBoundTo = config.boundTo && config.boundTo[this.responseIdentifier];\n this.hadResponse = qtiVariableHasValue(initialBoundTo);\n this.lastResponseStr = this.hadResponse ? JSON.stringify(initialBoundTo) : null;\n // Ensure expected DOM structure exists (markup + properties)\n this.markupEl = this.container.querySelector('qti-interaction-markup');\n if (!this.markupEl) {\n this.markupEl = document.createElement('qti-interaction-markup');\n this.container.appendChild(this.markupEl);\n }\n this.markupEl.classList.add('qti-customInteraction');\n this.propertiesEl = this.container.querySelector('properties');\n if (!this.propertiesEl) {\n this.propertiesEl = document.createElement('properties');\n this.propertiesEl.style.display = 'none';\n this.container.appendChild(this.propertiesEl);\n } else {\n this.propertiesEl.style.display = 'none';\n }\n\n // Apply any markup/properties that arrived before initialization\n if (this.pendingMarkup !== null) {\n this.setMarkup(this.pendingMarkup);\n this.pendingMarkup = null;\n }\n if (this.pendingProperties !== null) {\n this.setProperties(this.pendingProperties);\n this.pendingProperties = null;\n }\n if (this.pendingStylesheets !== null) {\n this.setStylesheets(this.pendingStylesheets);\n this.pendingStylesheets = null;\n }\n\n // Bridge qti-interaction-changed events (preferred over polling)\n if (!this.eventBridgeAttached) {\n this.eventBridgeAttached = true;\n const self = this;\n this.container.addEventListener(\n 'qti-interaction-changed',\n function (evt) {\n try {\n self.interactionChangedViaEvent = true;\n const value = evt && evt.detail ? evt.detail.value : undefined;\n if (value !== undefined) {\n const validFromEvent =\n evt && evt.detail && typeof evt.detail.valid === 'boolean' ? evt.detail.valid : undefined;\n let valid = validFromEvent;\n if (valid === undefined && self.pciInstance && typeof self.pciInstance.checkValidity === 'function') {\n try {\n valid = self.pciInstance.checkValidity();\n } catch (e) {\n // Keep undefined on PCI validity read errors.\n }\n }\n const customValidityFromEvent =\n evt && evt.detail && typeof evt.detail.customValidity === 'string'\n ? evt.detail.customValidity\n : undefined;\n let customValidity = customValidityFromEvent;\n if (\n customValidity === undefined &&\n self.pciInstance &&\n typeof self.pciInstance.getCustomValidity === 'function'\n ) {\n try {\n customValidity = self.pciInstance.getCustomValidity();\n } catch (e) {\n // Keep undefined on PCI custom validity read errors.\n }\n }\n const state =\n self.pciInstance && typeof self.pciInstance.getState === 'function'\n ? self.pciInstance.getState()\n : null;\n self.notifyInteractionChanged(value, state, valid, customValidity);\n }\n } catch (e) {\n // ignore bridge errors, polling fallback may still work\n }\n },\n true\n );\n }\n\n function getResolvablePath(path, basePath) {\n if (Array.isArray(path)) {\n return path.map(p => getResolvablePathString(p, basePath));\n } else {\n return getResolvablePathString(path, basePath);\n }\n }\n\n function removeDoubleSlashes(str) {\n return str\n .replace(/([^:\\\\/])\\\\/\\\\/+/g, '$1/')\n .replace(/\\\\/\\\\//g, '/')\n .replace('http:/', 'http://')\n .replace('https:/', 'https://');\n }\n\n function ensureDirectoryBasePath(basePath) {\n if (!basePath) return basePath;\n if (basePath.endsWith('/')) return basePath;\n return basePath + '/';\n }\n\n\n\n function combineRequireResolvePaths(path1, path2, baseUrl) {\n path1 = getResolvablePath(path1, baseUrl);\n const path1Array = Array.isArray(path1) ? path1 : [path1];\n if (!path2) {\n return path1Array;\n }\n path2 = getResolvablePath(path2, baseUrl);\n const path2Array = Array.isArray(path2) ? path2 : [path2];\n return path1Array.concat(path2Array).filter((value, index, self) => self.indexOf(value) === index);\n }\n\n // Update paths with modules from the config\n if (config.interactionModules && config.interactionModules.length > 0) {\n config.interactionModules.forEach(module => {\n if (module.id && module.primaryPath) {\n const currentPath = window.requirePaths[module.id] || [];\n const currentPaths = Array.isArray(currentPath) ? currentPath : [currentPath];\n const newPath = combineRequireResolvePaths(\n module.primaryPath,\n module.fallbackPath,\n config.baseUrl\n );\n window.requirePaths[module.id] = newPath.concat(currentPaths)\n .filter((value, index, self) => self.indexOf(value) === index);\n }\n });\n }\n\n // The ONLY other requirejs.config call - with the context for this specific PCI\n window.requirejs.config({\n context: this.customInteractionTypeIdentifier,\n paths: window.requirePaths,\n shim: window.requireShim\n });\n\n // Define qtiCustomInteractionContext for the PCI\n define('qtiCustomInteractionContext', () => {\n return {\n register: pciInstance => {\n this.pciInstance = pciInstance;\n // Configure PCI instance\n const pciConfig = {\n properties: config.properties || {},\n contextVariables: config.contextVariables || {},\n templateVariables: config.templateVariables || {},\n onready: pciInstance => {\n this.pciInstance = pciInstance;\n // Apply any pending updates that arrived before onready\n if (this.pendingBoundTo) {\n this.applyBoundTo(this.pendingBoundTo);\n this.pendingBoundTo = null;\n }\n if (this.pendingState && typeof this.pciInstance.setState === 'function') {\n this.pciInstance.setState(this.pendingState);\n this.pendingState = null;\n }\n this.notifyReady();\n },\n ondone: (pciInstance, response, state, status) => {\n const valid =\n this.pciInstance && typeof this.pciInstance.checkValidity === 'function'\n ? this.pciInstance.checkValidity()\n : undefined;\n const customValidity =\n this.pciInstance && typeof this.pciInstance.getCustomValidity === 'function'\n ? this.pciInstance.getCustomValidity()\n : undefined;\n this.notifyInteractionChanged(\n response,\n typeof state === 'string' ? state : null,\n valid,\n customValidity\n );\n },\n responseIdentifier: config.responseIdentifier,\n boundTo: config.boundTo\n };\n\n if (pciInstance.getInstance) {\n const dom = this.markupEl || this.container;\n // Round-trip support for object states (stored as a prefixed JSON string by the host).\n // For strict string-based PCIs we pass the original string through unchanged.\n let restoredState = config.state;\n if (typeof restoredState === 'string' && restoredState.indexOf('__qti_json__::') === 0) {\n try {\n restoredState = JSON.parse(restoredState.substring('__qti_json__::'.length));\n } catch (e) {\n // If parsing fails, fall back to the raw string.\n restoredState = config.state;\n }\n }\n pciInstance.getInstance(dom, pciConfig, restoredState || undefined);\n } else {\n this.notifyError('Loaded PCI module has no getInstance().');\n }\n },\n notifyReady: () => {\n PCIManager.notifyReady();\n }\n };\n });\n\n function getResolvablePathString(path, basePath) {\n path = path.replace(/\\\\.js$/, '');\n if (/^[a-z][a-z0-9+.-]*:/i.test(path) || !basePath) {\n return path;\n }\n\n if (path.startsWith('/') && !path.startsWith('//')) {\n path = path.slice(1);\n }\n\n try {\n const resolved = new URL(path, ensureDirectoryBasePath(basePath)).toString();\n return resolved.replace(/\\\\.js$/, '');\n } catch (error) {\n return removeDoubleSlashes(ensureDirectoryBasePath(basePath) + path);\n }\n }\n\n // Load the PCI module\n this.loadModule(config.module);\n },\n\n loadModule: function (modulePath) {\n try {\n // Get the context-specific require\n const contextRequire = window.requirejs.config({\n context: this.customInteractionTypeIdentifier\n });\n contextRequire(['require'], require => {\n // Now load the actual module\n require([modulePath], () => {}, err => {\n console.error('Error loading module:', modulePath, err);\n this.notifyError('Module load error: ' + err.toString());\n });\n });\n } catch (error) {\n console.error('Exception in loadModule:', modulePath);\n console.error(error);\n this.notifyError('Error in require call: ' + error.toString());\n }\n },\n\n notifyReady: function () {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'iframeReady'\n },\n '*'\n );\n },\n\n notifyInteractionChanged: function (response, state, valid, customValidity) {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'interactionChanged',\n params: {\n value: response,\n state: state,\n valid: typeof valid === 'boolean' ? valid : undefined,\n customValidity: typeof customValidity === 'string' ? customValidity : undefined\n }\n },\n '*'\n );\n },\n\n notifyError: function (message) {\n console.error('PCI Error:', message);\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: this.responseIdentifier,\n method: 'error',\n params: { message: message }\n },\n '*'\n );\n },\n\n setMarkup: function (markupHtml) {\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n if (!this.container) {\n this.pendingMarkup = markupHtml;\n return;\n }\n this.markupEl = this.container.querySelector('qti-interaction-markup');\n if (!this.markupEl) {\n this.markupEl = document.createElement('qti-interaction-markup');\n this.container.appendChild(this.markupEl);\n }\n this.markupEl.classList.add('qti-customInteraction');\n this.markupEl.innerHTML = markupHtml || '';\n },\n\n setProperties: function (propertiesHtml) {\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n if (!this.container) {\n this.pendingProperties = propertiesHtml;\n return;\n }\n this.propertiesEl = this.container.querySelector('properties');\n if (!this.propertiesEl) {\n this.propertiesEl = document.createElement('properties');\n this.container.appendChild(this.propertiesEl);\n }\n this.propertiesEl.style.display = 'none';\n this.propertiesEl.innerHTML = propertiesHtml || '';\n },\n\n minifyCss: function (cssContent) {\n return cssContent\n .replace(/\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\//g, '')\n .replace(/\\\\s+/g, ' ')\n .replace(/\\\\s*([{}:;])\\\\s*/g, '$1')\n .trim();\n },\n\n setStylesheets: function (stylesheetsHtml) {\n if (!stylesheetsHtml) return;\n if (!this.container) {\n this.container = document.getElementById('pci-container');\n }\n const target = this.container || document.body;\n if (!target) return;\n target.insertAdjacentHTML('afterbegin', stylesheetsHtml);\n },\n\n\n applyBoundTo: function (boundTo) {\n if (!this.pciInstance || typeof this.pciInstance.setResponse !== 'function') return;\n const value = boundTo && (boundTo[this.responseIdentifier] || boundTo[Object.keys(boundTo)[0]]);\n if (value) this.pciInstance.setResponse(value);\n }\n };\n\n // Set up message listener for communication with parent\n let expectedParentOrigin = null;\n window.addEventListener('message', function (event) {\n const { data } = event;\n\n // Ensure the message is from our parent\n if (event.source !== window.parent || !data || data.source !== 'qti-portable-custom-interaction') {\n return;\n }\n if (expectedParentOrigin === null) {\n expectedParentOrigin = event.origin;\n } else if (event.origin !== expectedParentOrigin) {\n return;\n }\n\n function deepQuerySelector(root, selector) {\n if (!root) return null;\n try {\n const direct = root.querySelector ? root.querySelector(selector) : null;\n if (direct) return direct;\n } catch (e) {\n // ignore invalid selector for this root\n }\n if (!root.querySelectorAll) return null;\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if (node && node.shadowRoot) {\n const found = deepQuerySelector(node.shadowRoot, selector);\n if (found) return found;\n }\n }\n return null;\n }\n\n function deepFindElementByExactText(root, text) {\n if (!root || !text) return null;\n if (root.querySelectorAll) {\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if ((node.textContent || '').trim() === text) return node;\n if (node.shadowRoot) {\n const found = deepFindElementByExactText(node.shadowRoot, text);\n if (found) return found;\n }\n }\n }\n return null;\n }\n\n switch (data.method) {\n case 'initialize':\n PCIManager.initialize(data.params);\n break;\n\n case 'setMarkup':\n PCIManager.setMarkup(data.params);\n break;\n\n case 'setBoundTo':\n if (PCIManager.pciInstance) {\n PCIManager.applyBoundTo(data.params);\n } else {\n PCIManager.pendingBoundTo = data.params;\n }\n break;\n\n case 'setProperties':\n PCIManager.setProperties(data.params);\n break;\n\n case 'setStylesheets':\n PCIManager.setStylesheets(data.params);\n break;\n\n case 'setState':\n if (PCIManager.pciInstance && typeof PCIManager.pciInstance.setState === 'function') {\n PCIManager.pciInstance.setState((data.params && data.params.state) || data.params);\n } else {\n PCIManager.pendingState = (data.params && data.params.state) || data.params;\n }\n break;\n\n case 'getContent': {\n const messageId = data.params && data.params.messageId;\n const collectShadowHtml = root => {\n const parts = [];\n if (!root || !root.querySelectorAll) return parts;\n const nodes = root.querySelectorAll('*');\n for (const node of nodes) {\n if (node && node.shadowRoot) {\n parts.push(node.shadowRoot.innerHTML || '');\n parts.push(...collectShadowHtml(node.shadowRoot));\n }\n }\n return parts;\n };\n const shadowHtml = collectShadowHtml(document).join('\\\\n');\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'getContentResponse',\n messageId: messageId,\n content: (document.documentElement ? document.documentElement.outerHTML : '') + '\\\\n' + shadowHtml\n },\n '*'\n );\n break;\n }\n\n case 'simulateClick': {\n const messageId = data.params && data.params.messageId;\n const x = data.params && data.params.x;\n const y = data.params && data.params.y;\n const el = typeof x === 'number' && typeof y === 'number' ? document.elementFromPoint(x, y) : null;\n const target = (el && el.closest && el.closest('.hitbox')) || document.querySelector('.hitbox') || el;\n if (target) {\n const evt = new MouseEvent('click', {\n bubbles: true,\n clientX: x,\n clientY: y,\n screenX: x,\n screenY: y,\n view: window\n });\n target.dispatchEvent(evt);\n }\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickResponse',\n messageId: messageId\n },\n '*'\n );\n break;\n }\n\n case 'getBoundingRect': {\n const messageId = data.params && data.params.messageId;\n const selector = data.params && data.params.selector;\n const el = selector ? deepQuerySelector(document, selector) : null;\n const rect = el && typeof el.getBoundingClientRect === 'function' ? el.getBoundingClientRect() : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'getBoundingRectResponse',\n messageId: messageId,\n rect: rect\n ? {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height\n }\n : null\n },\n '*'\n );\n break;\n }\n\n case 'clickOnSelector': {\n const messageId = data.params && data.params.messageId;\n const selector = data.params && data.params.selector;\n const el = selector ? deepQuerySelector(document, selector) : null;\n const success = !!el;\n if (el && typeof el.click === 'function') el.click();\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickSelectorResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\n\n case 'clickOnElementByText': {\n const messageId = data.params && data.params.messageId;\n const text = data.params && data.params.text;\n const target = text ? deepFindElementByExactText(document, text) : null;\n const success = !!target;\n if (target && typeof target.click === 'function') target.click();\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'clickTextResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\n\n case 'setValueElement': {\n const messageId = data.params && data.params.messageId;\n const selector = data.params && data.params.selector;\n const value = data.params && data.params.value;\n const el = selector ? deepQuerySelector(document, selector) : null;\n let success = false;\n if (el && 'value' in el) {\n try {\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n success = true;\n } catch (e) {\n success = false;\n }\n }\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'setValueResponse',\n messageId: messageId,\n success: success\n },\n '*'\n );\n break;\n }\n\n case 'console':\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'console',\n level: data.level,\n args: data.args\n },\n '*'\n );\n break;\n }\n });\n\n let resizeTimeout;\n let previousHeight = 0;\n const notifyResize = () => {\n const container = document.getElementById('pci-container');\n const newHeight = container.scrollHeight + 100;\n if (newHeight !== previousHeight) {\n previousHeight = newHeight;\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => {\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'resize',\n height: newHeight,\n width: container.scrollWidth\n },\n '*'\n );\n }, 100); // Adjust debounce time as needed\n }\n };\n\n function setupResizeObserver() {\n const container = document.getElementById('pci-container');\n if (!container || !(container instanceof Element)) {\n console.warn('ResizeObserver: document.container is not an Element');\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n notifyResize();\n });\n\n resizeObserver.observe(container);\n }\n\n // Run setup once DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n notifyResize(); // initial resize\n setupResizeObserver();\n });\n } else {\n notifyResize();\n setupResizeObserver();\n }\n\n window.addEventListener('load', () => {\n notifyResize();\n });\n let lastResponseStr = '';\n setInterval(() => {\n if (PCIManager.interactionChangedViaEvent) return;\n if (PCIManager.pciInstance && PCIManager.pciInstance.getResponse) {\n const response = PCIManager.pciInstance.getResponse();\n const valid =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.checkValidity === 'function'\n ? PCIManager.pciInstance.checkValidity()\n : undefined;\n const customValidity =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getCustomValidity === 'function'\n ? PCIManager.pciInstance.getCustomValidity()\n : undefined;\n if (response === undefined) {\n // Don't emit an initial empty on load; only emit a clear if we previously had a value\n if (!PCIManager.hadResponse) return;\n PCIManager.hadResponse = false;\n PCIManager.lastResponseStr = null;\n const state =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function'\n ? PCIManager.pciInstance.getState()\n : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'interactionChanged',\n params: { value: null, state: state, valid: valid, customValidity: customValidity }\n },\n '*'\n );\n return;\n }\n\n const responseStr = JSON.stringify(response);\n\n if (responseStr !== PCIManager.lastResponseStr) {\n PCIManager.lastResponseStr = responseStr;\n PCIManager.hadResponse = true;\n const state =\n PCIManager.pciInstance && typeof PCIManager.pciInstance.getState === 'function'\n ? PCIManager.pciInstance.getState()\n : null;\n window.parent.postMessage(\n {\n source: 'qti-pci-iframe',\n responseIdentifier: PCIManager.responseIdentifier,\n method: 'interactionChanged',\n params: { value: response, state: state, valid: valid, customValidity: customValidity }\n },\n '*'\n );\n }\n }\n }, 500); // Check every 500ms\n </script>\n </head>\n <body>\n <div id=\"pci-container\"></div>\n </body>\n </html>`;\n }\n\n /**\n * Toggle the display of the correct response\n * @param responseVariable The response variable containing the correct response\n * @param show Whether to show or hide the correct response\n */\n public override toggleInternalCorrectResponse(show: boolean) {\n const responseVariable = this.responseVariable;\n\n // Store the correct response or clear it based on the show parameter\n this.correctResponse = show\n ? responseVariable?.correctResponse\n : responseVariable.cardinality === 'single'\n ? ''\n : [];\n\n // Get unique identifiers for this PCI's correct response elements\n const containerId = `correct-response-container-${this.responseIdentifier}`;\n\n // Check the parent element for any existing containers with this ID\n const existingContainers = this.parentElement?.querySelectorAll(`#${containerId}`);\n if (existingContainers) {\n existingContainers.forEach(existingContainer => {\n existingContainer.remove();\n });\n }\n\n // Handle the current interaction's state\n if (show) {\n // Disable the current interaction when showing correct response\n this.disable();\n } else {\n // Enable the current interaction when hiding correct response\n this.enable();\n return; // Exit early, nothing else to do\n }\n\n // If there's no correct response to show, exit\n if (!show || !responseVariable?.correctResponse) {\n return;\n }\n\n // Create a container for the correct response viewer\n const correctResponseContainer = document.createElement('div');\n correctResponseContainer.id = containerId;\n correctResponseContainer.className = 'pci-correct-response-container';\n correctResponseContainer.style.position = 'relative';\n correctResponseContainer.style.marginTop = '20px';\n correctResponseContainer.style.border = '2px solid green';\n correctResponseContainer.style.padding = '16px';\n correctResponseContainer.style.borderRadius = '4px';\n correctResponseContainer.style.backgroundColor = 'rgba(0, 128, 0, 0.05)';\n\n // Add a label for the correct response\n const label = document.createElement('div');\n label.textContent = 'Correct Response:';\n label.style.fontWeight = 'bold';\n label.style.marginBottom = '10px';\n label.style.color = 'green';\n correctResponseContainer.appendChild(label);\n\n // Instead of cloning, we'll create a new instance and copy necessary attributes\n const correctResponseViewer = document.createElement(\n 'qti-portable-custom-interaction'\n ) as QtiPortableCustomInteraction;\n\n // Copy all attributes from the original PCI\n Array.from(this.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'response-identifier') {\n correctResponseViewer.setAttribute(attr.name, attr.value);\n }\n });\n\n // Set a unique response identifier to avoid conflicts\n const originalResponseId = this.responseIdentifier;\n correctResponseViewer.responseIdentifier = `${originalResponseId}-correct`;\n\n // Copy any light DOM content from the original PCI\n // This includes markup and properties\n Array.from(this.children).forEach(child => {\n const clonedChild = child.cloneNode(true);\n correctResponseViewer.appendChild(clonedChild);\n });\n\n // Store the correct response value\n const correctResponseValue = responseVariable.correctResponse;\n\n // Ensure the correct-response viewer is initialized and then configured in the iframe\n const originalConnectedCallback = correctResponseViewer.connectedCallback;\n correctResponseViewer.connectedCallback = function () {\n originalConnectedCallback.call(this);\n\n const applyCorrectResponse = () => {\n const qtiVariableJSON = this.responseVariablesToQtiVariableJSON(\n correctResponseValue,\n responseVariable.cardinality,\n responseVariable.baseType\n );\n\n this.sendMessageToIframe('setBoundTo', {\n [originalResponseId]: qtiVariableJSON\n });\n this.sendMessageToIframe('setState', { state: 'review' });\n };\n\n if (this._iframeLoaded) {\n applyCorrectResponse();\n } else {\n this.addEventListener('qti-portable-custom-interaction-loaded', applyCorrectResponse, { once: true });\n }\n };\n\n // Make sure the viewer is not interactive\n correctResponseViewer.style.pointerEvents = 'none';\n\n // Add the correct response viewer to the container\n correctResponseContainer.appendChild(correctResponseViewer);\n\n // Append the container after this PCI\n this.after(correctResponseContainer);\n }\n /**\n * Method to disable the PCI for review mode\n * This can be used when showing the correct response\n */\n public disable() {\n // First, store the current state of the PCI\n this.#previousState = {\n pointerEvents: this.style.pointerEvents,\n position: this.style.position\n };\n\n this.sendMessageToIframe('setState', { state: 'disabled' });\n\n // Add an overlay to prevent interaction if not already there\n const existingOverlay = this.querySelector('.pci-interaction-overlay');\n if (!existingOverlay) {\n const overlay = document.createElement('div');\n overlay.className = 'pci-interaction-overlay';\n overlay.style.position = 'absolute';\n overlay.style.top = '0';\n overlay.style.left = '0';\n overlay.style.width = '100%';\n overlay.style.height = '100%';\n overlay.style.backgroundColor = 'rgba(200, 200, 200, 0.3)';\n overlay.style.zIndex = '100';\n overlay.style.pointerEvents = 'all';\n overlay.style.cursor = 'not-allowed';\n\n // Make sure the container is relatively positioned\n if (getComputedStyle(this).position === 'static') {\n this.style.position = 'relative';\n }\n\n this.appendChild(overlay);\n }\n }\n\n /**\n * Method to enable the PCI for interactive mode\n */\n public enable() {\n // Remove any overlays\n const overlay = this.querySelector('.pci-interaction-overlay');\n if (overlay) {\n overlay.remove();\n }\n\n // Restore previous state if available\n if (this.#previousState) {\n if (this.#previousState.pointerEvents) {\n this.style.pointerEvents = this.#previousState.pointerEvents;\n }\n if (this.#previousState.position) {\n this.style.position = this.#previousState.position;\n }\n this.#previousState = null;\n }\n\n this.sendMessageToIframe('setState', { state: 'interacting' });\n }\n\n // Add this property to store the previous state\n #previousState: {\n pointerEvents?: string;\n position?: string;\n } = null;\n\n override render() {\n return html`\n <slot></slot>\n ${this._errorMessage\n ? html`<div style=\"color:red\">\n <h1>Error</h1>\n ${this._errorMessage}\n </div>`\n : ''}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-portable-custom-interaction': QtiPortableCustomInteraction;\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
// import componentStyles from '../../utilities/styles/component.styles';
|
|
3
|
+
/* ${componentStyles} */
|
|
4
|
+
export default css `
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
width: 100%;
|
|
8
|
+
min-height: 50px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
::slotted(qti-interaction-markup) {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
//# sourceMappingURL=qti-portable-custom-interaction.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-portable-custom-interaction.styles.js","sourceRoot":"","sources":["../src/qti-portable-custom-interaction.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,yEAAyE;AAEzE,wBAAwB;AACxB,eAAe,GAAG,CAAA;;;;;;;;;;CAUjB,CAAC","sourcesContent":["import { css } from 'lit';\n// import componentStyles from '../../utilities/styles/component.styles';\n\n/* ${componentStyles} */\nexport default css`\n :host {\n display: block;\n width: 100%;\n min-height: 50px;\n }\n\n ::slotted(qti-interaction-markup) {\n display: none;\n }\n`;\n"]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { QtiPortableCustomInteraction } from './qti-portable-custom-interaction';
|
|
2
|
+
import type { ItemContext } from '@qti-components/base';
|
|
3
|
+
/**
|
|
4
|
+
* Test-specific extension of QtiPortableCustomInteraction that adds methods
|
|
5
|
+
* for interacting with the iframe content in tests.
|
|
6
|
+
*/
|
|
7
|
+
export declare class QtiPortableCustomInteractionTest extends QtiPortableCustomInteraction {
|
|
8
|
+
#private;
|
|
9
|
+
/**
|
|
10
|
+
* Gets the HTML content of the iframe for testing purposes
|
|
11
|
+
* @returns Promise that resolves with the HTML content string
|
|
12
|
+
*/
|
|
13
|
+
getIFrameContent(): Promise<string>;
|
|
14
|
+
setTestContext(newContext: ItemContext): void;
|
|
15
|
+
/**
|
|
16
|
+
* Recreates the iframe completely
|
|
17
|
+
* @returns Promise that resolves when the iframe is loaded
|
|
18
|
+
*/
|
|
19
|
+
recreateIframe(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Override the original disconnectedCallback to handle iframe recreation
|
|
22
|
+
*/
|
|
23
|
+
disconnectedCallback(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Simulates a mouse click at specific coordinates within the iframe
|
|
26
|
+
* @param x The x coordinate
|
|
27
|
+
* @param y The y coordinate
|
|
28
|
+
* @returns Promise that resolves when the click is performed
|
|
29
|
+
*/
|
|
30
|
+
iFrameMouseClick(x: number, y: number): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Clicks on an element identified by a CSS selector
|
|
33
|
+
* @param selector The CSS selector string
|
|
34
|
+
* @returns Promise that resolves with boolean indicating if the element was found and clicked
|
|
35
|
+
*/
|
|
36
|
+
iFrameClickOnElement(selector: string): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Clicks on an element containing the specified text
|
|
39
|
+
* @param text The text to search for within elements
|
|
40
|
+
* @returns Promise that resolves with boolean indicating if the element was found and clicked
|
|
41
|
+
*/
|
|
42
|
+
iFrameClickOnElementByText(text: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Sets the value of an input element identified by a CSS selector
|
|
45
|
+
* @param selector The CSS selector string
|
|
46
|
+
* @param value The value to set
|
|
47
|
+
* @returns Promise that resolves with boolean indicating if the element was found and value was set
|
|
48
|
+
*/
|
|
49
|
+
iFrameSetValueElement(selector: string, value: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Gets the bounding client rect for an element inside the iframe
|
|
52
|
+
* @param selector The CSS selector string
|
|
53
|
+
* @returns Promise that resolves with the rect or null
|
|
54
|
+
*/
|
|
55
|
+
iFrameGetBoundingClientRect(selector: string): Promise<{
|
|
56
|
+
left: number;
|
|
57
|
+
top: number;
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
} | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Sets the value of an input element containing the specified text
|
|
63
|
+
* @param text The text to search for within elements
|
|
64
|
+
* @param value The value to set
|
|
65
|
+
* @returns Promise that resolves with boolean indicating if the element was found and value was set
|
|
66
|
+
*/
|
|
67
|
+
iFrameSetValueElementByText(text: string, value: string): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Performs a mousedown event on an element identified by a CSS selector
|
|
70
|
+
* @param selector The CSS selector string
|
|
71
|
+
* @returns Promise that resolves with boolean indicating if the element was found and mousedown was performed
|
|
72
|
+
*/
|
|
73
|
+
iFrameMousedownOnElement(selector: string): Promise<boolean>;
|
|
74
|
+
/**
|
|
75
|
+
* Override the original generateIframeContent method to include
|
|
76
|
+
* the test message handlers in the iframe HTML
|
|
77
|
+
*/
|
|
78
|
+
generateIframeContent(): string;
|
|
79
|
+
}
|
|
80
|
+
declare global {
|
|
81
|
+
interface HTMLElementTagNameMap {
|
|
82
|
+
'qti-portable-custom-interaction-test': QtiPortableCustomInteractionTest;
|
|
83
|
+
}
|
|
84
|
+
}
|