Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4192d16b7a | ||
|
|
12abd35cfa | ||
|
|
073ed52932 | ||
|
|
8f2605be9d | ||
|
|
9e7860542b | ||
|
|
f48b2a3274 | ||
|
|
b76f83d4fa | ||
|
|
977ec0003c | ||
|
|
0e91c42e89 | ||
|
|
0a4fd3608f | ||
|
|
11152dda87 | ||
|
|
246c9ddd35 | ||
|
|
164ef7433a | ||
|
|
a6decb9cfb | ||
|
|
9c85a89a8f | ||
|
|
58ed3de9dc | ||
|
|
3de4a4abb6 | ||
|
|
256450226b | ||
|
|
51db3da072 | ||
|
|
05c5697bc2 | ||
|
|
01e4160040 | ||
|
|
81f5166043 | ||
|
|
a1929fe33c | ||
|
|
840c002834 | ||
|
|
f4474fb7e4 | ||
|
|
8ca6cb0365 | ||
|
|
e2553358be | ||
|
|
34dbff5701 | ||
|
|
c408f2f5b3 |
No files matched your search
+19
@@ -0,0 +1,19 @@
|
|||||||
|
FROM node:19.4.0-slim as node
|
||||||
|
|
||||||
|
WORKDIR /app/
|
||||||
|
|
||||||
|
COPY ./package.json .
|
||||||
|
COPY ./package-lock.json .
|
||||||
|
COPY ./inc ./inc
|
||||||
|
COPY ./layouts ./layouts
|
||||||
|
COPY ./platforms ./platforms
|
||||||
|
COPY ./routes ./routes
|
||||||
|
COPY ./env.js .
|
||||||
|
COPY ./helpers.js .
|
||||||
|
COPY ./rollup.config.js .
|
||||||
|
COPY ./server.js .
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
EXPOSE 3010
|
||||||
|
CMD npm run view-mode
|
||||||
+239
-9
@@ -9,6 +9,12 @@ import archiver from "archiver";
|
|||||||
import {buildWordPress} from "./platforms/wordpress/wordpress-adapter.js";
|
import {buildWordPress} from "./platforms/wordpress/wordpress-adapter.js";
|
||||||
import {buildHubspotEmail} from "./platforms/hubspot/hubspot-email-adapter.js";
|
import {buildHubspotEmail} from "./platforms/hubspot/hubspot-email-adapter.js";
|
||||||
import {buildHubspotPage} from "./platforms/hubspot/hubspot-page-adapter.js";
|
import {buildHubspotPage} from "./platforms/hubspot/hubspot-page-adapter.js";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import {constants} from "fs";
|
||||||
|
import fetch from "node-fetch";
|
||||||
|
import mime from "mime-types";
|
||||||
|
import {exec} from "child_process";
|
||||||
|
import {REGISTRY_URL} from "@axe-web/create-block/env.js";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -26,6 +32,7 @@ export async function readJSONFile(jsonFile) {
|
|||||||
let data = {};
|
let data = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await fs.access(jsonFile, constants.F_OK | constants.R_OK);
|
||||||
data = await fsExtra.readJson(jsonFile);
|
data = await fsExtra.readJson(jsonFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
@@ -44,33 +51,46 @@ function getErrorHtml(message = '', errorMessage = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getBlockData(jsonFileName = 'default', {projectPath} = {jsonFileName: 'default'}) {
|
export async function getBlockData(jsonFileName = 'default', {projectPath} = {jsonFileName: 'default'}) {
|
||||||
let data = await readJSONFile(path.join(projectPath, 'data', `${jsonFileName}.json`));
|
const filePath = path.join(projectPath, 'data', `${jsonFileName}.json`);
|
||||||
|
const data = await readJSONFile(filePath);
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
return data;
|
console.log(filePath, data.errorMessage.replace(/<[^>]*>?/gm, ''));
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBlockConfigs(args = {modulesPath: '', dataFiles: []}) {
|
export async function getBlockConfigs(args) {
|
||||||
return Object.assign(JSON.parse(JSON.stringify(config)), // The entire config object.
|
const config = await readJSONFile(path.join('blocks', '@' + args.project, args.name, 'config', 'default.json'));
|
||||||
|
|
||||||
|
const updatedConfig = Object.assign({}, config, // The entire config object.
|
||||||
{
|
{
|
||||||
projectDir: args.modulesPath, dataFiles: args.dataFiles.map((name) => {
|
projectDir: '', dataFiles: args.dataFiles.map((name) => {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
};
|
};
|
||||||
}), remToPx: config.has('remToPx') ? config.get('remToPx') : 16,
|
}), remToPx: 16,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Avoid cache conflict on Global Project css/js files.
|
||||||
|
if (updatedConfig.project) {
|
||||||
|
updatedConfig.project.css = updatedConfig.project.css ? updatedConfig.project.css + '?cache=' + Date.now() : undefined;
|
||||||
|
updatedConfig.project.js = updatedConfig.project.js ? updatedConfig.project.js + '?cache=' + Date.now() : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBlockName(name = '') {
|
export function getBlockName(name = '') {
|
||||||
if (name.startsWith('@')) {
|
// Remove all @ from the beginning of the string.
|
||||||
name = name.substring(1);
|
name = name.replace(/^@/, '');
|
||||||
}
|
|
||||||
|
|
||||||
const arr = name.split('/');
|
const arr = name.split('/');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
blockName: `@${arr[0]}/${arr[1]}`,
|
||||||
project: arr[0],
|
project: arr[0],
|
||||||
name: arr[1],
|
name: arr[1],
|
||||||
};
|
};
|
||||||
@@ -160,3 +180,213 @@ export async function buildExportFiles(blockName, platform) {
|
|||||||
await buildHubspotPage(blockName)
|
await buildHubspotPage(blockName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeCommentsFromCss(content) {
|
||||||
|
return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeCommentsFromJs(content) {
|
||||||
|
return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function uploadFile(filePath, uploadUrl, validator) {
|
||||||
|
const options = {};
|
||||||
|
|
||||||
|
const contentType = mime.lookup(filePath);
|
||||||
|
if (['text/css', 'application/javascript'].includes(contentType)) {
|
||||||
|
options.encoding = 'utf8';
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = await fs.readFile(filePath, options);
|
||||||
|
|
||||||
|
if (validator) {
|
||||||
|
body = validator(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(uploadUrl, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: body,
|
||||||
|
headers: {'Content-Type': contentType}
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.status !== 200;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
const fileName = filePath.split('/').pop();
|
||||||
|
throw new Error(`Can't upload "${fileName}" file. Server permission error.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getImagesList(rootFolder, subFolder = '') {
|
||||||
|
const imagesPath = path.join(rootFolder, subFolder);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.access(imagesPath);
|
||||||
|
} catch (err) {
|
||||||
|
// Folder doesn't exist.
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const images = await fs.readdir(imagesPath);
|
||||||
|
const imagesList = [];
|
||||||
|
|
||||||
|
for (const image of images) {
|
||||||
|
const stats = await fs.stat(path.join(imagesPath, image));
|
||||||
|
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
const subImages = await getImagesList(rootFolder, image);
|
||||||
|
imagesList.push(...subImages);
|
||||||
|
} else {
|
||||||
|
imagesList.push(path.join(subFolder, image));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return imagesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function isFileEmpty(filePath, ignoreComments = false) {
|
||||||
|
const fileContent = await fs.readFile(filePath, 'utf8');
|
||||||
|
const lines = fileContent.split('\n');
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (ignoreComments && line.trim().startsWith('//')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.trim().length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function replaceNames(content, images, uploadedImages) {
|
||||||
|
images.forEach((image, index) => {
|
||||||
|
content = content.replace(image, uploadedImages[index].fileName);
|
||||||
|
});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBlockFromCloud(blockName, blocksRegistry) {
|
||||||
|
const queryString = new URLSearchParams();
|
||||||
|
queryString.append('blockName', blockName);
|
||||||
|
queryString.append('includeDevConfig', 'true');
|
||||||
|
|
||||||
|
const response = await fetch(`${blocksRegistry}?${queryString.toString()}`);
|
||||||
|
const responseData = await response.json();
|
||||||
|
if (!responseData || !responseData.name) {
|
||||||
|
const message = `⚠️ Block not found, please contact administrator. [${blockName}]`
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseData.statusCode && responseData.statusCode !== 200) {
|
||||||
|
const message = ["⚠️ [ERROR]", responseData.message || "Server side error."].join(' ');
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifyVersion(blockName, projectPath, blocksRegistry) {
|
||||||
|
const block = await getBlockFromCloud(blockName, blocksRegistry);
|
||||||
|
if (!block) {
|
||||||
|
throw new Error(`Block not found. [${blockName}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const blockJson = await readJSONFile(path.join(projectPath, `block.json`));
|
||||||
|
if (blockJson.error) {
|
||||||
|
return false; // Block doesn't exist locally.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This block is managed on cloud.
|
||||||
|
* Let's detect the latest version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return block.version === blockJson.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function syncFilesWithCloud(blockName, bs, sourceFiles = false) {
|
||||||
|
const block = await getBlockFromCloud(blockName, REGISTRY_URL);
|
||||||
|
|
||||||
|
let fileExists = false;
|
||||||
|
try {
|
||||||
|
await readJSONFile(path.join('blocks', '@' + block.project, block.name, 'block.json'));
|
||||||
|
fileExists = true;
|
||||||
|
} catch (e) {
|
||||||
|
// Dir doesn't exist.
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Pause watcher of the block?
|
||||||
|
blockName = `@${block.project}/${block.name}`;
|
||||||
|
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
const createBlockModulePath = `./node_modules/@axe-web/create-block`;
|
||||||
|
const action = sourceFiles ? fileExists ? 'sync --source' : 'pull' : 'sync';
|
||||||
|
|
||||||
|
exec(`BLOCK_NAME=${blockName} node ${createBlockModulePath}/create-block.js ${action}`, (err, stdout, stderr) => {
|
||||||
|
if (err || stderr) {
|
||||||
|
const message = err || stderr;
|
||||||
|
console.error('Error:', message);
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(stdout);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Release watcher of the block?
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBlockVariations(projectPath) {
|
||||||
|
const dataFiles = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.access(path.join(projectPath, 'data'));
|
||||||
|
|
||||||
|
const files = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data')));
|
||||||
|
dataFiles.push(...files);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Warning: data folder not found.', projectPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareListOfDataFiles(dataFiles) {
|
||||||
|
return dataFiles
|
||||||
|
.filter((fileName) => fileName.split('.').pop() === 'json')
|
||||||
|
.map((fileName) => {
|
||||||
|
const splitName = fileName.split('.');
|
||||||
|
splitName.pop();
|
||||||
|
return splitName.join('');
|
||||||
|
})
|
||||||
|
.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handlebarLayoutsPath() {
|
||||||
|
return path.join(...arguments)
|
||||||
|
.replace(/\\/g, '/'); // Windows path issue. Fix all "\" for Handlebars.
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getListOfDesignPreviewFiles(jsonDataFileName, previewFiles, block) {
|
||||||
|
return previewFiles
|
||||||
|
.filter(fileName => {
|
||||||
|
return fileName.startsWith(jsonDataFileName + '.');
|
||||||
|
})
|
||||||
|
.map(fileName => {
|
||||||
|
const fileData = fileName.split('.');
|
||||||
|
const fileFormat = fileData.pop();
|
||||||
|
const previewSize = fileData.pop();
|
||||||
|
|
||||||
|
return {
|
||||||
|
dataSource: jsonDataFileName,
|
||||||
|
widthDimension: Number.parseInt(previewSize, 10),
|
||||||
|
url: `/design/${block.project}/${block.name}/preview/${fileName}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import gulp from "gulp";
|
||||||
|
import path from "path";
|
||||||
|
import sourcemaps from "gulp-sourcemaps";
|
||||||
|
import babel from "gulp-babel";
|
||||||
|
import PluginError from "plugin-error";
|
||||||
|
import rename from "gulp-rename";
|
||||||
|
import uglify from "gulp-uglify";
|
||||||
|
import dartSass from 'sass';
|
||||||
|
import gulpSass from "gulp-sass";
|
||||||
|
import {getBlockName} from "../helpers.js";
|
||||||
|
|
||||||
|
const sass = gulpSass(dartSass);
|
||||||
|
|
||||||
|
export function setupWatcher(viewSync) {
|
||||||
|
|
||||||
|
const watchSCSS = gulp.watch(['blocks/**/*.scss'], {delay: 400});
|
||||||
|
watchSCSS.on('change', async function (filepath, stats) {
|
||||||
|
const pathArray = filepath.split('/', 3);
|
||||||
|
pathArray.shift();
|
||||||
|
const block = getBlockName(pathArray.join('/'));
|
||||||
|
|
||||||
|
buildStyleFiles(path.join('blocks', '@' + block.project, block.name), () => {
|
||||||
|
viewSync.syncTemplate(block.blockName, 'styleUpdate');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const watchJS = gulp.watch(['blocks/**/*.js', '!blocks/**/*.min.js'], {delay: 400});
|
||||||
|
watchJS.on('change', async function (filepath) {
|
||||||
|
const pathArray = filepath.split('/', 3);
|
||||||
|
pathArray.shift();
|
||||||
|
const block = getBlockName(pathArray.join('/'));
|
||||||
|
|
||||||
|
buildScriptFiles(path.join('blocks', '@' + block.project, block.name), () => {
|
||||||
|
viewSync.syncTemplate(block.blockName, 'scriptUpdate');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const watchHBS = gulp.watch(['blocks/**/*.hbs'], {delay: 400});
|
||||||
|
watchHBS.on('change', async function (filepath) {
|
||||||
|
const pathArray = filepath.split('/', 3);
|
||||||
|
pathArray.shift();
|
||||||
|
const block = getBlockName(pathArray.join('/'));
|
||||||
|
|
||||||
|
await viewSync.syncTemplate(block.blockName);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildAssetFiles(projectPath) {
|
||||||
|
// Register tasks.
|
||||||
|
gulp.task('build-script-files', (done) => buildScriptFiles(projectPath, done));
|
||||||
|
gulp.task('build-styling-files', (done) => buildStyleFiles(projectPath, done));
|
||||||
|
|
||||||
|
// Run first build.
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
gulp.series('build-script-files', 'build-styling-files', function () {
|
||||||
|
resolve();
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(errorMessage) {
|
||||||
|
console.log(errorMessage);
|
||||||
|
|
||||||
|
// TODO: Send this message to browser.
|
||||||
|
// So the developer can understand there is an error.
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildScriptFiles(projectPath = '', done) {
|
||||||
|
const files = getJSBundleFiles(projectPath);
|
||||||
|
const stream = gulp.src(files, {base: path.posix.join(projectPath, 'src')})
|
||||||
|
.pipe(sourcemaps.init({}))
|
||||||
|
.pipe(babel()).on('error', function (error) {
|
||||||
|
showError(new PluginError('JavaScript', error).toString());
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.pipe(gulp.src(path.join(projectPath, 'vendor/*.js')))
|
||||||
|
// .pipe(gulp.dest('src/'))
|
||||||
|
.pipe(rename({extname: '.min.js'}))
|
||||||
|
.pipe(uglify())
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(gulp.dest(path.posix.join(projectPath, 'src')));
|
||||||
|
|
||||||
|
stream.on('end', done);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJSBundleFiles(projectPath = '') {
|
||||||
|
return [path.posix.join(projectPath, "src/**/*.js"), path.posix.join(projectPath, "src/**/*.mjs"), "!" + path.posix.join(projectPath, "src/**/*.min.js")];
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildStyleFiles(projectPath = '', done) {
|
||||||
|
const stream = gulp.src(path.join(projectPath, 'src/**/*.scss'), {base: path.posix.join(projectPath, 'src')})
|
||||||
|
.pipe(sourcemaps.init({}))
|
||||||
|
.pipe(sass.sync({outputStyle: 'compressed'}).on('error', function (error) {
|
||||||
|
showError(new PluginError('SCSS', error.messageFormatted).toString());
|
||||||
|
// sass.logError(error);
|
||||||
|
done();
|
||||||
|
}))
|
||||||
|
// .pipe(gulp.dest('src/'))
|
||||||
|
.pipe(rename({extname: '.min.css'}))
|
||||||
|
.pipe(sourcemaps.write('.', {}))
|
||||||
|
.pipe(gulp.dest(path.posix.join(projectPath, 'src')));
|
||||||
|
|
||||||
|
stream.on('end', done);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export function setHeaders(req, res, next) {
|
||||||
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
next();
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import express from "express";
|
||||||
|
import bodyParser from "body-parser";
|
||||||
|
import {createServer} from "http";
|
||||||
|
import {create} from "express-handlebars";
|
||||||
|
import {escape} from "lodash-es";
|
||||||
|
import {sanitizeUrl} from "@braintree/sanitize-url";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export function init() {
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
// parse application/x-www-form-urlencoded
|
||||||
|
app.use(bodyParser.urlencoded({extended: false}));
|
||||||
|
|
||||||
|
// parse application/json
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
|
const hbs = getHandlebarsViewEngine();
|
||||||
|
|
||||||
|
app.engine('.hbs', hbs.engine);
|
||||||
|
app.set('view engine', '.hbs');
|
||||||
|
|
||||||
|
const modulesPath = '.';
|
||||||
|
app.set('views', path.join(modulesPath, 'layouts'));
|
||||||
|
|
||||||
|
// Static Files of blockDevTool.
|
||||||
|
app.use(express.static(path.join(modulesPath, 'layouts')));
|
||||||
|
|
||||||
|
return {
|
||||||
|
expressApp: app,
|
||||||
|
httpServer: createServer(app),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHandlebarsViewEngine() {
|
||||||
|
return create({
|
||||||
|
extname: '.hbs', defaultLayout: false, partialsDir: ['.'], helpers: handlebarsHelpers()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlebarsHelpers() {
|
||||||
|
return {
|
||||||
|
esc_attr(attr) {
|
||||||
|
return escape(attr);
|
||||||
|
},
|
||||||
|
esc_url(url) {
|
||||||
|
return sanitizeUrl(url);
|
||||||
|
},
|
||||||
|
esc_html(html) {
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import {Server} from "socket.io";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import {getBlockName, handlebarLayoutsPath} from "../helpers.js";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export class ViewSync {
|
||||||
|
constructor(httpServer) {
|
||||||
|
this.sessions = {};
|
||||||
|
this.init(httpServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
addSession(session, blockName) {
|
||||||
|
if (!this.sessions[blockName]) {
|
||||||
|
this.sessions[blockName] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sessions[blockName].push(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
init(httpServer) {
|
||||||
|
const io = new Server(httpServer);
|
||||||
|
io.on('connection', async (socket) => {
|
||||||
|
const blockName = socket.handshake.query.block;
|
||||||
|
|
||||||
|
if (!blockName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addSession(socket, blockName);
|
||||||
|
await this.syncTemplate(blockName);
|
||||||
|
});
|
||||||
|
|
||||||
|
// return httpServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
async syncTemplate(blockName, updateType = 'templateUpdate') {
|
||||||
|
const block = getBlockName(blockName);
|
||||||
|
|
||||||
|
const projectPath = path.join('blocks', '@' + block.project, block.name);
|
||||||
|
const hbsTemplate = await fs.readFile(handlebarLayoutsPath(projectPath, 'src', `${block.name}.template.hbs`), 'utf8');
|
||||||
|
|
||||||
|
if (!this.sessions[blockName]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sessions[blockName].forEach(session => {
|
||||||
|
session.emit(updateType, {block: blockName, template: hbsTemplate});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
{{> (include_partial "layouts/partials/head") }}
|
{{> (include_partial "layouts/partials/head") }}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
{{> (include_partial "layouts/partials/head") }}
|
{{> (include_partial "layouts/partials/head") }}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
{{> (include_partial "layouts/partials/head") }}
|
{{> (include_partial "layouts/partials/head") }}
|
||||||
|
|||||||
+4
-2
@@ -1,3 +1,4 @@
|
|||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
@@ -7,12 +8,13 @@
|
|||||||
<title>Block Development Tool</title>
|
<title>Block Development Tool</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="{{#if viewMode }}view-mode{{/if}}">
|
||||||
|
|
||||||
{{> (include_partial "layouts/partials/toolbar") }}
|
{{> (include_partial "layouts/partials/toolbar") }}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.devTool = {
|
window.devTool = {
|
||||||
|
blockName: '{{ blockName }}',
|
||||||
previewFrameUrl: '{{ previewFrameUrl }}',
|
previewFrameUrl: '{{ previewFrameUrl }}',
|
||||||
{{#if publicUrl}}
|
{{#if publicUrl}}
|
||||||
publicUrl: true,
|
publicUrl: true,
|
||||||
@@ -21,7 +23,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="preview">
|
<div class="preview">
|
||||||
<iframe id="preview_frame" src="{{ previewFrameUrl }}?iframe=true" class="breakpoint"></iframe>
|
<iframe id="preview_frame" src="{{ previewFrameUrl }}?iframe=true&block={{blockName}}" class="breakpoint"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/scripts/dist/index.min.js"></script>
|
<script src="/scripts/dist/index.min.js"></script>
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/[email protected]/swiper-bundle.min.css"/>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/swiper-bundle.min.css"/>
|
||||||
|
{{#if config.project.css }} <link rel="stylesheet" href="{{ config.project.css }}">
|
||||||
|
{{/if}}
|
||||||
{{#if config.cssUrl }}
|
{{#if config.cssUrl }}
|
||||||
{{#each config.cssUrl }}
|
{{#each config.cssUrl }}
|
||||||
<link rel="stylesheet" href="{{ this }}">
|
<link rel="stylesheet" href="{{ this }}">
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}<link rel="stylesheet" href="/styles/page--view.css">{{# if config.blockName}}
|
{{/if}}<link rel="stylesheet" href="/styles/page--view.css">{{# if config.blockName}}
|
||||||
<link rel="stylesheet" href="/styles/{{ config.blockName }}.min.css">{{/if}}
|
<link rel="stylesheet" id="block-stylesheet" href="{{staticFilesPath}}/styles/{{ config.blockName }}.min.css?v=1">{{/if}}
|
||||||
</head>
|
</head>
|
||||||
@@ -2,10 +2,13 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
|
||||||
<script src="/scripts/dist/frame-index.min.js"></script>
|
<script src="/scripts/dist/frame-index.min.js"></script>
|
||||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||||
<script src="https://unpkg.com/[email protected]/swiper-bundle.min.js"></script>{{#if config.jsUrl }}
|
<script src="https://unpkg.com/[email protected]/swiper-bundle.min.js"></script>
|
||||||
|
{{#if config.project.js }}<script src="{{ config.project.js }}"></script>
|
||||||
|
{{/if}}
|
||||||
|
{{#if config.jsUrl }}
|
||||||
{{#each config.jsUrl }}<script src="{{ this }}"></script>
|
{{#each config.jsUrl }}<script src="{{ this }}"></script>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if config.blockName }}
|
{{#if config.blockName }}
|
||||||
<script src="/scripts/{{ config.blockName }}.min.js"></script>
|
<script id="block-script" src="{{staticFilesPath}}/scripts/{{ config.blockName }}.min.js?v=1"></script>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
<div class="page_toolbar__left"></div>
|
<div class="page_toolbar__left"></div>
|
||||||
|
|
||||||
<div class="page_toolbar__middle">
|
<div class="page_toolbar__middle">
|
||||||
<div>
|
<div style="display: none">
|
||||||
Version: <b>1rem = {{ config.version }}px</b>
|
Version: {{ config.version }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -15,6 +15,6 @@
|
|||||||
{{#if styleGuideUrl}}
|
{{#if styleGuideUrl}}
|
||||||
<a href="{{ styleGuideUrl }}" target="_blank" class="palette" title="Open Style Guide"></a>
|
<a href="{{ styleGuideUrl }}" target="_blank" class="palette" title="Open Style Guide"></a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<a href="{{ previewFrameUrl }}" target="_blank" class="open_in_new_tab" title="Open in New Window"></a>
|
<a href="{{ previewFrameUrl }}?block={{blockName}}" target="_blank" class="open_in_new_tab" title="Open in New Window"></a>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
+1
-167
@@ -1,167 +1 @@
|
|||||||
window.initBlock = initBlock;
|
let e;window.initBlock=function(e="",n="",o){t=function(){document.querySelectorAll(n).forEach((e=>o(e)))},t()};let t,n={};!function(){const o=r().block;function r(){const e=new URLSearchParams(window.location.search),t={};for(const[n,o]of e)t[n]=o;return t}function a(e){const t=document.getElementById(e),n=t.parentNode;let o,r;return"SCRIPT"===t.tagName?(o=document.createElement("script"),o.type="text/javascript",r="src"):"LINK"===t.tagName&&(o=document.createElement("link"),o.rel="stylesheet",r="href"),o.id=e,o[r]=t[r].replace(/(\?v=)[^&]+/,`$1${Date.now()}`),t.remove(),n.append(o),o}function c(r={}){r.template&&(e=r.template),r.data&&(n=r.data),e&&function(e,n,r){const a=Handlebars.compile(e);let c;Handlebars.registerHelper("esc_attr",(function(e){return e})),Handlebars.registerHelper("esc_url",(function(e){return e})),Handlebars.registerHelper("esc_html",(function(e){return e})),Handlebars.registerHelper("base_url",(function(){const e=["block"];return o&&e.push(o.substr(1)),["",...e,""].join("/")}));try{c=a(n)}catch(e){c=`<div style="max-width: 1280px; margin: 1rem auto;">\n <h1 style="all: unset; font-size: 1.5rem; font-weight: bold; display: block;">Syntax Error:</h1>\n <pre style="all: unset; padding: 10px 15px; background-color: #ffe6e6; border: 1px solid red; border-radius: 0.25rem; overflow: auto; display: block; white-space: pre;">${e.toString()}</pre>\n </div>`}r.innerHTML=c,t&&t()}(e,n||{},document.getElementById("hbs-container"))}!function(){const e=new URLSearchParams({block:o,name:r().data||"default"});fetch(`/data?${e}`).then((e=>e.json())).then((e=>{n=e.data,c({data:n})}))}(),window.addEventListener("message",(function(e){const t=e.data,o="dataUpdate:";if("string"==typeof t&&t.startsWith(o))try{n=JSON.parse(t.substring(o.length)),c({data:n})}catch(e){console.log("Error parsing incoming data.",e)}})),function(){const e=window.io.connect("",{query:`block=${o}`});e.on("error",(function(e){console.log(e)})),e.on("templateUpdate",(function(e){c({template:e.template})})),e.on("scriptUpdate",(function(e){a("block-script").onload=()=>{c({template:e.template})}})),e.on("styleUpdate",(function(e){a("block-stylesheet")}))}()}();
|
||||||
|
|
||||||
let template;
|
|
||||||
let data = {};
|
|
||||||
let reload;
|
|
||||||
|
|
||||||
// Blocks Initialization.
|
|
||||||
function initBlock(blockName = '', selector = '', cb) {
|
|
||||||
reload = function () {
|
|
||||||
document.querySelectorAll(selector).forEach((el) => cb(el));
|
|
||||||
};
|
|
||||||
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scrollbars / Frame resizes notifications.
|
|
||||||
(function () {
|
|
||||||
let height;
|
|
||||||
|
|
||||||
handleHeightChange(); // Initial frame's height setup.
|
|
||||||
setupResizeListener(); // Listen to frame's height changes.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
function setupResizeListener() {
|
|
||||||
const resizeObserver = new ResizeObserver(handleHeightChange);
|
|
||||||
resizeObserver.observe(document.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleHeightChange() {
|
|
||||||
const updatedHeight = getCurrentHeight();
|
|
||||||
|
|
||||||
if (height === updatedHeight) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RESIZE_CODE = 'resize:';
|
|
||||||
height = updatedHeight;
|
|
||||||
window.parent.postMessage(RESIZE_CODE + JSON.stringify({height}), '*');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentHeight() {
|
|
||||||
return document.querySelector('#hbs-container').scrollHeight;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Data Updates Listeners.
|
|
||||||
(function () {
|
|
||||||
loadDataOptions();
|
|
||||||
listenToDataOptionsUpdates();
|
|
||||||
|
|
||||||
function listenToDataOptionsUpdates() {
|
|
||||||
window.addEventListener('message', function (event) {
|
|
||||||
const message = event.data;
|
|
||||||
const prefix = 'dataUpdate:';
|
|
||||||
|
|
||||||
if (typeof message !== "string" || !message.startsWith(prefix)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
data = JSON.parse(message.substring(prefix.length));
|
|
||||||
updateBlock({data});
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error parsing incoming data.', e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getQueryParams() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const params = {};
|
|
||||||
|
|
||||||
for (const [key, value] of urlParams) {
|
|
||||||
params[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadDataOptions() {
|
|
||||||
const queryParameters = new URLSearchParams({name: getQueryParams().data || 'default'});
|
|
||||||
fetch(`/data?${queryParameters}`)
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((response) => {
|
|
||||||
data = response.data; // Update state.
|
|
||||||
updateBlock({data});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Listen to Template updates.
|
|
||||||
(function () {
|
|
||||||
initSocket();
|
|
||||||
|
|
||||||
function initSocket() {
|
|
||||||
const socket = window.io.connect();
|
|
||||||
|
|
||||||
socket.on('error', function (err) {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
// socket.on('connect', function () {
|
|
||||||
// console.log('user connected', socket.id)
|
|
||||||
// });
|
|
||||||
|
|
||||||
socket.on('templateUpdate', function (args) {
|
|
||||||
updateBlock({template: args.template});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
function updateBlock(args = {}) {
|
|
||||||
if (args.template) {
|
|
||||||
template = args.template; // Update state.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.data) {
|
|
||||||
data = args.data; // Update state.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!template) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBlock(template, data || {}, document.getElementById("hbs-container"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderBlock(templateHbs, jsonData, target) {
|
|
||||||
const template = Handlebars.compile(templateHbs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handlebars Helpers
|
|
||||||
*/
|
|
||||||
Handlebars.registerHelper('esc_attr', function (attr) {
|
|
||||||
return attr;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('esc_url', function (attr) {
|
|
||||||
return attr;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('esc_html', function (attr) {
|
|
||||||
return attr;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('base_url', function () {
|
|
||||||
return '/';
|
|
||||||
});
|
|
||||||
|
|
||||||
let html;
|
|
||||||
|
|
||||||
try {
|
|
||||||
html = template(jsonData);
|
|
||||||
} catch (e) {
|
|
||||||
html = `<div style="max-width: 1280px; margin: 1rem auto;">
|
|
||||||
<h1 style="all: unset; font-size: 1.5rem; font-weight: bold; display: block;">Syntax Error:</h1>
|
|
||||||
<pre style="all: unset; padding: 10px 15px; background-color: #ffe6e6; border: 1px solid red; border-radius: 0.25rem; overflow: auto; display: block; white-space: pre;">${e.toString()}</pre>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.innerHTML = html;
|
|
||||||
if (reload) {
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=frame-index.min.js.map
|
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"frame-index.min.js","sources":["../frame/frame.js"],"sourcesContent":["'use strict';\n\nwindow.initBlock = initBlock;\n\nlet template;\nlet data = {};\nlet reload;\n\n// Blocks Initialization.\nfunction initBlock(blockName = '', selector = '', cb) {\n reload = function () {\n document.querySelectorAll(selector).forEach((el) => cb(el));\n }\n\n reload();\n}\n\n// Scrollbars / Frame resizes notifications.\n(function () {\n let height;\n const debug = false;\n\n handleHeightChange(); // Initial frame's height setup.\n setupResizeListener(); // Listen to frame's height changes.\n\n ///\n\n function setupResizeListener() {\n const resizeObserver = new ResizeObserver(handleHeightChange);\n resizeObserver.observe(document.body);\n }\n\n function handleHeightChange() {\n const updatedHeight = getCurrentHeight();\n\n if (debug) {\n console.log('Height Updates', 'Old vs New: ' + height, updatedHeight);\n }\n\n if (height === updatedHeight) {\n return;\n }\n\n const RESIZE_CODE = 'resize:';\n height = updatedHeight;\n window.parent.postMessage(RESIZE_CODE + JSON.stringify({height}), '*');\n\n if (debug) {\n console.log('Resize message sent: ', height)\n }\n }\n\n function getCurrentHeight() {\n return document.querySelector('#hbs-container').scrollHeight;\n }\n})();\n\n// Data Updates Listeners.\n(function () {\n loadDataOptions();\n listenToDataOptionsUpdates();\n\n function listenToDataOptionsUpdates() {\n window.addEventListener('message', function (event) {\n const message = event.data;\n const prefix = 'dataUpdate:';\n\n if (typeof message !== \"string\" || !message.startsWith(prefix)) {\n return;\n }\n\n try {\n data = JSON.parse(message.substring(prefix.length));\n updateBlock({data});\n } catch (e) {\n console.log('Error parsing incoming data.', e);\n }\n });\n }\n\n function getQueryParams() {\n const urlParams = new URLSearchParams(window.location.search);\n const params = {};\n\n for (const [key, value] of urlParams) {\n params[key] = value;\n }\n\n return params;\n }\n\n function loadDataOptions() {\n const queryParameters = new URLSearchParams({name: getQueryParams().data || 'default'});\n fetch(`/data?${queryParameters}`)\n .then((response) => response.json())\n .then((response) => {\n data = response.data; // Update state.\n updateBlock({data});\n })\n }\n})();\n\n// Listen to Template updates.\n(function () {\n initSocket();\n\n function initSocket() {\n const socket = window.io.connect();\n\n socket.on('error', function (err) {\n console.log(err);\n });\n\n // socket.on('connect', function () {\n // console.log('user connected', socket.id)\n // });\n\n socket.on('templateUpdate', function (args) {\n updateBlock({template: args.template});\n });\n }\n})();\n\nfunction updateBlock(args = {}) {\n if (args.template) {\n template = args.template; // Update state.\n }\n\n if (args.data) {\n data = args.data; // Update state.\n }\n\n if (!template) {\n return;\n }\n\n renderBlock(template, data || {}, document.getElementById(\"hbs-container\"));\n}\n\nfunction renderBlock(templateHbs, jsonData, target) {\n const template = Handlebars.compile(templateHbs);\n\n /**\n * Handlebars Helpers\n */\n Handlebars.registerHelper('esc_attr', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_url', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_html', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('base_url', function () {\n return '/';\n });\n\n let html;\n\n try {\n html = template(jsonData);\n } catch (e) {\n html = `<div style=\"max-width: 1280px; margin: 1rem auto;\">\n <h1 style=\"all: unset; font-size: 1.5rem; font-weight: bold; display: block;\">Syntax Error:</h1>\n <pre style=\"all: unset; padding: 10px 15px; background-color: #ffe6e6; border: 1px solid red; border-radius: 0.25rem; overflow: auto; display: block; white-space: pre;\">${e.toString()}</pre>\n </div>`;\n }\n\n target.innerHTML = html;\n if (reload) {\n reload();\n }\n}\n"],"names":[],"mappings":"AAEA,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;AAC7B;AACA,IAAI,QAAQ,CAAC;AACb,IAAI,IAAI,GAAG,EAAE,CAAC;AACd,IAAI,MAAM,CAAC;AACX;AACA;AACA,SAAS,SAAS,CAAC,SAAS,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,EAAE;AACtD,EAAE,MAAM,GAAG,YAAY;AACvB,IAAI,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAChE,IAAG;AACH;AACA,EAAE,MAAM,EAAE,CAAC;AACX,CAAC;AACD;AACA;AACA,CAAC,YAAY;AACb,EAAE,IAAI,MAAM,CAAC;AAEb;AACA,EAAE,kBAAkB,EAAE,CAAC;AACvB,EAAE,mBAAmB,EAAE,CAAC;AACxB;AACA;AACA;AACA,EAAE,SAAS,mBAAmB,GAAG;AACjC,IAAI,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAClE,IAAI,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1C,GAAG;AACH;AACA,EAAE,SAALine truncated
|
{"version":3,"file":"frame-index.min.js","sources":["../frame/frame.js"],"sourcesContent":["'use strict';\n\nwindow.initBlock = initBlock;\n\nlet template;\nlet data = {};\nlet reload;\n\n// Blocks Initialization.\nfunction initBlock(blockName = '', selector = '', cb) {\n reload = function () {\n document.querySelectorAll(selector).forEach((el) => cb(el));\n }\n\n reload();\n}\n\n// Data Updates Listeners.\n(function () {\n loadDataOptions();\n listenToDataOptionsUpdates();\n\n function listenToDataOptionsUpdates() {\n window.addEventListener('message', function (event) {\n const message = event.data;\n const prefix = 'dataUpdate:';\n\n if (typeof message !== \"string\" || !message.startsWith(prefix)) {\n return;\n }\n\n try {\n data = JSON.parse(message.substring(prefix.length));\n updateBlock({data});\n } catch (e) {\n console.log('Error parsing incoming data.', e);\n }\n });\n }\n\n function getQueryParams() {\n const urlParams = new URLSearchParams(window.location.search);\n const params = {};\n\n for (const [key, value] of urlParams) {\n params[key] = value;\n }\n\n return params;\n }\n\n function loadDataOptions() {\n const queryParameters = new URLSearchParams({name: getQueryParams().data || 'default'});\n fetch(`/data?${queryParameters}`)\n .then((response) => response.json())\n .then((response) => {\n data = response.data; // Update state.\n updateBlock({data});\n })\n }\n})();\n\n// Listen to Template updates.\n(function () {\n initSocket();\n\n function initSocket() {\n const socket = window.io.connect();\n\n socket.on('error', function (err) {\n console.log(err);\n });\n\n // socket.on('connect', function () {\n // console.log('user connected', socket.id)\n // });\n\n socket.on('templateUpdate', function (args) {\n updateBlock({template: args.template});\n });\n }\n})();\n\nfunction updateBlock(args = {}) {\n if (args.template) {\n template = args.template; // Update state.\n }\n\n if (args.data) {\n data = args.data; // Update state.\n }\n\n if (!template) {\n return;\n }\n\n renderBlock(template, data || {}, document.getElementById(\"hbs-container\"));\n}\n\nfunction renderBlock(templateHbs, jsonData, target) {\n const template = Handlebars.compile(templateHbs);\n\n /**\n * Handlebars Helpers\n */\n Handlebars.registerHelper('esc_attr', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_url', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_html', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('base_url', function () {\n return '/';\n });\n\n let html;\n\n try {\n html = template(jsonData);\n } catch (e) {\n html = `<div style=\"max-width: 1280px; margin: 1rem auto;\">\n <h1 style=\"all: unset; font-size: 1.5rem; font-weight: bold; display: block;\">Syntax Error:</h1>\n <pre style=\"all: unset; padding: 10px 15px; background-color: #ffe6e6; border: 1px solid red; border-radius: 0.25rem; overflow: auto; display: block; white-space: pre;\">${e.toString()}</pre>\n </div>`;\n }\n\n target.innerHTML = html;\n if (reload) {\n reload();\n }\n}\n"],"names":[],"mappings":"AAEA,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;AAC7B;AACA,IAAI,QAAQ,CAAC;AACb,IAAI,IAAI,GAAG,EAAE,CAAC;AACd,IAAI,MAAM,CAAC;AACX;AACA;AACA,SAAS,SAAS,CAAC,SAAS,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,EAAE;AACtD,EAAE,MAAM,GAAG,YAAY;AACvB,IAAI,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAChE,IAAG;AACH;AACA,EAAE,MAAM,EAAE,CAAC;AACX,CAAC;AACD;AACA;AACA,CAAC,YAAY;AACb,EAAE,eAAe,EAAE,CAAC;AACpB,EAAE,0BAA0B,EAAE,CAAC;AAC/B;AACA,EAAE,SAAS,0BAA0B,GAAG;AACxC,IAAI,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,KAAK,EAAE;AACxD,MAAM,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;AACjC,MAAM,MAAM,MAAM,GAAG,aAAa,CAAC;AACnC;AACA,MAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AACtE,QAAQ,OAAO;AACf,OAAO;AACP;AACA,MAAM,IAAI;AACV,QAAQ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,QAAQ,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,OAAO,CAAC,OAAO,CAAC,EAAE;AAClB,QAAQ,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;AACvD,OAAO;AACP,KAAK,CAAC,CAAC;AACP,GAAG;AACH;AACA,EAAE,SAAS,cAAc,GAAG;AAC5B,IAAI,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAClE,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;AACtB;AACA,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE;AAC1C,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC1B,KAAK;AACL;AACA,IAAI,OAAO,MAAM,CAAC;AAClB,GAAG;AACH;AACA,EAAE,SAAS,eAAe,GAAG;AAC7B,IAAI,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC;AAC5F,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AACrC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC1C,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK;AAC1B,QAAQ,IAAI,GAAG,QAAQ,CAAC,IAAI,CAALine truncated
|
||||||
Vendored
+15
-9917
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"index.min.js","sources":["../../../node_modules/react/cjs/react.production.min.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.min.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.min.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/client.js","../../../node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-is/index.js","../../../node_modules/@emotion/stylis/dist/stylis.esm.js","../../../node_modules/@emotion/unitless/dist/unitless.esm.js","../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../toolbar/responsive.style.js","../toolbar/responsive-button/responsive-button.style.js","../toolbar/responsive-button/ResponsiveButton.jsx","../toolbar/responsive.jsx","../toolbar/publish.jsx","../toolbar/data-options/data-options.style.js","../toolbar/data-options/design-preview.style.js","../toolbar/data-options/DesignPreview.jsx","../toolbar/data-options/DataOptions.jsx","../frame/editor.js","../index.js"],"sourcesContent":["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return\"object\"===typeof a&&null!==a&&null!=a.key?escape(\"\"+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if(\"undefined\"===k||\"boolean\"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case \"string\":case \"number\":h=!0;break;case \"object\":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=\"\"===d?\".\"+Q(h,0):d,I(c)?(e=\"\",null!=a&&(e=a.replace(P,\"$&/\")+\"/\"),R(c,b,e,\"\",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?\"\":(\"\"+c.key).replace(P,\"$&/\")+\"/\")+a)),b.push(c)),1;h=0;d=\"\"===d?\".\":d+\":\";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),\"function\"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if(\"object\"===k)throw b=String(a),Error(\"Objects are not valid as a React child (found: \"+(\"[object Object]\"===b?\"object with keys {\"+Object.keys(a).join(\", \")+\"}\":b)+\"). If you meant to render a collection of children, use an array instead.\");return h}\nfunction Line truncated
|
{"version":3,"file":"index.min.js","sources":["../../../node_modules/react/cjs/react.production.min.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.min.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.min.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/client.js","../../../node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-is/index.js","../../../node_modules/@emotion/stylis/dist/stylis.esm.js","../../../node_modules/@emotion/unitless/dist/unitless.esm.js","../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../toolbar/responsive.style.js","../toolbar/responsive-button/responsive-button.style.js","../toolbar/responsive-button/ResponsiveButton.jsx","../toolbar/responsive.jsx","../toolbar/publish.jsx","../toolbar/data-options/data-options.style.js","../toolbar/data-options/design-preview.style.js","../toolbar/data-options/DesignPreview.jsx","../toolbar/data-options/DataOptions.jsx","../index.js"],"sourcesContent":["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return\"object\"===typeof a&&null!==a&&null!=a.key?escape(\"\"+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if(\"undefined\"===k||\"boolean\"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case \"string\":case \"number\":h=!0;break;case \"object\":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=\"\"===d?\".\"+Q(h,0):d,I(c)?(e=\"\",null!=a&&(e=a.replace(P,\"$&/\")+\"/\"),R(c,b,e,\"\",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?\"\":(\"\"+c.key).replace(P,\"$&/\")+\"/\")+a)),b.push(c)),1;h=0;d=\"\"===d?\".\":d+\":\";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),\"function\"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if(\"object\"===k)throw b=String(a),Error(\"Objects are not valid as a React child (found: \"+(\"[object Object]\"===b?\"object with keys {\"+Object.keys(a).join(\", \")+\"}\":b)+\"). If you meant to render a collection of children, use an array instead.\");return h}\nfunction S(a,b,e){if(null==a)rLine truncated
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var n={exports:{}},t={},r=Symbol.for("react.element"),l=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),s=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),m=Symbol.iterator;var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,v={};function y(e,n,t){this.props=e,this.context=n,this.refs=v,this.updater=t||h}function b(){}function k(e,n,t){this.props=e,this.context=n,this.refs=v,this.updater=t||h}y.prototype.isReactComponent={},y.prototype.setState=function(e,n){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,n,"setState")},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=y.prototype;var w=k.prototype=new b;w.constructor=k,g(w,y.prototype),w.isPureReactComponent=!0;var S=Array.isArray,E=Object.prototype.hasOwnProperty,x={current:null},C={key:!0,ref:!0,__self:!0,__source:!0};function _(e,n,t){var l,a={},o=null,u=null;if(null!=n)for(l in void 0!==n.ref&&(u=n.ref),void 0!==n.key&&(o=""+n.key),n)E.call(n,l)&&!C.hasOwnProperty(l)&&(a[l]=n[l]);var i=arguments.length-2;if(1===i)a.children=t;else if(1<i){for(var s=Array(i),c=0;c<i;c++)s[c]=arguments[c+2];a.children=s}if(e&&e.defaultProps)for(l in i=e.defaultProps)void 0===a[l]&&(a[l]=i[l]);return{$$typeof:r,type:e,key:o,ref:u,props:a,_owner:x.current}}function P(e){return"object"==typeof e&&null!==e&&e.$$typeof===r}var N=/\/+/g;function z(e,n){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var n={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return n[e]}))}(""+e.key):n.toString(36)}function T(e,n,t,a,o){var u=typeof e;"undefined"!==u&&"boolean"!==u||(e=null);var i=!1;if(null===e)i=!0;else switch(u){case"string":case"number":i=!0;break;case"object":switch(e.$$typeof){case r:case l:i=!0}}if(i)return o=o(i=e),e=""===a?"."+z(i,0):a,S(o)?(t="",null!=e&&(t=e.replace(N,"$&/")+"/"),T(o,n,t,"",(function(e){return e}))):null!=o&&(P(o)&&(o=function(e,n){return{$$typeof:r,type:e.type,key:n,ref:e.ref,props:e.props,_owner:e._owner}}(o,t+(!o.key||i&&i.key===o.key?"":(""+o.key).replace(N,"$&/")+"/")+e)),n.push(o)),1;if(i=0,a=""===a?".":a+":",S(e))for(var s=0;s<e.length;s++){var c=a+z(u=e[s],s);i+=T(u,n,t,c,o)}else if(c=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=m&&e[m]||e["@@iterator"])?e:null}(e),"function"==typeof c)for(e=c.call(e),s=0;!(u=e.next()).done;)i+=T(u=u.value,n,t,c=a+z(u,s++),o);else if("object"===u)throw n=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===n?"object with keys {"+Object.keys(e).join(", ")+"}":n)+"). If you meant to render a collection of children, use an array instead.");return i}function L(e,n,t){if(null==e)return e;var r=[],l=0;return T(e,r,"","",(function(e){return n.call(t,e,l++)})),r}function R(e){if(-1===e._status){var n=e._result;(n=n()).then((function(n){0!==e._status&&-1!==e._status||(e._status=1,e._result=n)}),(function(n){0!==e._status&&-1!==e._status||(e._status=2,e._result=n)})),-1===e._status&&(e._status=0,e._result=n)}if(1===e._status)return e._result.default;throw e._result}var M={current:null},F={transition:null},O={ReactCurrentDispatcher:M,ReactCurrentBatchConfig:F,ReactCurrentOwner:x};t.Children={map:L,forEach:function(e,n,t){L(e,(function(){n.apply(this,arguments)}),t)},count:function(e){var n=0;return L(e,(function(){n++})),n},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!P(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=y,t.Fragment=a,t.Profiler=u,t.PureComponent=k,t.StrictMode=o,t.Suspense=f,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=O,t.cloneElement=function(e,n,t){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var l=g({},e.props),a=e.key,o=e.ref,u=e._owner;if(null!=n){if(void 0!==n.ref&&(o=n.ref,u=x.current),void 0!==n.key&&(a=""+n.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(s in n)E.call(n,s)&&!C.hasOwnProperty(s)&&(l[s]=void 0===n[s]&&void 0!==i?i[s]:n[s])}var s=arguments.length-2;if(1===s)l.children=t;else if(1<s){i=Array(s);for(var c=0;c<s;c++)i[c]=arguments[c+2];l.children=i}return{$$typeof:r,type:e.type,key:a,ref:o,props:l,_owner:u}},t.createContext=function(e){return(e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},Line truncated
|
||||||
|
/**
|
||||||
|
* @license React
|
||||||
|
* scheduler.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
!function(e){function n(e,n){var t=e.length;e.push(n);e:for(;0<t;){var r=t-1>>>1,a=e[r];if(!(0<l(a,n)))break e;e[r]=n,e[t]=a,t=r}}function t(e){return 0===e.length?null:e[0]}function r(e){if(0===e.length)return null;var n=e[0],t=e.pop();if(t!==n){e[0]=t;e:for(var r=0,a=e.length,o=a>>>1;r<o;){var u=2*(r+1)-1,i=e[u],s=u+1,c=e[s];if(0>l(i,t))s<a&&0>l(c,i)?(e[r]=c,e[s]=t,r=s):(e[r]=i,e[u]=t,r=u);else{if(!(s<a&&0>l(c,t)))break e;e[r]=c,e[s]=t,r=s}}}return n}function l(e,n){var t=e.sortIndex-n.sortIndex;return 0!==t?t:e.id-n.id}if("object"==typeof performance&&"function"==typeof performance.now){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,u=o.now();e.unstable_now=function(){return o.now()-u}}var i=[],s=[],c=1,f=null,d=3,p=!1,m=!1,h=!1,g="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function b(e){for(var l=t(s);null!==l;){if(null===l.callback)r(s);else{if(!(l.startTime<=e))break;r(s),l.sortIndex=l.expirationTime,n(i,l)}l=t(s)}}function k(e){if(h=!1,b(e),!m)if(null!==t(i))m=!0,R(w);else{var n=t(s);null!==n&&M(k,n.startTime-e)}}function w(n,l){m=!1,h&&(h=!1,v(C),C=-1),p=!0;var a=d;try{for(b(l),f=t(i);null!==f&&(!(f.expirationTime>l)||n&&!N());){var o=f.callback;if("function"==typeof o){f.callback=null,d=f.priorityLevel;var u=o(f.expirationTime<=l);l=e.unstable_now(),"function"==typeof u?f.callback=u:f===t(i)&&r(i),b(l)}else r(i);f=t(i)}if(null!==f)var c=!0;else{var g=t(s);null!==g&&M(k,g.startTime-l),c=!1}return c}finally{f=null,d=a,p=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var S,E=!1,x=null,C=-1,_=5,P=-1;function N(){return!(e.unstable_now()-P<_)}function z(){if(null!==x){var n=e.unstable_now();P=n;var t=!0;try{t=x(!0,n)}finally{t?S():(E=!1,x=null)}}else E=!1}if("function"==typeof y)S=function(){y(z)};else if("undefined"!=typeof MessageChannel){var T=new MessageChannel,L=T.port2;T.port1.onmessage=z,S=function(){L.postMessage(null)}}else S=function(){g(z,0)};function R(e){x=e,E||(E=!0,S())}function M(n,t){C=g((function(){n(e.unstable_now())}),t)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_continueExecution=function(){m||p||(m=!0,R(w))},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):_=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return d},e.unstable_getFirstCallbackNode=function(){return t(i)},e.unstable_next=function(e){switch(d){case 1:case 2:case 3:var n=3;break;default:n=d}var t=d;d=n;try{return e()}finally{d=t}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var t=d;d=e;try{return n()}finally{d=t}},e.unstable_scheduleCallback=function(r,l,a){var o=e.unstable_now();switch("object"==typeof a&&null!==a?a="number"==typeof(a=a.delay)&&0<a?o+a:o:a=o,r){case 1:var u=-1;break;case 2:u=250;break;case 5:u=1073741823;break;case 4:u=1e4;break;default:u=5e3}return r={id:c++,callback:l,priorityLevel:r,startTime:a,expirationTime:u=a+u,sortIndex:-1},a>o?(r.sortIndex=a,n(s,r),null===t(i)&&r===t(s)&&(h?(v(C),C=-1):h=!0,M(k,a-o))):(r.sortIndex=u,n(i,r),m||p||(m=!0,R(w))),r},e.unstable_shouldYield=N,e.unstable_wrapCallback=function(e){var n=d;return function(){var t=d;d=n;try{return e.apply(this,arguments)}finally{d=t}}}}(A),V.exports=A;
|
||||||
|
/**
|
||||||
|
* @license React
|
||||||
|
* react-dom.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
var $=n.exports,j=V.exports;function B(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t<arguments.length;t++)n+="&args[]="+encodeURIComponent(arguments[t]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var H=new Set,W={};function Q(e,n){q(e,n),q(e+"Capture",n)}function q(e,n){for(W[e]=n,e=0;e<n.length;e++)H.add(n[e])}var K=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),Y=Object.prototype.hasOwnProperty,X=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,G={},Z={};function J(e,n,t,r,l,a,o){this.acceptsBooleans=2===n||3===n||4===n,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=t,this.propertyName=e,this.type=n,this.sanitizeURL=a,this.removeEmptyString=o}var ee={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){ee[e]=new J(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var n=e[0];ee[n]=new J(n,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){ee[e]=new J(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){ee[e]=new J(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){ee[e]=new J(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){ee[e]=new J(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){ee[e]=new J(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){ee[e]=new J(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){ee[e]=new J(e,5,!1,e.toLowerCase(),null,!1,!1)}));var ne=/[\-:]([a-z])/g;function te(e){return e[1].toUpperCase()}function re(e,n,t,r){var l=ee.hasOwnProperty(n)?ee[n]:null;(null!==l?0!==l.type:r||!(2<n.length)||"o"!==n[0]&&"O"!==n[0]||"n"!==n[1]&&"N"!==n[1])&&(function(e,n,t,r){if(null==n||function(e,n,t,r){if(null!==t&&0===t.type)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==t?!t.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,n,t,r))return!0;if(r)return!1;if(null!==t)switch(t.type){case 3:return!n;case 4:return!1===n;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}(n,t,l,r)&&(t=null),r||null===l?function(e){return!!Y.call(Z,e)||!Y.call(G,e)&&(X.test(e)?Z[e]=!0:(G[e]=!0,!1))}(n)&&(null===t?e.removeAttribute(n):e.setAttribute(n,""+t)):l.mustUseProperty?e[l.propertyName]=null===t?3!==l.type&&"":t:(n=l.attributeName,r=l.attributeNamespace,null===t?e.removeAttribute(n):(t=3===(l=l.type)||4===l&&!0===t?"":""+t,r?e.setAttributeNS(r,n,t):e.setAttribute(n,t))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var n=e.replace(ne,te);ee[n]=new J(n,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var n=e.replace(ne,te);ee[n]=new J(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var n=e.replace(ne,te);ee[n]=new J(n,1,!1,e,"http://www.w3.org
Line truncated
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
export function setupFrameResizeListener() {
|
|
||||||
const previewFrame = getPreviewFrame();
|
|
||||||
|
|
||||||
window.addEventListener('message', function (e) {
|
|
||||||
const RESIZE_CODE = 'resize:';
|
|
||||||
if (typeof e.data !== 'string' || !e.data.startsWith(RESIZE_CODE)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = JSON.parse(e.data.substring(RESIZE_CODE.length))
|
|
||||||
let height = Number.parseInt(data.height)
|
|
||||||
if (height > 20000) {
|
|
||||||
height = 20000; // Limit max height.
|
|
||||||
}
|
|
||||||
previewFrame.style.height = height + 'px'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPreviewFrame() {
|
|
||||||
return document.getElementById('preview_frame');
|
|
||||||
}
|
|
||||||
@@ -15,48 +15,10 @@ function initBlock(blockName = '', selector = '', cb) {
|
|||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scrollbars / Frame resizes notifications.
|
|
||||||
(function () {
|
|
||||||
let height;
|
|
||||||
const debug = false;
|
|
||||||
|
|
||||||
handleHeightChange(); // Initial frame's height setup.
|
|
||||||
setupResizeListener(); // Listen to frame's height changes.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
function setupResizeListener() {
|
|
||||||
const resizeObserver = new ResizeObserver(handleHeightChange);
|
|
||||||
resizeObserver.observe(document.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleHeightChange() {
|
|
||||||
const updatedHeight = getCurrentHeight();
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
console.log('Height Updates', 'Old vs New: ' + height, updatedHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height === updatedHeight) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RESIZE_CODE = 'resize:';
|
|
||||||
height = updatedHeight;
|
|
||||||
window.parent.postMessage(RESIZE_CODE + JSON.stringify({height}), '*');
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
console.log('Resize message sent: ', height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentHeight() {
|
|
||||||
return document.querySelector('#hbs-container').scrollHeight;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Data Updates Listeners.
|
// Data Updates Listeners.
|
||||||
(function () {
|
(function () {
|
||||||
|
const block = getQueryParams().block;
|
||||||
|
|
||||||
loadDataOptions();
|
loadDataOptions();
|
||||||
listenToDataOptionsUpdates();
|
listenToDataOptionsUpdates();
|
||||||
|
|
||||||
@@ -90,7 +52,10 @@ function initBlock(blockName = '', selector = '', cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadDataOptions() {
|
function loadDataOptions() {
|
||||||
const queryParameters = new URLSearchParams({name: getQueryParams().data || 'default'});
|
const queryParameters = new URLSearchParams({
|
||||||
|
block,
|
||||||
|
name: getQueryParams().data || 'default'
|
||||||
|
});
|
||||||
fetch(`/data?${queryParameters}`)
|
fetch(`/data?${queryParameters}`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@@ -98,14 +63,12 @@ function initBlock(blockName = '', selector = '', cb) {
|
|||||||
updateBlock({data});
|
updateBlock({data});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
|
|
||||||
// Listen to Template updates.
|
// Listen to Template updates.
|
||||||
(function () {
|
|
||||||
initSocket();
|
initSocket();
|
||||||
|
|
||||||
function initSocket() {
|
function initSocket() {
|
||||||
const socket = window.io.connect();
|
const socket = window.io.connect('', {query: `block=${block}`});
|
||||||
|
|
||||||
socket.on('error', function (err) {
|
socket.on('error', function (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -118,8 +81,45 @@ function initBlock(blockName = '', selector = '', cb) {
|
|||||||
socket.on('templateUpdate', function (args) {
|
socket.on('templateUpdate', function (args) {
|
||||||
updateBlock({template: args.template});
|
updateBlock({template: args.template});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('scriptUpdate', function (args) {
|
||||||
|
const tag = updateTag('block-script');
|
||||||
|
tag.onload = () => {
|
||||||
|
updateBlock({template: args.template});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('styleUpdate', function (args) {
|
||||||
|
updateTag('block-stylesheet');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTag(id) {
|
||||||
|
const tag = document.getElementById(id);
|
||||||
|
const wrapper = tag.parentNode;
|
||||||
|
|
||||||
|
let clone;
|
||||||
|
let attr;
|
||||||
|
if (tag.tagName === 'SCRIPT') {
|
||||||
|
clone = document.createElement('script');
|
||||||
|
clone.type = 'text/javascript';
|
||||||
|
attr = 'src';
|
||||||
|
} else if (tag.tagName === 'LINK') {
|
||||||
|
clone = document.createElement('link');
|
||||||
|
clone.rel = 'stylesheet';
|
||||||
|
attr = 'href';
|
||||||
|
}
|
||||||
|
|
||||||
|
clone.id = id;
|
||||||
|
|
||||||
|
// Add version to the stylesheet URL, make sure we override the cache and already existing version there.
|
||||||
|
clone[attr] = tag[attr].replace(/(\?v=)[^&]+/, `$1${Date.now()}`);
|
||||||
|
|
||||||
|
tag.remove();
|
||||||
|
wrapper.append(clone);
|
||||||
|
|
||||||
|
return clone;
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
|
|
||||||
function updateBlock(args = {}) {
|
function updateBlock(args = {}) {
|
||||||
if (args.template) {
|
if (args.template) {
|
||||||
@@ -156,7 +156,13 @@ function renderBlock(templateHbs, jsonData, target) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('base_url', function () {
|
Handlebars.registerHelper('base_url', function () {
|
||||||
return '/';
|
const list = ['block'];
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
list.push(block.substr(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['', ...list, ''].join('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
let html;
|
let html;
|
||||||
@@ -175,3 +181,4 @@ function renderBlock(templateHbs, jsonData, target) {
|
|||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
@@ -3,13 +3,16 @@
|
|||||||
import {setupResponsiveness} from './toolbar/responsive.jsx';
|
import {setupResponsiveness} from './toolbar/responsive.jsx';
|
||||||
import {setupPublish} from "./toolbar/publish.jsx";
|
import {setupPublish} from "./toolbar/publish.jsx";
|
||||||
import {setupDataOptions} from "./toolbar/data-options/DataOptions.jsx";
|
import {setupDataOptions} from "./toolbar/data-options/DataOptions.jsx";
|
||||||
import {getPreviewFrame, setupFrameResizeListener} from "./frame/editor.js";
|
|
||||||
|
|
||||||
const rootAttributes = {
|
const rootAttributes = {
|
||||||
previewFrame: getPreviewFrame(),
|
previewFrame: getPreviewFrame(),
|
||||||
};
|
};
|
||||||
|
|
||||||
setupFrameResizeListener();
|
// setupFrameResizeListener();
|
||||||
setupResponsiveness(rootAttributes);
|
setupResponsiveness(rootAttributes);
|
||||||
setupDataOptions(rootAttributes);
|
setupDataOptions(rootAttributes);
|
||||||
setupPublish(rootAttributes);
|
setupPublish(rootAttributes);
|
||||||
|
|
||||||
|
function getPreviewFrame() {
|
||||||
|
return document.getElementById('preview_frame');
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import * as ReactDOM from "react-dom/client";
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
const wrapper = document.querySelector('#screen');
|
||||||
|
|
||||||
|
const root = ReactDOM.createRoot(wrapper);
|
||||||
|
const html = (<SyncScreen/>);
|
||||||
|
|
||||||
|
root.render(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SyncScreen() {
|
||||||
|
const [loading, setLoading] = useState(null);
|
||||||
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
|
return <>
|
||||||
|
|
||||||
|
<section className="container py-5">
|
||||||
|
<h1 style={{marginBottom: '2rem'}}>Oops... Block not in sync.</h1>
|
||||||
|
{error && <p className="alert alert-danger">{error}</p>}
|
||||||
|
|
||||||
|
{loading ?
|
||||||
|
<>
|
||||||
|
{loading === 'syncing' &&
|
||||||
|
<p>Version upgrade in progress...</p>
|
||||||
|
}
|
||||||
|
<p>Please wait...</p>
|
||||||
|
</>
|
||||||
|
:
|
||||||
|
<>
|
||||||
|
<p>Your version of the block is not in sync with the cloud (not latest version).<br/>
|
||||||
|
Would you like to update it?</p>
|
||||||
|
<div className="options">
|
||||||
|
<button className="btn btn-primary" style={{marginRight: '0.5rem'}} onClick={runSyncLogic}>Yes, Update to
|
||||||
|
Latest
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-secondary" onClick={ignoreVersionSync}>Ignore</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</>
|
||||||
|
|
||||||
|
async function ignoreVersionSync() {
|
||||||
|
// Add "ignore" query parameter to current URl and redirect.
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.searchParams.set('ignoreVersionSync', 'true');
|
||||||
|
window.location = url.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runSyncLogic() {
|
||||||
|
setLoading('syncing');
|
||||||
|
|
||||||
|
let data = {};
|
||||||
|
try {
|
||||||
|
const response = await fetch('/sync', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({block: getQueryParams().block}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
data = await response.json();
|
||||||
|
} catch (err) {
|
||||||
|
setError('Error: ' + err.message);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.status !== 200) {
|
||||||
|
setError(data.message);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => window.location.reload(), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This function is used in multiple places (repeated code).
|
||||||
|
// Move to a common place.
|
||||||
|
function getQueryParams() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const params = {};
|
||||||
|
|
||||||
|
for (const [key, value] of urlParams) {
|
||||||
|
params[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
@@ -125,12 +125,13 @@ function DataOptions(props = {}) {
|
|||||||
return fetch(url, requestOptions)
|
return fetch(url, requestOptions)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(result => {
|
.then(result => {
|
||||||
|
console.log(result)
|
||||||
if (result.statusCode !== 200) {
|
if (result.statusCode !== 200) {
|
||||||
throw new Error(result.message);
|
throw new Error(result.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = result.variation;
|
const data = result.variation;
|
||||||
updateState({dataText: JSON.stringify(data, null, 2), data});
|
updateState({dataText: JSON.stringify(data, null, 2), data, errorMessage: null, loading: false});
|
||||||
updateIframe(data);
|
updateIframe(data);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -168,7 +169,7 @@ function DataOptions(props = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchDataOptions(name = 'default') {
|
async function fetchDataOptions(name = 'default') {
|
||||||
const queryParameters = new URLSearchParams({name});
|
const queryParameters = new URLSearchParams({name, block: window.devTool.blockName});
|
||||||
const response = await fetch(`/data?${queryParameters}`);
|
const response = await fetch(`/data?${queryParameters}`);
|
||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ function Publish(props = {}) {
|
|||||||
export function setupPublish(rootAttributes) {
|
export function setupPublish(rootAttributes) {
|
||||||
// INIT
|
// INIT
|
||||||
const wrapper = document.createElement('div');
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.setAttribute('id', 'publish-btn');
|
||||||
document.querySelector('.page_toolbar__right').append(wrapper)
|
document.querySelector('.page_toolbar__right').append(wrapper)
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(wrapper);
|
const root = ReactDOM.createRoot(wrapper);
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ function Responsive(props = {}) {
|
|||||||
function updateController() {
|
function updateController() {
|
||||||
let frameBreakpoint = breakpoint;
|
let frameBreakpoint = breakpoint;
|
||||||
if (typeof frameBreakpoint !== 'string') {
|
if (typeof frameBreakpoint !== 'string') {
|
||||||
frameBreakpoint = frameBreakpoint + 'px';
|
const scrollbarWidth = 15;
|
||||||
|
frameBreakpoint = (scrollbarWidth + frameBreakpoint) + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
previewFrame.style.setProperty('--breakpoint', frameBreakpoint);
|
previewFrame.style.setProperty('--breakpoint', frameBreakpoint);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
{{> (include_partial "layouts/partials/head") }}
|
{{> (include_partial "layouts/partials/head") }}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
.preview {
|
.preview {
|
||||||
overflow-y: scroll;
|
|
||||||
height: calc(100% - var(--top_panel_height));
|
height: calc(100% - var(--top_panel_height));
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -9,17 +8,14 @@
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
//height: 100%;
|
||||||
|
|
||||||
--top_spacing: 0px;
|
--top_spacing: 0px;
|
||||||
--breakpoint_top_spacing: 30px;
|
--breakpoint_top_spacing: 30px;
|
||||||
|
|
||||||
margin-top: var(--top_spacing);
|
margin-top: var(--top_spacing);
|
||||||
height: 100%;
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: 1px solid #E2E8F0;
|
|
||||||
|
|
||||||
transition: max-width .3s ease-in-out, width .3s ease-in-out, margin-top .3s ease-in-out;
|
transition: max-width .3s ease-in-out, width .3s ease-in-out, margin-top .3s ease-in-out;
|
||||||
|
|
||||||
&.has-breakpoint {
|
&.has-breakpoint {
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
.swiper {
|
|
||||||
&-slide {
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-wrapper {
|
|
||||||
height: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,9 @@ body {
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
background-color: #F7FAFC;
|
background-color: #F7FAFC;
|
||||||
}
|
}
|
||||||
|
body.view-mode #publish-btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
--btn-color: #333;
|
--btn-color: #333;
|
||||||
@@ -114,7 +117,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
overflow-y: scroll;
|
|
||||||
height: calc(100% - var(--top_panel_height));
|
height: calc(100% - var(--top_panel_height));
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -127,10 +129,8 @@ body {
|
|||||||
--top_spacing: 0px;
|
--top_spacing: 0px;
|
||||||
--breakpoint_top_spacing: 30px;
|
--breakpoint_top_spacing: 30px;
|
||||||
margin-top: var(--top_spacing);
|
margin-top: var(--top_spacing);
|
||||||
height: 100%;
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: 1px solid #E2E8F0;
|
|
||||||
transition: max-width 0.3s ease-in-out, width 0.3s ease-in-out, margin-top 0.3s ease-in-out;
|
transition: max-width 0.3s ease-in-out, width 0.3s ease-in-out, margin-top 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
#preview_frame.has-breakpoint {
|
#preview_frame.has-breakpoint {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["page--main.scss","_buttons.scss","_overlay.scss","_page--preview.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;EACE;EACA;EAEA;;;ACTF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;;AC5BJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AFIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF;EADF;IAEI;;;AAKN;EAEE;EACA;EACA;EACA;;AAGF;EACE;;;AGlFJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EAEA;EACA;;;AH6DJ;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;;;AAGF;EAEE;EACA","file":"page--main.css"}
|
{"version":3,"sourceRoot":"","sources":["page--main.scss","_buttons.scss","_overlay.scss","_page--preview.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;EACE;EACA;EAEA;;AAGE;EACE;;;ACbN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;;AC5BJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AFUF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF;EADF;IAEI;;;AAKN;EAEE;EACA;EACA;EACA;;AAGF;EACE;;;AGxFJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EAGA;EACA;EAEA;EACA;EACA;EACA;;AAEA;EACE;EAEA;EACA;;;AHuEJ;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;;;AAGF;EAEE;EACA","file":"page--main.css"}
|
||||||
@@ -8,6 +8,12 @@ body {
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
//overflow: none;
|
//overflow: none;
|
||||||
background-color: #F7FAFC;
|
background-color: #F7FAFC;
|
||||||
|
|
||||||
|
&.view-mode {
|
||||||
|
#publish-btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "buttons";
|
@import "buttons";
|
||||||
|
|||||||
@@ -2,24 +2,8 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
min-height: 100%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
main .swiper-slide {
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
main .swiper-wrapper {
|
|
||||||
height: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body--iframe {
|
.body--iframe {
|
||||||
overflow-y: hidden;
|
overflow-y: scroll;
|
||||||
}
|
|
||||||
.body--iframe main {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen_layout {
|
.fullscreen_layout {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["page--view.scss","_page--view-swiper.scss"],"names":[],"mappings":"AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;;ACPA;EACE;;AAGF;EACE;;;ADSJ;EACE;;AAEA;EAGE;;;AAIJ;EACE;EACA;EACA;EACA","file":"page--view.css"}
|
{"version":3,"sourceRoot":"","sources":["page--view.scss"],"names":[],"mappings":"AAAA;EACE;;;AAIF;EACE;;;AAGF;EACE;EACA;EACA;EACA","file":"page--view.css"}
|
||||||
@@ -2,25 +2,9 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
min-height: 100%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
// Fixes scrolling issues of swiperJS. Should be included in all projects.
|
|
||||||
@import "page--view-swiper";
|
|
||||||
}
|
|
||||||
|
|
||||||
// iFrame mode
|
// iFrame mode
|
||||||
.body--iframe {
|
.body--iframe {
|
||||||
overflow-y: hidden;
|
overflow-y: scroll;
|
||||||
|
|
||||||
main {
|
|
||||||
// If you change to "overflow: initial", the margin-top/bottom of first/last element will be not included.
|
|
||||||
// Test on fresh block setup where heading has margin-top.
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen_layout {
|
.fullscreen_layout {
|
||||||
@@ -29,4 +13,3 @@ main {
|
|||||||
background-image: url('https://i.ibb.co/pjwL8D1/shapelined-JBKdviwe-XI-unsplash.jpg');
|
background-image: url('https://i.ibb.co/pjwL8D1/shapelined-JBKdviwe-XI-unsplash.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Block Development Tool</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="screen">Loading...</div>
|
||||||
|
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
|
<script src="/scripts/dist/sync.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Generated
+116
-8123
File diff suppressed because it is too large.
Load diff
+9
-5
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "@axe-web/block-dev-tool",
|
"name": "@axe-web/block-dev-tool",
|
||||||
"version": "1.0.27",
|
"version": "1.0.31",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "AXE-WEB",
|
"name": "AXE-WEB",
|
||||||
"email": "[email protected]",
|
"email": "[email protected]",
|
||||||
"url": "https://axe-web.com/"
|
"url": "https://axe-web.com/"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"info": "NODE_ENV=development BLOCK_NAME=header MODULE_PATH= node debug.js",
|
"info": "node debug.js",
|
||||||
"dev": "NODE_ENV=development BLOCK_NAME=header MODULE_PATH= node server.js",
|
"dev": "node server.js",
|
||||||
"build-platform": "NODE_ENV=development BLOCK_NAME=header MODULE_PATH= node ./build.js",
|
"view-mode": "VIEW_MODE=true node server.js",
|
||||||
"dev-dev-tool": "NODE_ENV=development rollup --config rollup.config.js --watch",
|
"build-platform": "BLOCK_NAME=swiper-test MODULE_PATH= node ./build.js",
|
||||||
|
"dev-dev-tool": "rollup --config rollup.config.js --watch",
|
||||||
"build-dev-tool": "rollup --config rollup.config.js"
|
"build-dev-tool": "rollup --config rollup.config.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -19,8 +20,10 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@axe-web/create-block": "^1.1.30",
|
||||||
"@braintree/sanitize-url": "^6.0.0",
|
"@braintree/sanitize-url": "^6.0.0",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
|
"body-parser": "^1.20.2",
|
||||||
"browser-sync": "^2.27.9",
|
"browser-sync": "^2.27.9",
|
||||||
"config": "^3.3.7",
|
"config": "^3.3.7",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
@@ -37,6 +40,7 @@
|
|||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mem-fs": "^2.2.1",
|
"mem-fs": "^2.2.1",
|
||||||
"mem-fs-editor": "^9.5.0",
|
"mem-fs-editor": "^9.5.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
"ngrok": "^5.0.0-beta.2",
|
"ngrok": "^5.0.0-beta.2",
|
||||||
"node-fetch": "^3.2.10",
|
"node-fetch": "^3.2.10",
|
||||||
"open": "^8.4.0",
|
"open": "^8.4.0",
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ export async function createDistFolder(blockName, projectPath = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getBlockFields(block = {}, type = 'content') {
|
export function getBlockFields(block = {}, type = 'content') {
|
||||||
|
if (!block['field_groups']) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const fields_group = block['field_groups'].find((group) => group.name === type);
|
const fields_group = block['field_groups'].find((group) => group.name === type);
|
||||||
const fields = [];
|
const fields = [];
|
||||||
|
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ class Component_Builder {
|
|||||||
$this->register_default_handlebar_helpers();
|
$this->register_default_handlebar_helpers();
|
||||||
|
|
||||||
$this->add_handlebar( 'base_url', function ( $context ) {
|
$this->add_handlebar( 'base_url', function ( $context ) {
|
||||||
$path = join( '/', [ 'blocks', $this->block_project, $this->block_name, 'templates' ] );
|
$path = join( '/', [ $this->block_project, $this->block_name, 'templates' ] );
|
||||||
return plugins_url( $path . '/', 'axeweb-blocks-library/axeweb-blocks-library.php' );
|
return join( '/', [ get_site_url(),'wp-content', 'axe-web-blocks', $path, '' ] );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class <%= blockClassModel %>_Component extends \Core\Component {
|
|||||||
// $version = \Core\Global_Functions::get_current_version_number(); // In Theme
|
// $version = \Core\Global_Functions::get_current_version_number(); // In Theme
|
||||||
|
|
||||||
// $base_path = get_template_directory_uri() . '/components/partials/<%= blockFilename %>/';
|
// $base_path = get_template_directory_uri() . '/components/partials/<%= blockFilename %>/';
|
||||||
wp_enqueue_style( 'block-<%= blockFilename %>', plugins_url( 'templates/styles/<%= blockFilename %>.min.css', __FILE__ ), ['assets-style'], self::VERSION );<% if (include_script) { %>
|
wp_enqueue_style( 'block-<%= blockFilename %>', $this->get_assets_path_url( 'templates/styles/<%= blockFilename %>.min.css' ), ['assets-style'], self::VERSION );<% if (include_script) { %>
|
||||||
wp_enqueue_script( 'block-<%= blockFilename %>', plugins_url( 'templates/scripts/<%= blockFilename %>.min.js', __FILE__ ), ['assets-script'], self::VERSION, true );<% } %>
|
wp_enqueue_script( 'block-<%= blockFilename %>', $this->get_assets_path_url( 'templates/scripts/<%= blockFilename %>.min.js' ), ['assets-script'], self::VERSION, true );<% } %>
|
||||||
|
|
||||||
wp_enqueue_script( 'script-block-<%= blockFilename %>' );
|
wp_enqueue_script( 'script-block-<%= blockFilename %>' );
|
||||||
}<% } %>
|
}<% } %>
|
||||||
@@ -32,13 +32,13 @@ class <%= blockClassModel %>_Component extends \Core\Component {
|
|||||||
'style_assets' => [
|
'style_assets' => [
|
||||||
[
|
[
|
||||||
'name' => '<%= blockFilename %>',
|
'name' => '<%= blockFilename %>',
|
||||||
'url' => plugins_url( 'templates/styles/<%= blockFilename %>.min.css', __FILE__ ),
|
'url' => $this->get_assets_path_url( 'templates/styles/<%= blockFilename %>.min.css' ),
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'script_assets' => [
|
'script_assets' => [
|
||||||
[
|
[
|
||||||
'name' => '<%= blockFilename %>',
|
'name' => '<%= blockFilename %>',
|
||||||
'url' => plugins_url( 'templates/scripts/<%= blockFilename %>.min.js', __FILE__ ),
|
'url' => $this->get_assets_path_url( 'templates/scripts/<%= blockFilename %>.min.js' ),
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
] );
|
] );
|
||||||
@@ -50,7 +50,7 @@ class <%= blockClassModel %>_Component extends \Core\Component {
|
|||||||
$asset_file_front = include( plugin_dir_path( __FILE__ ) . '/templates/gutenberg-block/build/front.asset.php' );
|
$asset_file_front = include( plugin_dir_path( __FILE__ ) . '/templates/gutenberg-block/build/front.asset.php' );
|
||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
'gutenberg-<%= blockFilename %>-scripts-front',
|
'gutenberg-<%= blockFilename %>-scripts-front',
|
||||||
plugins_url( 'templates/gutenberg-block/build/front.js', __FILE__ ),
|
$this->get_assets_path_url( 'templates/gutenberg-block/build/front.js' ),
|
||||||
$asset_file_front['dependencies'],
|
$asset_file_front['dependencies'],
|
||||||
$asset_file_front['version'],
|
$asset_file_front['version'],
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import {mkdir, copyFile} from "fs/promises";
|
import fs, {mkdir, copyFile} from "fs/promises";
|
||||||
import {capitalize, createFiles, getBlockName, getConfigs, readJSONFile} from "../../helpers.js";
|
import {capitalize, createFiles, getBlockName, getConfigs, readJSONFile} from "../../helpers.js";
|
||||||
import {fileURLToPath} from 'url';
|
import {fileURLToPath} from 'url';
|
||||||
import {copy} from "fs-extra";
|
import {copy} from "fs-extra";
|
||||||
@@ -68,10 +68,17 @@ export async function buildWordPress(blockName, args = {}) {
|
|||||||
path.join(distPath, 'templates', 'scripts', `${data.blockFilename}.min.js`),
|
path.join(distPath, 'templates', 'scripts', `${data.blockFilename}.min.js`),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const imagesPath = path.join(projectPath, 'src', 'images');
|
||||||
|
await fs.access(imagesPath);
|
||||||
|
|
||||||
await copy(
|
await copy(
|
||||||
path.join(projectPath, 'src', 'images'),
|
path.join(imagesPath),
|
||||||
path.join(distPath, 'templates', 'images'),
|
path.join(distPath, 'templates', 'images'),
|
||||||
);
|
);
|
||||||
|
} catch (err) {
|
||||||
|
// Folder doesn't exist.
|
||||||
|
}
|
||||||
|
|
||||||
const phpDataObject = await execPHPFile(path.join(phpGeneratorPath, 'build.php'), 'jsonToPhp', {
|
const phpDataObject = await execPHPFile(path.join(phpGeneratorPath, 'build.php'), 'jsonToPhp', {
|
||||||
json: await readJSONFile(path.join(projectPath, 'data', 'default.json'), "utf8"),
|
json: await readJSONFile(path.join(projectPath, 'data', 'default.json'), "utf8"),
|
||||||
|
|||||||
@@ -47,4 +47,26 @@ export default [{
|
|||||||
commonjs(),
|
commonjs(),
|
||||||
!devMode && terser()
|
!devMode && terser()
|
||||||
]
|
]
|
||||||
|
}, {
|
||||||
|
input: 'layouts/scripts/sync.jsx',
|
||||||
|
output: {
|
||||||
|
file: 'layouts/scripts/dist/sync.min.js',
|
||||||
|
sourcemap: devMode
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
nodeResolve({
|
||||||
|
extensions: [".js"],
|
||||||
|
}),
|
||||||
|
replace({
|
||||||
|
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||||
|
preventAssignment: true,
|
||||||
|
}),
|
||||||
|
babel({
|
||||||
|
compact: false,
|
||||||
|
babelHelpers: 'bundled',
|
||||||
|
presets: ["@babel/preset-react"],
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
!devMode && terser()
|
||||||
|
]
|
||||||
}];
|
}];
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import {getBlockConfigs, getBlockName, getBlockVariations, handlebarLayoutsPath} from "../helpers.js";
|
||||||
|
import path from "path";
|
||||||
|
import {buildAssetFiles} from "../inc/changes-watcher.js";
|
||||||
|
|
||||||
|
export default async function (req, res) {
|
||||||
|
const blockName = req.query.block;
|
||||||
|
const block = getBlockName(blockName);
|
||||||
|
|
||||||
|
const blockDir = path.join('blocks', '@' + block.project, block.name);
|
||||||
|
const dataFiles = await getBlockVariations(blockDir);
|
||||||
|
|
||||||
|
const data = await getDataOfFrame(!!req.query.iframe, Object.assign({}, block, {dataFiles}));
|
||||||
|
|
||||||
|
if (data.error && data.errorMessage) {
|
||||||
|
return res.send(data.errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseView = req.params.baseView ?? 'alignfull';
|
||||||
|
|
||||||
|
await buildAssetFiles(blockDir);
|
||||||
|
|
||||||
|
res.render(baseView, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDataOfFrame(isIframe = false, block) {
|
||||||
|
const data = {config: await getBlockConfigs(block)};
|
||||||
|
if (data.error && data.errorMessage) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.helpers = {
|
||||||
|
include_partial: (filesPath) => handlebarLayoutsPath(filesPath),
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIframe) {
|
||||||
|
data.iframeMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.staticFilesPath = `/block/${block.project}/${block.name}`;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
getBlockData,
|
||||||
|
getBlockName,
|
||||||
|
getBlockVariations,
|
||||||
|
getListOfDesignPreviewFiles,
|
||||||
|
} from "../helpers.js";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
|
||||||
|
export default async function (req, res, next) {
|
||||||
|
let variationName = req.query.name ? req.query.name : 'default';
|
||||||
|
const block = getBlockName(req.query.block);
|
||||||
|
|
||||||
|
const blockDir = path.join('blocks', '@' + block.project, block.name);
|
||||||
|
const dataFiles = await getBlockVariations(blockDir);
|
||||||
|
const data = await getBlockData(variationName, {projectPath: blockDir});
|
||||||
|
|
||||||
|
let designPreviewFiles = [];
|
||||||
|
try {
|
||||||
|
designPreviewFiles = getListOfDesignPreviewFiles(variationName, await fs.readdir(path.join(blockDir, 'design', 'preview')), block);
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Preview Design doesn\'t exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
dataOptions: dataFiles,
|
||||||
|
designPreview: designPreviewFiles,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import {getBlockConfigs, getBlockName, getBlockVariations, handlebarLayoutsPath, verifyVersion} from "../helpers.js";
|
||||||
|
import path from "path";
|
||||||
|
import {REGISTRY_URL} from "@axe-web/create-block/env.js";
|
||||||
|
|
||||||
|
export async function index(req, res, next) {
|
||||||
|
|
||||||
|
const blockName = req.query.block;
|
||||||
|
const block = getBlockName(blockName);
|
||||||
|
|
||||||
|
const blockDir = path.join('blocks', '@' + block.project, block.name);
|
||||||
|
const dataFiles = await getBlockVariations(blockDir);
|
||||||
|
|
||||||
|
const data = await getBlockConfigs(Object.assign({}, block, {dataFiles}));
|
||||||
|
|
||||||
|
if (data.error && data.errorMessage) {
|
||||||
|
// TODO: Throw Error.
|
||||||
|
}
|
||||||
|
|
||||||
|
data.helpers = {
|
||||||
|
include_partial: (filesPath) => handlebarLayoutsPath('.', filesPath),
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Make sure we sync block before we start working on it.
|
||||||
|
try {
|
||||||
|
const verifiedVersion = await verifyVersion(blockName, blockDir, REGISTRY_URL);
|
||||||
|
if (!verifiedVersion && !req.query['ignoreVersionSync']) {
|
||||||
|
return res.render('sync', data);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
const errorMessage = "Can't verify block version.";
|
||||||
|
console.log(errorMessage, err);
|
||||||
|
return next(new Error(errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
data.blockName = blockName;
|
||||||
|
data.baseView = 'alignfull';
|
||||||
|
data.port = `/view/${data.baseView}`;
|
||||||
|
|
||||||
|
let previewFrameUrl = ``; // This variable is used in `*.hbs` and it will be updated once BrowserSync is ready.
|
||||||
|
data.previewFrameUrl = `${previewFrameUrl}${data.port}`;
|
||||||
|
data.previewFrameUrlNewWindow = `${previewFrameUrl}${data.port}`;
|
||||||
|
data.shareUrl = '';
|
||||||
|
|
||||||
|
data.viewMode = process.env.VIEW_MODE ?? false;
|
||||||
|
|
||||||
|
res.render('index', data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export default async function (req, res, next) {
|
||||||
|
|
||||||
|
if (process.env.VIEW_MODE) {
|
||||||
|
throw new Error("Can't publish in view mode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
export function staticFiles(req, res) {
|
||||||
|
const fileName = req.params[0];
|
||||||
|
const path = `blocks/@${req.params.project}/${req.params.blockName}/src/${fileName}`;
|
||||||
|
|
||||||
|
return deliverStaticFile(path, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function previewFiles(req, res) {
|
||||||
|
const fileName = req.params[0];
|
||||||
|
const path = `blocks/@${req.params.project}/${req.params.blockName}/design/${fileName}`;
|
||||||
|
|
||||||
|
return deliverStaticFile(path, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deliverStaticFile(path, res) {
|
||||||
|
// If file doesn't exist, return 404.
|
||||||
|
res.sendFile(path, {root: './'}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
res.send('File not found.');
|
||||||
|
res.status(err.status).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import {syncFilesWithCloud} from "../helpers.js";
|
||||||
|
|
||||||
|
export default async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
await syncFilesWithCloud(req.body.block, null, true);
|
||||||
|
} catch (err) {
|
||||||
|
return res.status(500).json({status: 500, message: err.message});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({status: 200, message: 'Successfully synced!'});
|
||||||
|
}
|
||||||
@@ -1,441 +1,35 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import {PRODUCTION_REGISTRY_URL} from "./env.js";
|
import {init} from "./inc/server.js";
|
||||||
import path from 'path';
|
import {index} from "./routes/index.js";
|
||||||
import fetch from "node-fetch";
|
import dataRoute from "./routes/data.js";
|
||||||
import express from 'express';
|
import baseView from "./routes/base-view.js";
|
||||||
import {create} from 'express-handlebars';
|
import syncRoute from "./routes/sync.js";
|
||||||
import browserSync from 'browser-sync';
|
import publishRoute from "./routes/publish.js";
|
||||||
import config from 'config';
|
import {ViewSync} from "./inc/view-sync.js";
|
||||||
import gulp from 'gulp';
|
import {previewFiles, staticFiles} from "./routes/static-files.js";
|
||||||
import babel from "gulp-babel";
|
import {setupWatcher} from "./inc/changes-watcher.js";
|
||||||
import uglify from "gulp-uglify";
|
|
||||||
import rename from "gulp-rename";
|
|
||||||
import dartSass from 'sass';
|
|
||||||
import gulpSass from 'gulp-sass';
|
|
||||||
import sourcemaps from "gulp-sourcemaps";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import open from "open";
|
|
||||||
import {sanitizeUrl} from "@braintree/sanitize-url";
|
|
||||||
import sanitizeHtml from 'sanitize-html';
|
|
||||||
import {escape} from "lodash-es";
|
|
||||||
import {getBlockData, getBlockConfigs, getConfigs, readJSONFile, zipProject} from "./helpers.js";
|
|
||||||
import PluginError from 'plugin-error';
|
|
||||||
import {Server} from "socket.io";
|
|
||||||
import {createServer} from 'http';
|
|
||||||
import {authtoken, connect} from "ngrok";
|
|
||||||
|
|
||||||
/**
|
const {expressApp, httpServer} = init();
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const {isDev, modulesPath, projectPath, developmentBlockName} = getConfigs();
|
const viewSync = new ViewSync(httpServer);
|
||||||
const blocksRegistry = isDev ? 'http://localhost:3020' : PRODUCTION_REGISTRY_URL;
|
setupWatcher(viewSync);
|
||||||
const DevToolToken = 'D9lgz0TvzXCnp0xnwVBL109DaAR6Puk6F7YewDhgmP8='; // Temporary token for development purposes.
|
|
||||||
|
|
||||||
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data')));
|
const PORT = process.env.PORT || 3010;
|
||||||
|
|
||||||
/**
|
httpServer.listen(PORT, '0.0.0.0', () => {
|
||||||
* State
|
console.log(`Server app listening on port ${PORT}`)
|
||||||
*/
|
|
||||||
|
|
||||||
let port = 3000; // This variable is used in `*.hbs` and it will be updated once BrowserSync is ready.
|
|
||||||
let previewFrameUrl = `/`; // This variable is used in `*.hbs` and it will be updated once BrowserSync is ready.
|
|
||||||
let shareUrl = '';
|
|
||||||
const sessions = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init server
|
|
||||||
*/
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
const httpServer = createServer(app);
|
|
||||||
initSessionsServer(httpServer);
|
|
||||||
|
|
||||||
const sass = gulpSass(dartSass);
|
|
||||||
|
|
||||||
const hbs = create({
|
|
||||||
extname: '.hbs', defaultLayout: false, partialsDir: ['.'], helpers: {
|
|
||||||
esc_attr(attr) {
|
|
||||||
return escape(attr);
|
|
||||||
}, esc_url(url) {
|
|
||||||
return sanitizeUrl(url);
|
|
||||||
}, esc_html(html) {
|
|
||||||
// TODO: Check if we can remove this helper.
|
|
||||||
return html;
|
|
||||||
}, safe_html(html) {
|
|
||||||
return sanitizeHtml(html);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.engine('.hbs', hbs.engine);
|
// Middleware
|
||||||
app.set('view engine', '.hbs');
|
// expressApp.use(setHeaders);
|
||||||
app.set('views', path.join(modulesPath, 'layouts'));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Routes
|
// Routes
|
||||||
//
|
expressApp.get('/', index);
|
||||||
|
expressApp.get('/data', dataRoute);
|
||||||
|
expressApp.get('/view/:baseView', baseView);
|
||||||
|
expressApp.get('/design/:project/:blockName/*', previewFiles);
|
||||||
|
expressApp.get('/block/:project/:blockName/*', staticFiles);
|
||||||
|
expressApp.post('/sync', syncRoute);
|
||||||
|
expressApp.get('/publish', publishRoute);
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
|
||||||
const data = getBlockConfigs({modulesPath, dataFiles});
|
|
||||||
if (data.error && data.errorMessage) {
|
|
||||||
return res.send(data.errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseView = config.has('baseView') ? config.get('baseView') : 'container';
|
|
||||||
const baseViewUrl = `view/${baseView}`;
|
|
||||||
|
|
||||||
data.helpers = {
|
|
||||||
include_partial: (filesPath) => handlebarLayoutsPath(modulesPath, filesPath),
|
|
||||||
}
|
|
||||||
|
|
||||||
data.baseView = baseView;
|
|
||||||
data.port = `/${baseViewUrl}`;
|
|
||||||
data.previewFrameUrl = `${previewFrameUrl}/${baseViewUrl}`;
|
|
||||||
// data.previewFrameUrl = `/${baseViewUrl}`;
|
|
||||||
data.shareUrl = shareUrl;
|
|
||||||
|
|
||||||
if (req.headers.referer) {
|
|
||||||
// NGROK, public URL
|
|
||||||
data.shareUrl = undefined; // Link already shared.
|
|
||||||
data.previewFrameUrl = `/${baseViewUrl}`;
|
|
||||||
data.publicUrl = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.render('index', data);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/view/:baseView', (req, res) => {
|
|
||||||
const data = {config: getBlockConfigs({modulesPath, dataFiles})};
|
|
||||||
if (data.error && data.errorMessage) {
|
|
||||||
return res.send(data.errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.helpers = {
|
|
||||||
include_partial: (filesPath) => handlebarLayoutsPath(modulesPath, filesPath),
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!!req.query.iframe) {
|
|
||||||
data.iframeMode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseView = req.params.baseView ?? 'container';
|
|
||||||
|
|
||||||
res.render(baseView, data)
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/publish', async (req, res) => {
|
|
||||||
const data = await readJSONFile(path.join(projectPath, `block.json`));
|
|
||||||
let responseData = {
|
|
||||||
uploadUrl: undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${blocksRegistry}`, {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
headers: {'Content-Type': 'application/json'}
|
|
||||||
});
|
|
||||||
|
|
||||||
responseData = await response.json();
|
|
||||||
} catch (e) {
|
|
||||||
res.json({success: false, message: 'Blocks Registry server is not available.'});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseData.statusCode !== 200) {
|
|
||||||
res.json({success: false, message: 'Error on registry level.'});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseData.uploadUrl) {
|
|
||||||
await zipProject(path.join(projectPath, 'src'), path.join(projectPath, 'dist.zip'));
|
|
||||||
const body = await fs.readFile(path.join(projectPath, 'dist.zip'));
|
|
||||||
const response = await fetch(`${responseData.uploadUrl}`, {
|
|
||||||
method: 'PUT',
|
|
||||||
body,
|
|
||||||
headers: {'Content-Type': 'application/zip'}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
res.json({success: false, message: "Can't upload the archive, permissions error."});
|
|
||||||
// TODO: Need to update the registry server.
|
|
||||||
await fs.unlink(path.join(projectPath, 'dist.zip'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
res.json({success: true});
|
|
||||||
|
|
||||||
await fs.unlink(path.join(projectPath, 'dist.zip'));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/data', async (req, res) => {
|
|
||||||
let jsonDataFileName = req.query.name ? req.query.name : 'default';
|
|
||||||
|
|
||||||
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data')));
|
|
||||||
const data = await getBlockData(jsonDataFileName, {projectPath});
|
|
||||||
const designPreviewFiles = getListOfDesignPreviewFiles(jsonDataFileName, await fs.readdir(path.join(projectPath, 'design', 'preview')));
|
|
||||||
|
|
||||||
return res.json({
|
|
||||||
dataOptions: dataFiles,
|
|
||||||
designPreview: designPreviewFiles,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Errors handler
|
|
||||||
app.use(handleSyntaxErrors);
|
|
||||||
|
|
||||||
// Static Files
|
|
||||||
app.use(express.static(path.join(projectPath, 'src')));
|
|
||||||
app.use(express.static(path.join(projectPath, 'design')));
|
|
||||||
app.use(express.static(path.join(modulesPath, 'layouts')));
|
|
||||||
|
|
||||||
// Custom Middleware
|
|
||||||
app.use(setHeaders);
|
|
||||||
|
|
||||||
// Setup Gulp
|
|
||||||
await buildAssetFiles();
|
|
||||||
|
|
||||||
// BrowserSync
|
|
||||||
shareUrl = await getShareableUrl();
|
|
||||||
const bsOptions = await startBrowserSync();
|
|
||||||
port = bsOptions.port;
|
|
||||||
previewFrameUrl = bsOptions.previewFrameUrl;
|
|
||||||
await open(bsOptions.devToolUrl);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Functions
|
|
||||||
//
|
|
||||||
|
|
||||||
function getListOfDesignPreviewFiles(jsonDataFileName, previewFiles) {
|
|
||||||
return previewFiles
|
|
||||||
.filter(fileName => {
|
|
||||||
return fileName.startsWith(jsonDataFileName + '.');
|
|
||||||
})
|
|
||||||
.map(fileName => {
|
|
||||||
const fileData = fileName.split('.');
|
|
||||||
const fileFormat = fileData.pop();
|
|
||||||
const previewSize = fileData.pop();
|
|
||||||
|
|
||||||
return {
|
|
||||||
dataSource: jsonDataFileName,
|
|
||||||
widthDimension: Number.parseInt(previewSize, 10),
|
|
||||||
url: `/preview/${fileName}`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function startBrowserSync() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const listener = httpServer.listen(0, async () => {
|
|
||||||
const PORT = listener.address().port;
|
|
||||||
|
|
||||||
console.log(`The web server has started on port ${PORT}`);
|
|
||||||
|
|
||||||
const bs = browserSync.create();
|
|
||||||
|
|
||||||
const files = getJSBundleFiles();
|
|
||||||
gulp.watch(files, {delay: 400}, gulp.series(['build-script-files', function (cb) {
|
|
||||||
browserSyncReload(bs, 'js', 'Script Files Change');
|
|
||||||
return cb();
|
|
||||||
}]));
|
|
||||||
|
|
||||||
gulp.watch(path.posix.join(projectPath, "src/**/*.scss"), {delay: 400}, gulp.series(['build-styling-files', function (cb) {
|
|
||||||
browserSyncReload(bs, 'css', 'Style Files Change');
|
|
||||||
return cb();
|
|
||||||
}]));
|
|
||||||
|
|
||||||
bs.watch(path.join(projectPath, "src/**/*.hbs"), function () {
|
|
||||||
return syncTemplate(sessions);
|
|
||||||
});
|
|
||||||
|
|
||||||
const args = {
|
|
||||||
proxy: `http://localhost:${PORT}`,
|
|
||||||
open: false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (shareUrl) {
|
|
||||||
args.socket = {
|
|
||||||
domain: shareUrl
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bs.init(args, (err, bs) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = bs.getOptions().toJS();
|
|
||||||
|
|
||||||
const urls = {
|
|
||||||
devTool: options.urls.local.replace(options.port, options.proxy.url.port),
|
|
||||||
previewFrame: options.urls.local,
|
|
||||||
};
|
|
||||||
|
|
||||||
// If local network is available.
|
|
||||||
if (options.urls.external) {
|
|
||||||
urls.devTool = options.urls.external.replace(options.port, options.proxy.url.port);
|
|
||||||
urls.previewFrame = options.urls.external;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
devToolUrl: urls.devTool,
|
|
||||||
previewFrameUrl: urls.previewFrame,
|
|
||||||
port: options.port
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function browserSyncReload(bs, extension = '', message = '') {
|
|
||||||
if (isDev) {
|
|
||||||
// console.log(event, file);
|
|
||||||
console.log(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extension) {
|
|
||||||
extension = "*." + extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
bs.reload(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getJSBundleFiles() {
|
|
||||||
return [path.posix.join(projectPath, "src/**/*.js"), path.posix.join(projectPath, "src/**/*.mjs"), "!" + path.posix.join(projectPath, "src/**/*.min.js")];
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildScriptFiles(done) {
|
|
||||||
const files = getJSBundleFiles();
|
|
||||||
return gulp.src(files, {base: path.posix.join(projectPath, 'src')})
|
|
||||||
.pipe(sourcemaps.init({}))
|
|
||||||
.pipe(babel()).on('error', function (error) {
|
|
||||||
showError(new PluginError('JavaScript', error).toString());
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
.pipe(gulp.src(path.join(projectPath, 'vendor/*.js')))
|
|
||||||
// .pipe(gulp.dest('src/'))
|
|
||||||
.pipe(rename({extname: '.min.js'}))
|
|
||||||
.pipe(uglify())
|
|
||||||
.pipe(sourcemaps.write('.'))
|
|
||||||
.pipe(gulp.dest(path.posix.join(projectPath, 'src')));
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildStyleFiles(done) {
|
|
||||||
return gulp.src(path.join(projectPath, 'src/**/*.scss'), {base: path.posix.join(projectPath, 'src')})
|
|
||||||
.pipe(sourcemaps.init({}))
|
|
||||||
.pipe(sass.sync({outputStyle: 'compressed'}).on('error', function (error) {
|
|
||||||
showError(new PluginError('SCSS', error.messageFormatted).toString());
|
|
||||||
// sass.logError(error);
|
|
||||||
done();
|
|
||||||
}))
|
|
||||||
// .pipe(gulp.dest('src/'))
|
|
||||||
.pipe(rename({extname: '.min.css'}))
|
|
||||||
.pipe(sourcemaps.write('.', {}))
|
|
||||||
.pipe(gulp.dest(path.posix.join(projectPath, 'src')))
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAssetFiles() {
|
|
||||||
// Register tasks.
|
|
||||||
gulp.task('build-script-files', buildScriptFiles);
|
|
||||||
gulp.task('build-styling-files', buildStyleFiles);
|
|
||||||
|
|
||||||
// Run first build.
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
gulp.series('build-script-files', 'build-styling-files', function () {
|
|
||||||
resolve();
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function showError(errorMessage) {
|
|
||||||
console.log(errorMessage);
|
|
||||||
|
|
||||||
// TODO: Send this message to browser.
|
|
||||||
// So the developer can understand there is an error.
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareListOfDataFiles(dataFiles) {
|
|
||||||
return dataFiles
|
|
||||||
.filter((fileName) => fileName.split('.').pop() === 'json')
|
|
||||||
.map((fileName) => {
|
|
||||||
const splitName = fileName.split('.');
|
|
||||||
splitName.pop();
|
|
||||||
return splitName.join('');
|
|
||||||
})
|
|
||||||
.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSyntaxErrors(err, req, res, next) {
|
|
||||||
if (err) {
|
|
||||||
return res.render('error', {
|
|
||||||
helpers: {
|
|
||||||
include_partial: (filesPath) => path.join(modulesPath, filesPath),
|
|
||||||
},
|
|
||||||
err
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlebarLayoutsPath() {
|
|
||||||
return path.join(...arguments)
|
|
||||||
.replace(/\\/g, '/'); // Windows path issue. Fix all "\" for Handlebars.
|
|
||||||
}
|
|
||||||
|
|
||||||
function initSessionsServer(httpServer) {
|
|
||||||
const io = new Server(httpServer);
|
|
||||||
io.on('connection', async (socket) => {
|
|
||||||
sessions.push(socket);
|
|
||||||
await syncTemplate(sessions);
|
|
||||||
});
|
|
||||||
|
|
||||||
return httpServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHeaders(req, res, next) {
|
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function syncTemplate(sessions = []) {
|
|
||||||
const blockName = config.has('blockName') ? config.get('blockName') : developmentBlockName;
|
|
||||||
const hbsTemplate = await fs.readFile(handlebarLayoutsPath(projectPath, 'src', `${blockName}.template.hbs`), 'utf8');
|
|
||||||
|
|
||||||
sessions.forEach(socket => {
|
|
||||||
socket.emit('templateUpdate', {template: hbsTemplate});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getShareableUrl() {
|
|
||||||
let domain = PRODUCTION_REGISTRY_URL;
|
|
||||||
let data = {}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${domain}/dev-tool/?devToolToken=${DevToolToken}`);
|
|
||||||
data = await response.json();
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error:', `Can't load data from DevTool endpoint: ${domain}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.statusCode !== 200) {
|
|
||||||
console.log('Reply from DevTool endpoint:', data.message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let url;
|
|
||||||
try {
|
|
||||||
await authtoken(data.ngrokApiToken);
|
|
||||||
url = await connect(port);
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error:', `Can't connect to ngrok, probably wrong token.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user