@patch-adams/core 1.4.2 → 1.4.3
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/cli.cjs +127 -30
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +127 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +127 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +127 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3062,49 +3062,146 @@ function generateLrsBridgeCode(options) {
|
|
|
3062
3062
|
function setupMediaInterceptors() {
|
|
3063
3063
|
if (!TRACK_MEDIA) return;
|
|
3064
3064
|
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3065
|
+
// Track which elements we've already attached listeners to
|
|
3066
|
+
var trackedMedia = new WeakSet();
|
|
3067
|
+
|
|
3068
|
+
// Helper to get media name/title from element or surrounding context
|
|
3069
|
+
function getMediaName(el) {
|
|
3070
|
+
// Check element attributes
|
|
3071
|
+
var name = el.title || el.getAttribute('aria-label') || el.getAttribute('data-name');
|
|
3072
|
+
if (name) return name;
|
|
3073
|
+
|
|
3074
|
+
// Check parent Rise video block for title
|
|
3075
|
+
var videoBlock = findClosest(el, '[data-block-type="video"], .blocks-video, .video-block');
|
|
3076
|
+
if (videoBlock) {
|
|
3077
|
+
var titleEl = videoBlock.querySelector('.video-title, .block-title, [class*="title"]');
|
|
3078
|
+
if (titleEl) return titleEl.textContent.trim();
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
// Use src filename as fallback
|
|
3082
|
+
var src = el.src || el.currentSrc || '';
|
|
3083
|
+
if (src) {
|
|
3084
|
+
var filename = src.split('/').pop().split('?')[0];
|
|
3085
|
+
if (filename && filename.length < 100) return filename;
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
return el.tagName.toLowerCase();
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
// Attach media event listeners to a single element
|
|
3092
|
+
function attachMediaListeners(el) {
|
|
3093
|
+
if (trackedMedia.has(el)) return;
|
|
3094
|
+
trackedMedia.add(el);
|
|
3095
|
+
|
|
3096
|
+
var mediaType = el.tagName.toLowerCase();
|
|
3097
|
+
log('Attaching media listeners to:', mediaType, el.src || el.currentSrc || 'no-src');
|
|
3098
|
+
|
|
3099
|
+
el.addEventListener('play', function() {
|
|
3100
|
+
log('Media play event captured:', mediaType);
|
|
3068
3101
|
LRS.mediaPlayed({
|
|
3069
|
-
type:
|
|
3070
|
-
src:
|
|
3071
|
-
name:
|
|
3072
|
-
currentTime:
|
|
3073
|
-
duration:
|
|
3102
|
+
type: mediaType,
|
|
3103
|
+
src: el.src || el.currentSrc || '',
|
|
3104
|
+
name: getMediaName(el),
|
|
3105
|
+
currentTime: el.currentTime || 0,
|
|
3106
|
+
duration: el.duration || 0,
|
|
3074
3107
|
action: 'play'
|
|
3075
3108
|
});
|
|
3076
|
-
}
|
|
3077
|
-
}, true);
|
|
3109
|
+
});
|
|
3078
3110
|
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3111
|
+
el.addEventListener('pause', function() {
|
|
3112
|
+
// Ignore pause events that fire right before ended
|
|
3113
|
+
if (el.ended) return;
|
|
3114
|
+
log('Media pause event captured:', mediaType);
|
|
3082
3115
|
LRS.mediaPlayed({
|
|
3083
|
-
type:
|
|
3084
|
-
src:
|
|
3085
|
-
name:
|
|
3086
|
-
currentTime:
|
|
3087
|
-
duration:
|
|
3116
|
+
type: mediaType,
|
|
3117
|
+
src: el.src || el.currentSrc || '',
|
|
3118
|
+
name: getMediaName(el),
|
|
3119
|
+
currentTime: el.currentTime || 0,
|
|
3120
|
+
duration: el.duration || 0,
|
|
3088
3121
|
action: 'pause'
|
|
3089
3122
|
});
|
|
3090
|
-
}
|
|
3091
|
-
}, true);
|
|
3123
|
+
});
|
|
3092
3124
|
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
if (target.tagName === 'VIDEO' || target.tagName === 'AUDIO') {
|
|
3125
|
+
el.addEventListener('ended', function() {
|
|
3126
|
+
log('Media ended event captured:', mediaType);
|
|
3096
3127
|
LRS.mediaPlayed({
|
|
3097
|
-
type:
|
|
3098
|
-
src:
|
|
3099
|
-
name:
|
|
3100
|
-
currentTime:
|
|
3101
|
-
duration:
|
|
3128
|
+
type: mediaType,
|
|
3129
|
+
src: el.src || el.currentSrc || '',
|
|
3130
|
+
name: getMediaName(el),
|
|
3131
|
+
currentTime: el.duration || 0,
|
|
3132
|
+
duration: el.duration || 0,
|
|
3102
3133
|
action: 'completed'
|
|
3103
3134
|
});
|
|
3135
|
+
});
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
// Scan for and attach listeners to all video/audio elements
|
|
3139
|
+
function scanForMedia(root) {
|
|
3140
|
+
var elements = (root || document).querySelectorAll('video, audio');
|
|
3141
|
+
log('Scanning for media elements, found:', elements.length);
|
|
3142
|
+
for (var i = 0; i < elements.length; i++) {
|
|
3143
|
+
attachMediaListeners(elements[i]);
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
// Initial scan
|
|
3148
|
+
scanForMedia();
|
|
3149
|
+
|
|
3150
|
+
// Document-level capture for any we might miss
|
|
3151
|
+
document.addEventListener('play', function(e) {
|
|
3152
|
+
var target = e.target;
|
|
3153
|
+
if (target.tagName === 'VIDEO' || target.tagName === 'AUDIO') {
|
|
3154
|
+
// Attach listeners if not already tracked
|
|
3155
|
+
if (!trackedMedia.has(target)) {
|
|
3156
|
+
log('Captured play from untracked media, attaching listeners');
|
|
3157
|
+
attachMediaListeners(target);
|
|
3158
|
+
}
|
|
3104
3159
|
}
|
|
3105
3160
|
}, true);
|
|
3106
3161
|
|
|
3107
|
-
|
|
3162
|
+
// MutationObserver to detect dynamically added video/audio elements
|
|
3163
|
+
var mediaObserver = new MutationObserver(function(mutations) {
|
|
3164
|
+
var needsScan = false;
|
|
3165
|
+
mutations.forEach(function(mutation) {
|
|
3166
|
+
mutation.addedNodes.forEach(function(node) {
|
|
3167
|
+
if (node.nodeType === 1) {
|
|
3168
|
+
if (node.tagName === 'VIDEO' || node.tagName === 'AUDIO') {
|
|
3169
|
+
attachMediaListeners(node);
|
|
3170
|
+
} else if (node.querySelectorAll) {
|
|
3171
|
+
// Check for nested video/audio
|
|
3172
|
+
var nested = node.querySelectorAll('video, audio');
|
|
3173
|
+
if (nested.length > 0) {
|
|
3174
|
+
needsScan = true;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
});
|
|
3179
|
+
});
|
|
3180
|
+
if (needsScan) {
|
|
3181
|
+
scanForMedia();
|
|
3182
|
+
}
|
|
3183
|
+
});
|
|
3184
|
+
|
|
3185
|
+
// Start observing once DOM is ready
|
|
3186
|
+
function startMediaObserver() {
|
|
3187
|
+
if (document.body) {
|
|
3188
|
+
mediaObserver.observe(document.body, {
|
|
3189
|
+
childList: true,
|
|
3190
|
+
subtree: true
|
|
3191
|
+
});
|
|
3192
|
+
log('Media mutation observer started');
|
|
3193
|
+
} else {
|
|
3194
|
+
setTimeout(startMediaObserver, 100);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
startMediaObserver();
|
|
3198
|
+
|
|
3199
|
+
// Periodic rescan for Rise lazy-loaded content
|
|
3200
|
+
setInterval(function() {
|
|
3201
|
+
scanForMedia();
|
|
3202
|
+
}, 3000);
|
|
3203
|
+
|
|
3204
|
+
log('Media interceptors set up (enhanced)');
|
|
3108
3205
|
}
|
|
3109
3206
|
|
|
3110
3207
|
function setupNavigationInterceptors() {
|
|
@@ -3345,7 +3442,7 @@ function generateLrsBridgeCode(options) {
|
|
|
3345
3442
|
// ========================================================================
|
|
3346
3443
|
|
|
3347
3444
|
function init() {
|
|
3348
|
-
log('Initializing LRS bridge v2.
|
|
3445
|
+
log('Initializing LRS bridge v2.3.0...');
|
|
3349
3446
|
|
|
3350
3447
|
// Extract course info early
|
|
3351
3448
|
extractCourseInfo();
|