'use strict'; const { JSDOM } = require('jsdom'); const moment = require('moment'); function q(context, selector, attrArg, trim = true) { const attr = attrArg === true ? 'textContent' : attrArg; if (attr) { const value = context.querySelector(selector)?.[attr]; return trim ? value?.trim() : value; } return context.querySelector(selector); } function qall(context, selector, attrArg, trim = true) { const attr = attrArg === true ? 'textContent' : attrArg; if (attr) { return Array.from(context.querySelectorAll(selector), el => (trim ? el[attr]?.trim() : el[attr])); } return Array.from(context.querySelectorAll(selector)); } function qdate(context, selector, format, match, attr = 'textContent') { const dateString = context.querySelector(selector)?.[attr]; if (!dateString) return null; if (match) { const dateStamp = dateString.match(match); if (dateStamp) return moment.utc(dateStamp[0], format).toDate(); return null; } return moment.utc(dateString.trim(), format).toDate(); } function qimages(context, selector = 'img', attr = 'src') { return qall(context, selector, attr); } function qurls(context, selector = 'a', attr = 'href') { return qall(context, selector, attr); } function qposter(context, selector = 'video', attr = 'poster') { return q(context, selector, attr); } function qtrailer(context, selector = 'source', attr = 'src') { return q(context, selector, attr); } function qlength(context, selector, attr = 'textContent') { const durationString = q(context, selector, attr); const duration = durationString.match(/(\d+:)?\d+:\d+/); if (duration) { const segments = ['00'].concat(duration[0].split(':')).slice(-3); return moment.duration(segments.join(':')).asSeconds(); } return null; } const funcs = { q, qall, qdate, qimages, qposter, qlength, qtrailer, qurls, qa: qall, qd: qdate, qi: qimages, qp: qposter, ql: qlength, qt: qtrailer, qu: qurls, }; function ctx(element, window) { const contextFuncs = Object.entries(funcs) // dynamically attach methods with context .reduce((acc, [key, func]) => ({ ...acc, [key]: (...args) => (window && args[0] instanceof window.HTMLElement // allow for different context ? func(...args) : func(element, ...args)), }), {}); return { element, ...(window && { window }), ...contextFuncs, }; } function ctxa(context, selector) { return Array.from(context.querySelectorAll(selector)).map(element => ctx(element)); } function ex(html) { const { window } = new JSDOM(html); return ctx(window.document, window); } module.exports = { ex, ctx, ctxa, ...funcs, };