Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • oss/minerva/minerva-app
1 result
Show changes
Commits on Source (2)
......@@ -3,7 +3,7 @@
<module name="minerva" />
<working_directory value="$PROJECT_DIR$/application/source" />
<useCustomBuildTags value="true" />
<parameters value="serve --config=../../development/examples/theme1/config.yaml --path=$PROJECT_DIR$/../../alvine/application/platform-themes/silicon/application/web/" />
<parameters value="serve --config=../../development/examples/theme1/config.yaml --path=$PROJECT_DIR$/../../alvine/application/platform-themes/spring/application/web/" />
<kind value="DIRECTORY" />
<directory value="$PROJECT_DIR$/application/source" />
<filePath value="$PROJECT_DIR$" />
......
......@@ -165,6 +165,10 @@ func getEditorScript() http.Handler {
})
}
func getEditorFileserver() http.Handler {
return http.FileServer(http.Dir(webDistPath))
}
func getFileserver() http.Handler {
c := config.GetConfiguration()
return http.FileServer(http.Dir(c.Server.Path))
......
......@@ -130,6 +130,7 @@ func initRouting() *chi.Mux {
router.Handle("/scripts/main.js", getEditorScript())
router.Handle("/styles/main.css", getEditorStyle())
router.Handle("/editor/*", getEditorFileserver())
router.Handle("/*", getFileserver())
router.Get("/", redirectToApp())
return router
......
{
"name": "",
"short_name": "",
"name": "Minerva Editor",
"short_name": "Minerva",
"icons": [
{
"src": "/android-chrome-192x192.png",
"src": "/editor/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"src": "/editor/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
......
......@@ -4170,7 +4170,9 @@ html {
width: 300px;
}
.gjs-pn-views-container {
width: 300px;
width: 288px;
padding: 0;
margin: 0;
}
.gjs-pn-options {
right: 300px;
......
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Minerva Editor</title>
<link rel="icon" type="image/svg+xml" href="/editor/favicon.svg">
<link rel="icon" type="image/png" sizes="32x32" href="/editor/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/editor/favicon-16x16.png">
<link rel="icon" type="image/png" href="/editor/favicon.png">
<link rel="apple-touch-icon" sizes="180x180" href="/editor/apple-touch-icon.png">
<link rel="manifest" href="/editor/site.webmanifest">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/styles/main.css">
<script type="module" src="/scripts/main.js"></script>
</head>
<body>
\ No newline at end of file
import grapesjs from "grapesjs"
import grapesRte from "grapesjs-rte-extensions"
//import grapesjsProjectManager from "grapesjs-project-manager"
import grapesjsCustomCode from "grapesjs-custom-code"
import grapesjsProjectManager from 'grapesjs-project-manager';
import parserPostCSS from 'grapesjs-parser-postcss';
import grapesjsPluginCodeEditor from 'grapesjs-component-code-editor';
import grapesjsScriptEditor from 'grapesjs-script-editor';
import grapesjsTable from 'grapesjs-table';
import grapesjsPluginExport from 'grapesjs-plugin-export';
import grapesjsRulers from 'grapesjs-rulers';
/**
* select an element
* editor.select(editor.DomComponents.getWrapper().find("#i2321t")[0]);
*
*/
export function startEditor(config) {
new Promise((resolve, reject) => {
......@@ -26,15 +30,6 @@ export function startEditor(config) {
`)
function myPlugin(editor, options) {
//console.log(options, 'console.log(options);');
editor.BlockManager.add('my-plugin-name', {
label: 'Simple block',
content: '<div class="my-block">This is a simple block</div>',
});
}
const swv = 'sw-visibility';
const expt = 'export-template';
const osm = 'open-sm';
......@@ -48,9 +43,8 @@ export function startEditor(config) {
container: "#gjs",
// cssIcons: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css",
pageManager: {
},
pageManager: {},
allowScripts: 1,
styleManager: {
// options
......@@ -59,14 +53,12 @@ export function startEditor(config) {
selectorManager: {
// options
},
// grapesjsTable, grapesjsPluginExport, grapesjsProjectManager
plugins: [myPlugin, grapesRte, grapesjsRulers, grapesjsProjectManager,grapesjsPluginCodeEditor, grapesjsScriptEditor, parserPostCSS, grapesjsCustomCode],
plugins: [grapesRte, grapesjsRulers, grapesjsProjectManager, grapesjsPluginCodeEditor, grapesjsScriptEditor, parserPostCSS, grapesjsCustomCode],
pluginsOpts: {
[myPlugin]: {
customField: 'customValue'
},
[grapesjsPluginCodeEditor]: {
openState: {pn: '45%', cv: '55%'},
closedState: {pn: '300px', cv: 'calc( 100% - 300px )'},
......@@ -75,41 +67,7 @@ export function startEditor(config) {
},
[grapesjsCustomCode]: {},
[grapesjsScriptEditor]: {},
// [grapesjsTable]: {
// /* options */
// },
// [grapesjsPluginExport]: {
//
// filenamePfx: 'dummy',
// filename: 'temp',
// addExportBtn: 1,
// btnLabel: 'Export as ZIP',
//
// root(ed) {
// const all = ed.Pages.getAll();
// const pages = {};
// const css = {};
// all.map(page => {
// pages[(page.get('name') || page.id) + '.html'] = '<!doctype html>' +
// '<html lang="en">' +
// '<head>' +
// '<meta charset="utf-8">' +
// '<link rel="stylesheet" href="/css/style-' + page.id + '.css">' +
// '</head>' +
// '<body>' +
// page.getMainComponent().toHTML() +
// '</body>' +
// '</html>';
// css['style-' + page.id + '.css'] = editor.CodeManager.getCode(page.getMainComponent(), 'css')
// });
// return {
// css: {
// ...css
// },
// ...pages
// }
// }
// },
},
......@@ -117,27 +75,10 @@ export function startEditor(config) {
// Size of the editor
height: vh + 'px',
width: 'auto',
//
// resizable: {
// maxDim: 450,
// minDim: 200,
// tc: 0, // Top handler
// cl: 1, // Left handler
// cr: 0, // Right handler
// bc: 0, // Bottom handler
// // Being a flex child we need to change `flex-basis` property
// // instead of the `width` (default)
// keyWidth: 'flex-basis',
// },
noticeOnUnload: config?.editor?.noticeOnUnload ?? false,
// storageManager: {
// type: 'indexeddb',
// // ...
// },
storageManager: {
//type: 'remote',
type: 'rest-api',
......@@ -146,43 +87,8 @@ export function startEditor(config) {
urlStore: config?.editor?.storage?.storeUrl,
urlLoad: config?.editor?.storage?.loadUrl,
urlDelete: config?.editor?.storage?.deleteUrl,
// For custom parameters/headers on requests
//params: { _some_token: '....' },
//headers: { Authorization: 'Basic ...' },
// the URIs below can be the same depending on your API design
// urlStore: config?.editor?.storage?.storeUrl,
// urlLoad: config?.editor?.storage?.loadUrl,
// urlDelete: config?.editor?.storage?.deleteUrl,
//params: { _some_token: '...' },
//headers: { Authorization: 'Basic ...' }
// uuidInPath:false
},
// storageManager: true,
// {
// type: 'remote',
// stepsBeforeSave: 10,
// urlStore: config?.editor?.storage?.storeUrl,
// urlLoad: config?.editor?.storage?.loadUrl,
// params: {}, // Custom parameters to pass with the remote storage request, eg. CSRF token
// headers: {}, // Custom headers for the remote storage request
// // },
// pageManager: {
// // pages: [
// // {
// // id: 'page-id1',
// // styles: `.my-class { color: red }`, // or a JSON of styles
// // component: '<div class="my-class">My element1</div>', // or a JSON of components
// // },
// // {
// // id: 'page-id2',
// // styles: `.my-class { color: blue }`, // or a JSON of styles
// // component: '<div class="my-class">My element2</div>', // or a JSON of components
// // }
// // ],
// },
},
// Avoid any default panel
panels: {
......@@ -285,49 +191,13 @@ export function startEditor(config) {
uploadName: 'files',
autoAdd: true,
dropzone: true,
// assets?: Array<object>;
// noAssets?: string;
// stylePrefix?: string;
// upload?: boolean;
// uploadName?: string;
// headers?: object;
// params?: object;
// credentials?: RequestCredentials;
// multiUpload?: boolean;
// autoAdd?: boolean;
// uploadText?: string;
// addBtnText?: string;
// customFetch?: Function;
// uploadFile?: Function;
// embedAsBase64?: boolean;
// handleAdd?: Function;
// dropzone?: boolean;
// openAssetsOnDrop?: number;
// dropzoneContent?: string;
// modalTitle?: string;
// inputPlaceholder?: string;
// params: {
// _token: "pCYrSwjuiV0t5NVtZpQDY41Gn5lNUwo3it1FIkAj"
// },
},
});
const assetManager = editor.AssetManager;
const storageManager = editor.StorageManager;
// Running commands from panels
const pn = editor.Panels
pn.addButton('options', {
editor.Panels.addButton('options', {
id: 'open-templates',
className: 'fa fa-folder-o',
attributes: {
......@@ -335,7 +205,8 @@ export function startEditor(config) {
},
command: 'open-templates', //Open modal
});
pn.addButton('views', {
editor.Panels.addButton('views', {
id: 'open-pages',
className: 'fa fa-file-o',
attributes: {
......@@ -345,8 +216,7 @@ export function startEditor(config) {
togglable: false
});
pn.addButton('views', {
editor.Panels.addButton('views', {
id: 'open-code',
className: 'fa fa-file-code-o',
attributes: {
......@@ -356,8 +226,7 @@ export function startEditor(config) {
togglable: false
});
pn.addButton('options', {
editor.Panels.addButton('options', {
attributes: {
title: 'Toggle Rulers'
},
......@@ -367,199 +236,7 @@ export function startEditor(config) {
id: 'ruler-visibility'
});
const viewContainerPanel = pn.getPanel('views')
// setTimeout(() => {
// const panels2 = pn.getPanel('views-container')
// console.log(panels2)
// }, 600)
//panels2.set('appendContent', editMenuDiv).trigger('change:appendContent')
//editPanel = editMenuDiv
//
// let editPanel = null
// pn.addButton('views', {
// id: 'editMenu',
// attributes: {class: 'fa fa-file-text-o', title: "Edit Pages"},
// active: false,
// command: {
// run: function (editor) {
// if(editPanel == null){
// const editMenuDiv = document.createElement('div')
// editMenuDiv.innerHTML = `
// <div id="your-content">
// Input: <input/>
// <button>Button</button>
// <!-- eg. bind a click event on button and do something with GrapesJS API -->
// </div>
// `
// const panels = pn.getPanel('views-container')
// panels.set('appendContent', editMenuDiv).trigger('change:appendContent')
// editPanel = editMenuDiv
// }
// editPanel.style.display = 'block'
// },
// stop: function (editor) {
// if(editPanel != null){
// editPanel.style.display = 'none'
// }
// }
//
// }
// })
// assetManager.open({
// select(asset, complete) {
// const selected = editor.getSelected();
// if (selected && selected.is('image')) {
// selected.addAttributes({ src: asset.getSrc() });
// // The default AssetManager UI will trigger `select(asset, false)` on asset click
// // and `select(asset, true)` on double-click
// complete && assetManager.close();
// }
// }
// });
let panels = editor.Panels.getPanels()
//console.log(panels)
//panels.forEach(item => console.log(item.get('id')))
console.log("editor",editor)
// editor.DomComponents.addType('input', {
// isComponent: el => el.tagName == 'H1',
// model: {
// defaults: {
// traits: [
// // Strings are automatically converted to text types
// 'name', // Same as: { type: 'text', name: 'name' }
// 'placeholder',
// {
// type: 'select', // Type of the trait
// label: 'Type', // The label you will see in Settings
// name: 'type', // The name of the attribute/property to use on component
// options: [
// {id: 'text', name: 'Text'},
// {id: 'email', name: 'Email'},
// {id: 'password', name: 'Password'},
// {id: 'number', name: 'Number'},
// ]
// }, {
// type: 'checkbox',
// name: 'required',
// }],
// // As by default, traits are binded to attributes, so to define
// // their initial value we can use attributes
// attributes: {type: 'text', required: true},
// },
// },
// });
const blockManager = editor.BlockManager;
blockManager.add('h1-block', {
label: '<h1>Heading 1</h1>',
content: '<h1>Put your title here</h1>',
category: 'Headlines',
attributes: {
title: 'Insert h1 block'
}
});
blockManager.add('h2-block', {
label: '<h2>Heading 2</h2>',
content: '<h2>Put your title here</h2>',
category: 'Headlines',
attributes: {
title: 'Insert h2 block'
}
});
blockManager.add('h3-block', {
label: '<h3>Heading 3</h3>',
content: '<h3>Put your title here</h3>',
category: 'Headlines',
attributes: {
title: 'Insert h3 block'
}
});
blockManager.add('h4-block', {
label: '<h4>Heading 4</h4>',
content: '<h4>Put your title here</h4>',
category: 'Headlines',
attributes: {
title: 'Insert h4 block'
}
});
blockManager.add('images-block', {
id: 'image',
label: 'Image',
media: `<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path d="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z" /></svg>`,
// Use `image` component
content: { type: 'image' },
// The component `image` is activatable (shows the Asset Manager).
// We want to activate it once dropped in the canvas.
activate: true,
// select: true, // Default with `activate: true`
});
const pageManager = editor.Pages;
console.log('pageManager', pageManager)
//pageManager.select('page-id');
// or by passing the page
// const somePage1 = pageManager.get('page-id2');
// pageManager.select(somePage1);
// const somePage2 = pageManager.get('page-id2');
// pageManager.select(somePage2);
//console.log(pageManager);
//
// const newPage = pageManager.add({
// id: 'new-page-id', // without an explicit ID, a random one will be created
// styles: `.my-class { color: red }`, // or a JSON of styles
// component: '<div class="my-class">My element</div>', // or a JSON of components
// });
// editor.Panels.addPanel({
// id: 'myNewPanel',
// visible : true,
// buttons : []
// });
//
// editor.Panels.addButton('myNewPanel',{
// id: 'myNewButton',
// className: 'someClass',
// command: 'someCommand',
// attributes: { title: 'Some title'},
// active: false,
// });
const pm = editor.Panels;
// Add undo/redo buttons
// editor.Panels.addButton('options', {
// id: 'undo',
// className: 'fa fa-undo',
// command: 'undo',
// attributes: { title: 'Undo' }
// });
// editor.Panels.addButton('options', {
// id: 'redo',
// className: 'fa fa-repeat',
// command: 'redo',
// attributes: { title: 'Redo' }
// });
pm.addButton("options", [{
editor.Panels.addButton("options", [{
id: "undo",
className: "fa fa-undo icon-undo",
command: function command(editor, sender) {
......@@ -581,25 +258,45 @@ export function startEditor(config) {
}
}]);
// var newPanel = panelManager.addPanel({
// id: 'myNewPanel',
// visible : true,
//
// });
editor.BlockManager.add('demo-container1', {
label: '<h1>C1</h1>',
content: `
<div style="border-color:red">
</div>
`,
category: 'demo',
attributes: {
title: 'Insert h1 block'
}
});
editor.BlockManager.add('demo-container2', {
label: '<h1>C2</h1>',
content: `
<div style="border-color:red">
</div>
`,
category: 'demo',
attributes: {
title: 'Insert h1 block'
}
});
editor.BlockManager.add('demo-content1', {
label: '<h1>CC1</h1>',
content: `
<p>INHALT1</p>
`,
category: 'demo',
attributes: {
title: 'Insert h1 block'
}
});
// var newButton = panelManager.addButton('views',{
// id: 'myNewButton',
// className: 'someClass',
// command: 'someCommand',
// attributes: { title: 'Some title'},
// active: true,
// });
// var p = editor.Panels.getPanel( 'views' );
// p.set( 'resizable', true );
console.log(editor)
// editor.Panels.render();
});
}
......@@ -18,7 +18,7 @@ html {
}
.gjs-pn-command {
width: calc( 100% - 300px )
width: calc( 100% - 300px )
}
.gjs-pn-views {
......@@ -26,7 +26,9 @@ html {
}
.gjs-pn-views-container {
width: 300px;
width: 288px;
padding: 0;
margin: 0;
}
.gjs-pn-options {
......
No preview for this file type
import grapesjsTable from 'grapesjs-table';
import grapesjsPluginExport from 'grapesjs-plugin-export';
//import grapesjsProjectManager from "grapesjs-project-manager"
const component = editor.getSelected();
// Get the View
const view = component.getView();
// Get the DOM element
const el = component.getEl();
function updateContent(model, prev, next) {
console.log(model, prev, next);
let html = `
<head>
<style>${editor.getCss()}</style>
<style>${editor.getJs()}</style>
</head>
${editor.getHtml()}`;
console.log('html', html)
}
//https://grapesjs.com/docs/api/components.html#available-events
editor.on('component:add', updateContent);
editor.on('component:remove', updateContent);
editor.on('component:clone', updateContent);
editor.on('component:styleUpdate', updateContent);
pn.addButton('options', {
attributes: {
title: 'Script Enable'
},
className: 'fa fa-file-code-o',
command: {
run: function (editor) {
console.log("----> Scripts Enabled <----" + editor.getConfig().allowScripts);
editor.getConfig().allowScripts = 1;
},
stop: function (editor) {
console.log("----> Scripts Disabled <----" + editor.getConfig().allowScripts);
editor.getConfig().allowScripts = 0;
},
},
id: 'script-enable'
});
assetManager.open({
select(asset, complete) {
const selected = editor.getSelected();
if (selected && selected.is('image')) {
selected.addAttributes({src: asset.getSrc()});
// The default AssetManager UI will trigger `select(asset, false)` on asset click
// and `select(asset, true)` on double-click
complete && assetManager.close();
}
}
});
setTimeout(() => {
const panels2 = pn.getPanel('views-container')
console.log(panels2)
}, 600)
panels2.set('appendContent', editMenuDiv).trigger('change:appendContent')
editPanel = editMenuDiv
let editPanel = null
pn.addButton('views', {
id: 'editMenu',
attributes: {class: 'fa fa-file-text-o', title: "Edit Pages"},
active: false,
command: {
run: function (editor) {
if (editPanel == null) {
const editMenuDiv = document.createElement('div')
editMenuDiv.innerHTML = `
<div id="your-content">
Input: <input/>
<button>Button</button>
<!-- eg. bind a click event on button and do something with GrapesJS API -->
</div>
`
const panels = pn.getPanel('views-container')
panels.set('appendContent', editMenuDiv).trigger('change:appendContent')
editPanel = editMenuDiv
}
editPanel.style.display = 'block'
},
stop: function (editor) {
if (editPanel != null) {
editPanel.style.display = 'none'
}
}
}
})
console.log(panels)
panels.forEach(item => console.log(item.get('id')))
console.log("editor", editor)
editor.DomComponents.addType('input', {
isComponent: el => el.tagName == 'H1',
model: {
defaults: {
traits: [
// Strings are automatically converted to text types
'name', // Same as: { type: 'text', name: 'name' }
'placeholder',
{
type: 'select', // Type of the trait
label: 'Type', // The label you will see in Settings
name: 'type', // The name of the attribute/property to use on component
options: [
{id: 'text', name: 'Text'},
{id: 'email', name: 'Email'},
{id: 'password', name: 'Password'},
{id: 'number', name: 'Number'},
]
}, {
type: 'checkbox',
name: 'required',
}],
// As by default, traits are binded to attributes, so to define
// their initial value we can use attributes
attributes: {type: 'text', required: true},
},
},
});
pnm.addButton('options', [{
active: true,
className: 'fa fa-terminal',
command: function command(editor, sender) {
sender.set("active", 0);
editor.UndoManager.undo(1);
},
attributes: {
title: 'Allow Scripts'
}
}]);
//Add undo/redo buttons
editor.Panels.addButton('options', {
id: 'undo',
className: 'fa fa-undo',
command: 'undo',
attributes: {title: 'Undo'}
});
editor.Panels.addButton('options', {
id: 'redo',
className: 'fa fa-repeat',
command: 'redo',
attributes: {title: 'Redo'}
});
var newPanel = panelManager.addPanel({
id: 'myNewPanel',
visible: true,
});
var newButton = panelManager.addButton('views', {
id: 'myNewButton',
className: 'someClass',
command: 'someCommand',
attributes: {title: 'Some title'},
active: true,
});
var p = editor.Panels.getPanel('views');
p.set('resizable', true);
editor.Panels.render();
pageManager.select('page-id');
or
by
passing
the
page
const somePage1 = pageManager.get('page-id2');
pageManager.select(somePage1);
const somePage2 = pageManager.get('page-id2');
pageManager.select(somePage2);
console.log(pageManager);
const newPage = pageManager.add({
id: 'new-page-id', // without an explicit ID, a random one will be created
styles: `.my-class { color: red }`, // or a JSON of styles
component: '<div class="my-class">My element</div>', // or a JSON of components
});
editor.Panels.addPanel({
id: 'myNewPanel',
visible: true,
buttons: []
});
editor.Panels.addButton('myNewPanel', {
id: 'myNewButton',
className: 'someClass',
command: 'someCommand',
attributes: {title: 'Some title'},
active: false,
});
const viewContainerPanel = pn.getPanel('views')
let panels = editor.Panels.getPanels()
const blockManager = editor.BlockManager;
blockManager.add('h1-block', {
label: '<h1>Heading 1</h1>',
content: '<h1>Put your title here</h1><script>setInterval(()=>console.log(1),1000)</script>',
category: 'Headlines',
attributes: {
title: 'Insert h1 block'
}
});
const assetManager = editor.AssetManager;
const storageManager = editor.StorageManager;
let a = {
assetManager: {
upload: config?.assets?.url,
uploadName: 'files',
autoAdd: true,
dropzone: true,
//
// assets? : Array < object >;
// noAssets? : string;
// stylePrefix? : string;
// upload? : boolean;
// uploadName? : string;
// headers? : object;
// params? : object;
// credentials? : RequestCredentials;
// multiUpload? : boolean;
// autoAdd? : boolean;
// uploadText? : string;
// addBtnText? : string;
// customFetch? : Function;
// uploadFile? : Function;
// embedAsBase64? : boolean;
// handleAdd? : Function;
// dropzone? : boolean;
// openAssetsOnDrop? : number;
// dropzoneContent? : string;
// modalTitle? : string;
// inputPlaceholder? : string;
params: {
_token: "pCYrSwjuiV0t5NVtZpQDY41Gn5lNUwo3it1FIkAj"
},
},
}
blockManager.add('h2-block', {
label: '<h2>Heading 2</h2>',
content: '<h2>Put your title here</h2>',
category: 'Headlines',
attributes: {
title: 'Insert h2 block'
}
});
blockManager.add('h3-block', {
label: '<h3>Heading 3</h3>',
content: '<h3>Put your title here</h3>',
category: 'Headlines',
attributes: {
title: 'Insert h3 block'
}
});
blockManager.add('h4-block', {
label: '<h4>Heading 4</h4>',
content: '<h4>Put your title here</h4>',
category: 'Headlines',
attributes: {
title: 'Insert h4 block'
}
});
blockManager.add('images-block', {
id: 'image',
label: 'Image',
media: `<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path d="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z" /></svg>`,
// Use `image` component
content: {type: 'image'},
// The component `image` is activatable (shows the Asset Manager).
// We want to activate it once dropped in the canvas.
activate: true,
// select: true, // Default with `activate: true`
});
// storageManager: true,
// {
// type: 'remote',
// stepsBeforeSave: 10,
// urlStore: config?.editor?.storage?.storeUrl,
// urlLoad: config?.editor?.storage?.loadUrl,
// params: {}, // Custom parameters to pass with the remote storage request, eg. CSRF token
// headers: {}, // Custom headers for the remote storage request
// // },
// pageManager: {
// // pages: [
// // {
// // id: 'page-id1',
// // styles: `.my-class { color: red }`, // or a JSON of styles
// // component: '<div class="my-class">My element1</div>', // or a JSON of components
// // },
// // {
// // id: 'page-id2',
// // styles: `.my-class { color: blue }`, // or a JSON of styles
// // component: '<div class="my-class">My element2</div>', // or a JSON of components
// // }
// // ],
// },
// For custom parameters/headers on requests
//params: { _some_token: '....' },
//headers: { Authorization: 'Basic ...' },
// the URIs below can be the same depending on your API design
// urlStore: config?.editor?.storage?.storeUrl,
// urlLoad: config?.editor?.storage?.loadUrl,
// urlDelete: config?.editor?.storage?.deleteUrl,
//params: { _some_token: '...' },
//headers: { Authorization: 'Basic ...' }
// uuidInPath:false
// storageManager: {
// type: 'indexeddb',
// // ...
// },
// [grapesjsTable]: {
// /* options */
// },
// [grapesjsPluginExport]: {
//
// filenamePfx: 'dummy',
// filename: 'temp',
// addExportBtn: 1,
// btnLabel: 'Export as ZIP',
//
// root(ed) {
// const all = ed.Pages.getAll();
// const pages = {};
// const css = {};
// all.map(page => {
// pages[(page.get('name') || page.id) + '.html'] = '<!doctype html>' +
// '<html lang="en">' +
// '<head>' +
// '<meta charset="utf-8">' +
// '<link rel="stylesheet" href="/css/style-' + page.id + '.css">' +
// '</head>' +
// '<body>' +
// page.getMainComponent().toHTML() +
// '</body>' +
// '</html>';
// css['style-' + page.id + '.css'] = editor.CodeManager.getCode(page.getMainComponent(), 'css')
// });
// return {
// css: {
// ...css
// },
// ...pages
// }
// }
// },
\ No newline at end of file