mirror of
https://gitlab.com/SpaccInc/SpaccDotWeb.git
synced 2025-06-05 21:29:12 +02:00
[Alt] Fix errors, add element creation to $(); [Build] Updates and example
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
. ./BuildLib.sh
|
||||
|
||||
buildHtml(){
|
||||
useBuilder "Build.BuildHtmlFile('$1', { outputFile: '$2' })"
|
||||
useBuilder "BuildHtmlFile('$1', { outputFile: '$2' })"
|
||||
}
|
||||
|
||||
for example in Server
|
||||
|
@ -5,7 +5,7 @@ useBuilder(){
|
||||
}
|
||||
|
||||
buildScript(){
|
||||
useBuilder "Build.BuildScriptFile('$1')"
|
||||
useBuilder "BuildScriptFile('$1')"
|
||||
}
|
||||
|
||||
for file in ./SpaccDotWeb.js ./SpaccDotWeb.*.js
|
||||
|
@ -92,23 +92,27 @@
|
||||
SpaccDotWeb.sleep = (ms) => (new Promise((resolve) => setTimeout(resolve, ms)));
|
||||
SpaccDotWeb.Sleep = SpaccDotWeb.sleep;
|
||||
|
||||
SpaccDotWeb.$ = (query) => {
|
||||
SpaccDotWeb.$ = (query, extra) => ((query.startsWith('<') && query.endsWith('>'))
|
||||
? Object.assign(Object.assign(document.createElement('div'), { innerHTML: query }).querySelector('*'), extra)
|
||||
: SpaccDotWeb.query(query));
|
||||
|
||||
SpaccDotWeb.query = (query) => {
|
||||
query = query.trim();
|
||||
return (query.startsWith('::')
|
||||
? arrayFrom(document.querySelectorAll(domSpecialQuery(query.slice(2).trim())))
|
||||
? Array.from(document.querySelectorAll(domSpecialQuery(query.slice(2).trim())))
|
||||
: document.querySelector(domSpecialQuery(query))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
function domSpecialQuery (query) {
|
||||
const chars = [];
|
||||
let buffer = [];
|
||||
let brackets = 0;
|
||||
for (const char of query) {
|
||||
for (const char of `${query} `) {
|
||||
if (brackets === 0) {
|
||||
if (buffer.length > 0) {
|
||||
buffer = buffer.join('');
|
||||
if (!buffer.includes('=')) {
|
||||
if (!buffer.includes('=') && (buffer.includes('"') || buffer.includes("'"))) {
|
||||
buffer = `name=${buffer}`;
|
||||
}
|
||||
chars.push(buffer);
|
||||
|
@ -31,32 +31,31 @@ alerter("It's a nice day today, innit?");
|
||||
</fieldset>
|
||||
|
||||
<script>
|
||||
const BuildScript = window.SpaccDotWeb.Build.BuildScript;
|
||||
const Build = window.SpaccDotWeb.Build;
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const createElement = (tag, attrs) => Object.assign(document.createElement(tag), attrs);
|
||||
|
||||
// Get the sample script
|
||||
const scriptText = $('script').textContent = $('script').textContent.trimEnd();
|
||||
|
||||
// Actually build the script
|
||||
const builtScript = BuildScript(scriptText);
|
||||
const builtScript = Build.BuildScript(scriptText);
|
||||
|
||||
// Show the build result
|
||||
$('compiled').textContent = builtScript.compiled;
|
||||
$('minified').textContent = builtScript.minified;
|
||||
|
||||
// Execute the compiled result
|
||||
//setTimeout('eval(builtScript.compiled);', 100);
|
||||
|
||||
setTimeout(function(){
|
||||
Array.from(document.querySelectorAll('script')).filter(el => !el.dataset.spaccdotweb).forEach(scriptElement => {
|
||||
scriptElement.textContent = BuildScript(scriptElement.textContent).minified;
|
||||
Build.BuildHtml(document.documentElement.outerHTML, {}).then(html => {
|
||||
$('html').textContent = html;
|
||||
document.querySelector('fieldset.html > span').innerHTML += `, ${html.length}b`;
|
||||
});
|
||||
$('html').textContent = `<!DOCTYPE html>\n${document.documentElement.outerHTML}`;
|
||||
}, 100);
|
||||
}, 1);
|
||||
|
||||
document.querySelectorAll('fieldset.script').forEach(fieldset => {
|
||||
const script = fieldset.querySelector('textarea').textContent;
|
||||
fieldset.querySelector('span').innerHTML += `, ${script.length}b`;
|
||||
fieldset.appendChild(Object.assign(document.createElement('button'), {
|
||||
fieldset.appendChild(createElement('button', {
|
||||
innerHTML: "Execute",
|
||||
onclick: () => eval(script),
|
||||
}));
|
||||
|
@ -34,35 +34,49 @@ const babelConfig = {
|
||||
],
|
||||
};
|
||||
|
||||
const findPath = (path, folder) => {
|
||||
for (const prefix of [folder, __dirname]) {
|
||||
path = Lib.path.join(prefix, path);
|
||||
if (Lib.fs.existsSync(path)) {
|
||||
const findPath = (path, folder, files) => {
|
||||
for (const prefix of [folder, (typeof __dirname !== 'undefined' ? __dirname : '')]) {
|
||||
path = (Lib.path?.join(prefix, path) || `${prefix}/${path}`);
|
||||
if ((files && (path in files)) || (!files && Lib.fs?.existsSync(path))) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const readFile = (path, folder, files) => {
|
||||
path = (findPath(path, folder, files) || path);
|
||||
return (files ? files[path] : Lib.fs?.readFileSync(path, 'utf8'));
|
||||
}
|
||||
|
||||
const fileToBase64 = (path, content) => `data:${Lib.mime.lookup(path)};base64,${content || Lib.fs.readFileSync(findPath(path)).toString('base64')}`;
|
||||
const fileToBase64 = (path, content) => `data:${Lib.mime.lookup(path)};base64,${content || Lib.fs?.readFileSync(findPath(path))?.toString('base64')}`;
|
||||
|
||||
const isUrlAbsolute = (url) => (url && ['http:', 'https:', ''].includes(url.split('/')[0]));
|
||||
|
||||
const BuildScript = (scriptText, options) => {
|
||||
options = {
|
||||
minify: true,
|
||||
...options };
|
||||
options ||= {};
|
||||
options.minify ??= true;
|
||||
const compiled = (Lib.babel.transformSync || Lib.babel.transform)(scriptText, babelConfig).code;
|
||||
const minified = (options.minify && Lib.uglify.minify(compiled).code);
|
||||
return { compiled, minified };
|
||||
}
|
||||
};
|
||||
|
||||
const BuildHtml = async (html, options) => {
|
||||
options = {
|
||||
compileScripts: true,
|
||||
minifyScripts: true,
|
||||
compileStyles: true,
|
||||
inputFolder: '.',
|
||||
...options };
|
||||
const BuildStyle = async (styleText, stylePath, options) => {
|
||||
options ||= {};
|
||||
options.minify ??= true;
|
||||
const plugins = [
|
||||
Lib.postcssImport(),
|
||||
Lib.postcssUrl({ url: 'inline' }),
|
||||
...(options.minify ? [Lib.postcssMinify()] : []),
|
||||
];
|
||||
return (await Lib.postcss(plugins).process(styleText, { from: stylePath })).css;
|
||||
};
|
||||
|
||||
const BuildHtml = async (html, options, files) => {
|
||||
options ||= {};
|
||||
options.compileScripts ??= true;
|
||||
options.minifyScripts ??= true;
|
||||
options.compileStyles ??= true;
|
||||
options.inputFolder ??= '.';
|
||||
const dom = makeHtmlDom(html);
|
||||
for (const element of dom.querySelectorAll('script, [src], link[rel=stylesheet][href]')) {
|
||||
if (isUrlAbsolute(element.src || element.href)) {
|
||||
@ -72,21 +86,20 @@ const BuildHtml = async (html, options) => {
|
||||
const scriptOptions = JSON.parse(element.dataset.spaccdotweb || '{}');
|
||||
const minifyScripts = (scriptOptions.minify ?? options.minifyScripts);
|
||||
let scriptText = (element.src
|
||||
? Lib.fs.readFileSync(findPath(element.src, options.inputFolder), 'utf8')
|
||||
? readFile(element.src, options.inputFolder, files) //Lib.fs.readFileSync(findPath(element.src, options.inputFolder), 'utf8')
|
||||
: element.textContent);
|
||||
if (scriptOptions.compile ?? options.compileScripts) {
|
||||
scriptText = BuildScript(scriptText, { minify: minifyScripts })[minifyScripts ? 'minified' : 'compiled'];
|
||||
}
|
||||
if (scriptText) {
|
||||
element.removeAttribute('src');
|
||||
element.textContent = scriptText;
|
||||
}
|
||||
} else if (element.tagName === 'LINK') {
|
||||
const stylePath = findPath(element.href, options.inputFolder);
|
||||
let styleText = Lib.fs.readFileSync(stylePath, 'utf8');
|
||||
if (options.compileStyles) {
|
||||
styleText = (await Lib.postcss([
|
||||
Lib.postcssImport(),
|
||||
Lib.postcssUrl({ url: 'inline' }),
|
||||
]).process(styleText, { from: stylePath })).css;
|
||||
let styleText = readFile(stylePath, options.inputFolder, files); //Lib.fs.readFileSync(stylePath, 'utf8');
|
||||
if (options.compileStyles && !envIsBrowser) {
|
||||
styleText = await BuildStyle(styleText, stylePath, { minify: options.minifyStyles });
|
||||
}
|
||||
element.parentElement.insertBefore(Object.assign(dom.createElement('style'), { textContent: styleText }), element);
|
||||
element.remove();
|
||||
@ -95,7 +108,7 @@ const BuildHtml = async (html, options) => {
|
||||
}
|
||||
}
|
||||
return `<!DOCTYPE html>\n${dom.documentElement.outerHTML}`;
|
||||
}
|
||||
};
|
||||
|
||||
return { BuildScript, BuildHtml, fileToBase64 };
|
||||
|
||||
|
@ -7,6 +7,7 @@ const Lib = {
|
||||
babel: require('@babel/core'),
|
||||
uglify: require('uglify-js'),
|
||||
postcss: require('postcss'),
|
||||
postcssMinify: require('postcss-minify'),
|
||||
postcssImport: require('postcss-import'),
|
||||
postcssUrl: require('postcss-url'),
|
||||
jsdom: require('jsdom').JSDOM,
|
||||
@ -41,11 +42,10 @@ const BuildScriptFile = (scriptFile, options) => {
|
||||
};
|
||||
|
||||
const BuildHtmlFile = (htmlFile, options) => {
|
||||
options = {
|
||||
outputFolder: './Build',
|
||||
outputFile: htmlFile,
|
||||
inputFolder: Lib.path.dirname(htmlFile),
|
||||
...options };
|
||||
options ||= {};
|
||||
options.outputFile ??= htmlFile;
|
||||
options.inputFolder ??= Lib.path.dirname(htmlFile);
|
||||
options.outputFolder ??= './Build';
|
||||
const outputPath = `${options.outputFolder}/${options.outputFile}`;
|
||||
Build.BuildHtml(Lib.fs.readFileSync(htmlFile, 'utf8'), options).then(html => Lib.fs.writeFileSync(outputPath, html));
|
||||
return outputPath;
|
||||
@ -60,5 +60,5 @@ const EncodeStaticFiles = (files, /* encoding='base64' */) => {
|
||||
module.exports = Build = { ...Build, BuildScriptFile, BuildHtmlFile, EncodeStaticFiles };
|
||||
|
||||
if (require.main === module) {
|
||||
console.log(eval(process.argv.slice(-1)[0]));
|
||||
console.log(eval('Build.'+process.argv.slice(-1)[0]));
|
||||
}
|
||||
|
1444
package-lock.json
generated
1444
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -17,13 +17,24 @@
|
||||
"jsdom": "^22.1.0",
|
||||
"postcss": "^8.5.3",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-minify": "^1.1.0",
|
||||
"postcss-url": "^10.1.3",
|
||||
"uglify-js": "^3.17.4",
|
||||
"uglifyjs-browser": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-browserify": "^3.12.1",
|
||||
"events": "^3.3.0",
|
||||
"fs-web": "^1.0.1",
|
||||
"mime-types": "^2.1.35",
|
||||
"mime-types-browser": "^0.0.3",
|
||||
"parse-multipart-data": "^1.5.0"
|
||||
"os-browserify": "^0.3.0",
|
||||
"parse-multipart-data": "^1.5.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"url": "^0.11.4",
|
||||
"util": "^0.12.5"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user