five-server
Version:
Development Server with Live Reload Capability. (Maintained Fork of Live Server)
133 lines • 5.69 kB
JavaScript
;
/**
* @author Yannick Deubel (https://github.com/yandeu)
* @copyright Copyright (c) 2021 Yannick Deubel
* @license {@link https://github.com/yandeu/five-server/blob/main/LICENSE LICENSE}
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeTmpDirectory = exports.createTmpDirectory = exports.injectHighlight = void 0;
// https://html-validate.org/dev/using-api.html
const path_1 = require("path");
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const execPHP_1 = require("../utils/execPHP");
const html_validate_1 = require("html-validate");
const worker_threads_1 = require("worker_threads");
const node_html_parser_1 = require("node-html-parser");
const PHP = new execPHP_1.ExecPHP();
const htmlvalidate = new html_validate_1.HtmlValidate({
// https://html-validate.org/rules/index.html
rules: {
'close-attr': 'error', // necessary
'close-order': 'error', // necessary
'element-name': [
'error',
{
pattern: '[a-z][a-z0-9\\-._]*-?[a-z0-9\\-._]*$'
}
], // necessary
deprecated: 'error',
'no-dup-attr': 'error',
'no-dup-class': 'error',
'no-dup-id': 'error'
}
});
const injectHighlight = (body, cursorPosition) => {
if (!cursorPosition)
return body;
try {
const lines = body.split('\n');
const line = cursorPosition.line;
const char = cursorPosition.character;
// add five-server-cursor tag where cursor is
const part1 = lines[line].slice(0, char);
const part2 = lines[line].slice(char);
// simple check if cursor is inside a <> block
if (part2.indexOf('<') > part2.indexOf('>') ||
(part2.indexOf('<') === -1 && part2.indexOf('<') < part2.indexOf('>')))
return body;
// eslint-disable-next-line prefer-template
lines[line] = part1 + '<five-server-cursor></five-server-cursor>' + part2;
let new_body = lines.join('\n');
const root = (0, node_html_parser_1.parse)(new_body);
const span = root.querySelector('five-server-cursor');
const parent = span === null || span === void 0 ? void 0 : span.parentNode;
if (!parent)
throw new Error();
// don't highlight if here is an H
if (!parent.hasAttribute('H'))
parent === null || parent === void 0 ? void 0 : parent.setAttribute('data-highlight', 'true');
new_body = root.toString().replace('<five-server-cursor></five-server-cursor>', '');
return new_body;
}
catch {
return body;
}
};
exports.injectHighlight = injectHighlight;
const writeTmpFile = (fileName, text) => {
return new Promise(resolve => {
(0, fs_1.writeFile)(fileName, text, { encoding: 'utf-8' }, () => {
return resolve();
});
});
};
const createTmpDirectory = async (cwd) => {
const tmpDir = (0, path_1.join)(cwd, '.php_tmp');
if (!(0, fs_1.existsSync)(tmpDir))
await (0, promises_1.mkdir)(tmpDir);
return tmpDir;
};
exports.createTmpDirectory = createTmpDirectory;
const removeTmpDirectory = async (cwd) => {
if (cwd) {
const tmpDir = (0, path_1.join)(cwd, '.php_tmp');
if ((0, fs_1.existsSync)(tmpDir))
await (0, promises_1.rm)(tmpDir, { recursive: true, force: true });
}
};
exports.removeTmpDirectory = removeTmpDirectory;
// let start
// const reset_time = () => {
// start = process.hrtime()
// }
// const elapsed_time = (note = '') => {
// const precision = 3 // 3 decimal places
// const elapsed = process.hrtime(start)[1] / 1000000 // divide by a million to get nano to milliseconds
// // eslint-disable-next-line prefer-template
// return process.hrtime(start)[0] + ' s, ' + elapsed.toFixed(precision) + ' ms - ' + note // print message + time
// }
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.on('message', async (data) => {
// reset_time()
const { text, shouldHighlight, cursorPosition, fileName, init, close } = JSON.parse(data);
if (init) {
PHP.path = init.phpExecPath;
PHP.ini = init.phpIniPath;
PHP.cwd = init.cwd;
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage(JSON.stringify({ ignore: true }));
return;
}
const isPhp = /\.php$/.test(fileName);
let tmpDir = '', tmpFile = '';
if (isPhp) {
tmpDir = await (0, exports.createTmpDirectory)(PHP.cwd);
tmpFile = (0, path_1.join)(tmpDir, (0, path_1.basename)(fileName));
await writeTmpFile(tmpFile, text);
}
const php = isPhp ? await PHP.parseFile(tmpFile, { status: () => { } }) : text;
const html = shouldHighlight ? (0, exports.injectHighlight)(php, cursorPosition) : php;
const res = /(<body[^>]*>)((.|[\n\r])*)(<\/body>)/gim.exec(html);
if (!res) {
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage(JSON.stringify({ ignore: true }));
}
else {
const b = res[2]
.split('\n')
// .map((l) => l.trim())
.join('');
const body = `${res[1]}${b}${res[4]}`;
const report = htmlvalidate.validateString(php);
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage(JSON.stringify({ report, body, fileName /*, time: elapsed_time()*/ }));
}
});
//# sourceMappingURL=parseBody.js.map