Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
- Base: wintercms/winter branch 1.2 (full framework) - Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS - Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication - Partials: hero (offline-first), features, modes (offline/nube toggle), screenshots, pricing (3 planes), comparison, FAQ, CTA - Plugin VivesPOS.Site with ContactForm - Dockerfile: PHP 8.2 Apache, port 80, healthcheck - Added winter/wn-pages, blog, sitemap, seo plugins - Active theme set to vivespos
190 lines
4.7 KiB
JavaScript
190 lines
4.7 KiB
JavaScript
/* globals __dirname, URL */
|
|
|
|
import { JSDOM } from 'jsdom'
|
|
import path from 'path'
|
|
|
|
export default class FakeDom
|
|
{
|
|
constructor(content, options)
|
|
{
|
|
if (options === undefined) {
|
|
options = {};
|
|
}
|
|
|
|
// Header settings
|
|
this.url = options.url || `file://${path.resolve(__dirname, '../../../../')}`;
|
|
this.referer = options.referer;
|
|
this.contentType = options.contentType || 'text/html';
|
|
|
|
// Content settings
|
|
this.headStart = options.headStart || '<!DOCTYPE html><html><head><title>Fake document</title>';
|
|
this.headEnd = options.headEnd || '</head>';
|
|
this.bodyStart = options.bodyStart || '<body>';
|
|
this.content = content || '';
|
|
this.bodyEnd = options.bodyEnd || '</body>';
|
|
this.foot = options.foot || '</html>';
|
|
|
|
// Callback settings
|
|
this.beforeParse = (typeof options.beforeParse === 'function')
|
|
? options.beforeParse
|
|
: undefined;
|
|
|
|
// Assets
|
|
this.css = [];
|
|
this.scripts = [];
|
|
this.inline = [];
|
|
}
|
|
|
|
static new(content, options)
|
|
{
|
|
return new FakeDom(content, options);
|
|
}
|
|
|
|
setContent(content)
|
|
{
|
|
this.content = content;
|
|
return this;
|
|
}
|
|
|
|
addScript(script, id)
|
|
{
|
|
if (Array.isArray(script)) {
|
|
script.forEach((item) => {
|
|
this.addScript(item);
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
let url = new URL(script, this.url);
|
|
let base = new URL(this.url);
|
|
|
|
if (url.host === base.host) {
|
|
this.scripts.push({
|
|
url: `${url.pathname}`,
|
|
id: id || this.generateId(),
|
|
});
|
|
} else {
|
|
this.scripts.push({
|
|
url,
|
|
id: id || this.generateId(),
|
|
});
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
addCss(css, id)
|
|
{
|
|
if (Array.isArray(css)) {
|
|
css.forEach((item) => {
|
|
this.addCss(item)
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
let url = new URL(css, this.url);
|
|
let base = new URL(this.url);
|
|
|
|
if (url.host === base.host) {
|
|
this.css.push({
|
|
url: `${url.pathname}`,
|
|
id: id || this.generateId(),
|
|
});
|
|
} else {
|
|
this.css.push({
|
|
url,
|
|
id: id || this.generateId(),
|
|
});
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
addInlineScript(script, id)
|
|
{
|
|
this.inline.push({
|
|
script,
|
|
id: id || this.generateId(),
|
|
element: null,
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
generateId()
|
|
{
|
|
let id = 'script-';
|
|
let chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-';
|
|
let charLength = chars.length;
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
let currentChar = chars.substr(Math.floor(Math.random() * charLength), 1);
|
|
id = `${id}${currentChar}`;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
render(content)
|
|
{
|
|
if (content) {
|
|
this.content = content;
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
try {
|
|
const dom = new JSDOM(
|
|
this._renderContent(),
|
|
{
|
|
url: this.url,
|
|
referrer: this.referer,
|
|
contentType: this.contentType,
|
|
includeNodeLocations: true,
|
|
runScripts: 'dangerously',
|
|
resources: 'usable',
|
|
pretendToBeVisual: true,
|
|
beforeParse: this.beforeParse,
|
|
}
|
|
);
|
|
|
|
dom.window.resolver = () => {
|
|
resolve(dom);
|
|
};
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
}
|
|
|
|
_renderContent()
|
|
{
|
|
// Create content list
|
|
const content = [this.headStart];
|
|
|
|
// Embed CSS
|
|
this.css.forEach((css) => {
|
|
content.push(`<link rel="stylesheet" href="${css.url}" id="${css.id}">`);
|
|
});
|
|
|
|
content.push(this.headEnd, this.bodyStart, this.content);
|
|
|
|
// Embed scripts
|
|
this.scripts.forEach((script) => {
|
|
content.push(`<script src="${script.url}" id="${script.id}"></script>`);
|
|
});
|
|
this.inline.forEach((script) => {
|
|
content.push(`<script id="${script.id}">${script.script}</script>`);
|
|
});
|
|
|
|
// Add resolver
|
|
content.push(`<script>window.resolver()</script>`);
|
|
|
|
// Add final content
|
|
content.push(this.bodyEnd);
|
|
content.push(this.foot);
|
|
|
|
return content.join('\n');
|
|
}
|
|
}
|