@patch-adams/core 1.5.8 → 1.5.10

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/dist/index.cjs CHANGED
@@ -625,12 +625,30 @@ function generateLrsBridgeCode(options) {
625
625
  });
626
626
  }
627
627
 
628
- // Decode HTML entities (e.g., " " & ') to clean text
628
+ // Clean HTML entities from text \u2014 handles both proper (") and broken (quot;) forms
629
+ // Rise strips the & from entities in SCORM interaction IDs, so we need both
629
630
  function decodeEntities(str) {
630
631
  if (!str || typeof str !== 'string') return str;
631
- var txt = document.createElement('textarea');
632
- txt.innerHTML = str;
633
- return txt.value;
632
+ // 1. Replace known broken entities (without &) that Rise leaves behind
633
+ str = str
634
+ .replace(/quot;/g, '"')
635
+ .replace(/apos;/g, "'")
636
+ .replace(/amp;/g, '&')
637
+ .replace(/lt;/g, '<')
638
+ .replace(/gt;/g, '>')
639
+ .replace(/nbsp;/g, ' ');
640
+ // 2. Replace numeric entities like &#34; &#39; &#x22; etc.
641
+ str = str.replace(/&#(x?[0-9a-fA-F]+);/g, function(match, code) {
642
+ var num = code.charAt(0) === 'x' ? parseInt(code.substring(1), 16) : parseInt(code, 10);
643
+ return isNaN(num) ? match : String.fromCharCode(num);
644
+ });
645
+ // 3. Catch any remaining standard &entities; via textarea decode
646
+ try {
647
+ var txt = document.createElement('textarea');
648
+ txt.innerHTML = str;
649
+ str = txt.value;
650
+ } catch (e) {}
651
+ return str;
634
652
  }
635
653
 
636
654
  LRS.sessionId = generateUUID();
@@ -3369,6 +3387,22 @@ function generateLrsBridgeCode(options) {
3369
3387
  sendStatement(statement);
3370
3388
  };
3371
3389
 
3390
+ // Send a "launched" statement \u2014 called by skin after email gate / actor setup
3391
+ LRS.sendLaunchStatement = function(data) {
3392
+ data = data || {};
3393
+ var activityDetails = {
3394
+ launchSource: data.source || 'email-gate',
3395
+ employeeEmail: data.email || (LRS.actor && LRS.actor.mbox ? LRS.actor.mbox.replace('mailto:', '') : undefined),
3396
+ employeeId: data.employeeId || LRS.employeeId || undefined
3397
+ };
3398
+
3399
+ if (data.employeeName) activityDetails.employeeName = data.employeeName;
3400
+
3401
+ var statement = buildStatement('launched', ACTIVITY_TYPES.course, activityDetails, null, null);
3402
+ log('Sending launch statement for:', activityDetails.employeeEmail || '(unknown)');
3403
+ sendStatement(statement);
3404
+ };
3405
+
3372
3406
  /**
3373
3407
  * Re-extract actor from SCORM after LMSInitialize has been called.
3374
3408
  * Call this from the SCORM wrapper after scormInit() succeeds,