@silexlabs/silex 3.0.0-alpha.147 → 3.0.0-alpha.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ export declare enum ClientEvent {
4
4
  GRAPESJS_START = "silex:grapesjs:start",
5
5
  GRAPESJS_END = "silex:grapesjs:end",
6
6
  PUBLISH_START = "silex:publish:start",
7
+ PUBLISH_PAGE = "silex:publish:page",
7
8
  PUBLISH_DATA = "silex:publish:data",
8
9
  PUBLISH_END = "silex:publish:end",
9
10
  PUBLISH_ERROR = "silex:publish:error",
@@ -21,8 +21,9 @@ export var ClientEvent;
21
21
  ClientEvent["STARTUP_END"] = "silex:startup:end";
22
22
  ClientEvent["GRAPESJS_START"] = "silex:grapesjs:start";
23
23
  ClientEvent["GRAPESJS_END"] = "silex:grapesjs:end";
24
- // Sent on the editor object
24
+ // Sent on GrapesJs editor object (returned by silex.getEditor())
25
25
  ClientEvent["PUBLISH_START"] = "silex:publish:start";
26
+ ClientEvent["PUBLISH_PAGE"] = "silex:publish:page";
26
27
  ClientEvent["PUBLISH_DATA"] = "silex:publish:data";
27
28
  ClientEvent["PUBLISH_END"] = "silex:publish:end";
28
29
  ClientEvent["PUBLISH_ERROR"] = "silex:publish:error";
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/ts/client/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAN,IAAY,WAqBX;AArBD,WAAY,WAAW;IACrB,4BAA4B;IAC5B,oDAAqC,CAAA;IACrC,gDAAiC,CAAA;IACjC,sDAAuC,CAAA;IACvC,kDAAmC,CAAA;IAEnC,4BAA4B;IAC5B,oDAAqC,CAAA;IACrC,kDAAmC,CAAA;IACnC,gDAAiC,CAAA;IACjC,oDAAqC,CAAA;IACrC,gEAAiD,CAAA;IACjD,4DAA6C,CAAA;IAC7C,wDAAyC,CAAA;IACzC,4CAA6B,CAAA;IAC7B,oDAAqC,CAAA;IACrC,sDAAuC,CAAA;IACvC,gEAAiD,CAAA;IACjD,4DAA6C,CAAA;IAC7C,wEAAyD,CAAA;AAC3D,CAAC,EArBW,WAAW,KAAX,WAAW,QAqBtB"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/ts/client/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAN,IAAY,WAsBX;AAtBD,WAAY,WAAW;IACrB,4BAA4B;IAC5B,oDAAqC,CAAA;IACrC,gDAAiC,CAAA;IACjC,sDAAuC,CAAA;IACvC,kDAAmC,CAAA;IAEnC,iEAAiE;IACjE,oDAAqC,CAAA;IACrC,kDAAmC,CAAA;IACnC,kDAAmC,CAAA;IACnC,gDAAiC,CAAA;IACjC,oDAAqC,CAAA;IACrC,gEAAiD,CAAA;IACjD,4DAA6C,CAAA;IAC7C,wDAAyC,CAAA;IACzC,4CAA6B,CAAA;IAC7B,oDAAqC,CAAA;IACrC,sDAAuC,CAAA;IACvC,gEAAiD,CAAA;IACjD,4DAA6C,CAAA;IAC7C,wEAAyD,CAAA;AAC3D,CAAC,EAtBW,WAAW,KAAX,WAAW,QAsBtB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@silexlabs/silex",
3
3
  "description": "Free and easy website builder for everyone.",
4
- "version": "3.0.0-alpha.147",
4
+ "version": "3.0.0-alpha.149",
5
5
  "version:backwardcompat": "3.0.0",
6
6
  "author": {
7
7
  "name": "Alex Hoyau",
@@ -79,7 +79,7 @@
79
79
  "dev": "run-p watch start:debug start:http-server",
80
80
  "watch": "npm-watch",
81
81
  "start": "node dist/server/server/",
82
- "start:debug": "cross-env SILEX_FS_ROOT=`pwd`/.silex SILEX_DEBUG=true SILEX_CLIENT_CONFIG=examples/client-config-transformers.js nodemon --watch dist/server dist/server/server/",
82
+ "start:debug": "cross-env SILEX_FS_ROOT=`pwd`/silex SILEX_DEBUG=true SILEX_CLIENT_CONFIG=examples/client-config-transformers.js nodemon --watch dist/server dist/server/server/",
83
83
  "start:http-server": "http-server silex/hosting",
84
84
  "prepublishOnly": "$npm_execpath run lint && $npm_execpath test && $npm_execpath run build",
85
85
  "preversion": "$npm_execpath run prepublishOnly",
@@ -101,32 +101,32 @@
101
101
  "test:watch": "$npm_execpath test -- --watch"
102
102
  },
103
103
  "dependencies": {
104
- "@fontsource/ubuntu": "^5.0.8",
105
- "@fortawesome/fontawesome-free": "6.4.2",
104
+ "@fontsource/ubuntu": "^5.0.12",
105
+ "@fortawesome/fontawesome-free": "6.5.1",
106
106
  "@silexlabs/grapesjs-filter-styles": "^1.0.0",
107
- "@silexlabs/grapesjs-fonts": "^1.0.15",
107
+ "@silexlabs/grapesjs-fonts": "^1.0.16",
108
108
  "@silexlabs/grapesjs-loading": "1.0.9",
109
109
  "@silexlabs/grapesjs-storage-rate-limit": "^1.0.8",
110
- "@silexlabs/grapesjs-symbols": "1.0.38",
110
+ "@silexlabs/grapesjs-symbols": "1.0.39",
111
111
  "@silexlabs/grapesjs-ui-suggest-classes": "1.0.23",
112
112
  "@silexlabs/silex-plugins": "1.0.10",
113
- "@types/archiver": "^6.0.1",
114
- "adm-zip": "0.5.10",
115
- "archiver": "^6.0.1",
116
- "basic-ftp": "^5.0.3",
113
+ "@types/archiver": "^6.0.2",
114
+ "adm-zip": "0.5.12",
115
+ "archiver": "^7.0.1",
116
+ "basic-ftp": "^5.0.5",
117
117
  "body-parser": "1.20.2",
118
118
  "cli": "1.0.1",
119
119
  "compression": "1.7.4",
120
120
  "cookie-parser": "1.4.6",
121
- "cookie-session": "2.0.0",
121
+ "cookie-session": "2.1.0",
122
122
  "cors": "2.8.5",
123
123
  "cross-env": "7.0.3",
124
124
  "crypto": "^1.0.1",
125
- "dotenv": "^16.3.1",
125
+ "dotenv": "^16.4.5",
126
126
  "express": "4.18.2",
127
127
  "express-force-ssl": "0.3.2",
128
128
  "formidable": "3.5.1",
129
- "fs-extra": "^11.1.1",
129
+ "fs-extra": "^11.2.0",
130
130
  "grapesjs": "0.21.7",
131
131
  "grapesjs-blocks-basic": "1.0.2",
132
132
  "grapesjs-custom-code": "1.0.2",
@@ -135,14 +135,14 @@
135
135
  "grapesjs-style-border": "1.0.4",
136
136
  "grapesjs-style-filter": "^1.0.2",
137
137
  "html-minifier": "^4.0.0",
138
- "lit-html": "3.0.2",
138
+ "lit-html": "3.1.2",
139
139
  "mkdirp": "3.0.1",
140
140
  "node_modules-path": "2.0.7",
141
141
  "node-fetch": "2.6.9",
142
142
  "normalize.css": "8.0.1",
143
143
  "object-path": "0.11.8",
144
144
  "promise-sequential": "1.1.1",
145
- "sass": "1.69.5",
145
+ "sass": "1.72.0",
146
146
  "serve-static": "1.15.0",
147
147
  "uuid": "^9.0.1"
148
148
  },
@@ -152,13 +152,14 @@
152
152
  "@types/node": "20.9.0",
153
153
  "@typescript-eslint/eslint-plugin": "6.10.0",
154
154
  "@typescript-eslint/parser": "6.10.0",
155
- "css-loader": "6.8.1",
155
+ "css-loader": "6.10.0",
156
156
  "eslint": "8.53.0",
157
157
  "file-loader": "6.2.0",
158
+ "http-server": "^14.1.1",
158
159
  "jest": "29.7.0",
159
160
  "jest-environment-jsdom": "29.7.0",
160
161
  "livereload": "0.9.3",
161
- "nodemon": "3.0.1",
162
+ "nodemon": "3.1.0",
162
163
  "npm-run-all": "4.1.5",
163
164
  "npm-watch": "0.11.0",
164
165
  "pug-cli": "1.0.0-alpha6",
@@ -17,23 +17,24 @@
17
17
 
18
18
  export enum ClientEvent {
19
19
  // Sent on the config object
20
- STARTUP_START = 'silex:startup:start',
21
- STARTUP_END = 'silex:startup:end',
22
- GRAPESJS_START = 'silex:grapesjs:start',
23
- GRAPESJS_END = 'silex:grapesjs:end',
20
+ STARTUP_START = 'silex:startup:start', /* Loading is over and Silex is starting */
21
+ STARTUP_END = 'silex:startup:end', /* Silex is ready to be used */
22
+ GRAPESJS_START = 'silex:grapesjs:start', /* GrapesJS is about to be initialized, it is time to edit config.grapesJsConfig */
23
+ GRAPESJS_END = 'silex:grapesjs:end', /* GrapesJS is ready to be used, `editor` is passed as an argument */
24
24
 
25
- // Sent on the editor object
26
- PUBLISH_START = 'silex:publish:start',
27
- PUBLISH_DATA = 'silex:publish:data',
28
- PUBLISH_END = 'silex:publish:end',
29
- PUBLISH_ERROR = 'silex:publish:error',
25
+ // Sent on GrapesJs editor object (returned by silex.getEditor())
26
+ PUBLISH_START = 'silex:publish:start', /* Publication starts, you can read+write {projectData, siteSettings} */
27
+ PUBLISH_PAGE = 'silex:publish:page', /* Publication of a page, read+write { siteSettings, pageSettings, page } */
28
+ PUBLISH_DATA = 'silex:publish:data', /* Just before we send the published data to the server, read+write all publication data, check PublicationData type in types.ts */
29
+ PUBLISH_END = 'silex:publish:end', /* Publication is over, the argument is the publication result with {success: boolean, message: string} */
30
+ PUBLISH_ERROR = 'silex:publish:error', /* Publication failed, the argument is the publication result with {success: boolean, message: string} */
30
31
  PUBLISH_LOGIN_START = 'silex:publish:login:start',
31
32
  PUBLISH_LOGIN_END = 'silex:publish:login:end',
32
33
  ASSET_WRITE_END = 'silex:asset:write:end',
33
34
  WRITE_END = 'silex:write:end',
34
- SETTINGS_OPEN = 'silex:settings:open',
35
- SETTINGS_CLOSE = 'silex:settings:close',
36
- SETTINGS_SAVE_START = 'silex:settings:save:start',
37
- SETTINGS_SAVE_END = 'silex:settings:save:end',
38
- SETTINGS_SECTION_CHANGE = 'silex:settings:section-change',
35
+ SETTINGS_OPEN = 'silex:settings:open', /* The settings dialog is opened */
36
+ SETTINGS_CLOSE = 'silex:settings:close', /* The settings dialog is closed */
37
+ SETTINGS_SAVE_START = 'silex:settings:save:start', /* The settings dialog is closed and the settings are about to be saved */
38
+ SETTINGS_SAVE_END = 'silex:settings:save:end', /* The settings dialog is closed and the settings are saved */
39
+ SETTINGS_SECTION_CHANGE = 'silex:settings:section-change', /* The user clicked on a section in the settings dialog */
39
40
  }
@@ -212,12 +212,10 @@ export class PublicationManager {
212
212
  }
213
213
  }
214
214
 
215
- async getPublicationData(): Promise<PublicationData> {
215
+ async getPublicationData(projectData, siteSettings): Promise<PublicationData> {
216
216
  // Data to publish
217
217
  // See assetUrl.ts which is a default transformer, always present
218
218
  this.setPublicationTransformers()
219
- const projectData = this.editor.getProjectData() as WebsiteData
220
- const siteSettings = this.editor.getModel().get('settings') as WebsiteSettings
221
219
  // Build the files structure
222
220
  const files: ClientSideFile[] = (await this.getHtmlFiles(siteSettings))
223
221
  .flatMap(file => ([{
@@ -280,7 +278,10 @@ export class PublicationManager {
280
278
  this.status = PublicationStatus.STATUS_PENDING
281
279
  this.job = null
282
280
  this.dialog && this.dialog.displayPending(this.job, this.status)
283
- this.editor.trigger(ClientEvent.PUBLISH_START)
281
+ // Get the data to publish, clone the objects because plugins can change it
282
+ const projectData = { ...this.editor.getProjectData() as WebsiteData }
283
+ const siteSettings = { ...this.editor.getModel().get('settings') as WebsiteSettings }
284
+ this.editor.trigger(ClientEvent.PUBLISH_START, {projectData, siteSettings})
284
285
  // User and where to publish
285
286
  const storageUser = this.editor.getModel().get('user') as ConnectorUser
286
287
  if(!storageUser) throw new Error('User not logged in to a storage connector')
@@ -288,7 +289,7 @@ export class PublicationManager {
288
289
  const websiteId = this.options.websiteId
289
290
  const storageId = storageUser.storage.connectorId
290
291
  // Get the data to publish
291
- const data = await this.getPublicationData()
292
+ const data = await this.getPublicationData(projectData, siteSettings)
292
293
  // Use the publication API
293
294
  const [url, job] = await publish({
294
295
  websiteId,
@@ -299,12 +300,6 @@ export class PublicationManager {
299
300
  })
300
301
  this.job = job
301
302
  this.status = jobStatusToPublicationStatus(this.job.status)
302
- // Save the publication settings
303
- // Useless because the url is useful after publish only
304
- //if(this.settings.url !== url) {
305
- // this.settings.url = url
306
- // await this.editor.store(null)
307
- //}
308
303
  this.trackProgress()
309
304
  } catch (e) {
310
305
  console.error('publish error', e)
@@ -324,15 +319,18 @@ export class PublicationManager {
324
319
 
325
320
  async getHtmlFiles(siteSettings: WebsiteSettings): Promise<WebsiteFile[]> {
326
321
  return Promise.all(this.editor.Pages.getAll().map(async page => {
327
- const pageSettings = page.get('settings') as WebsiteSettings
322
+ // Clone the settings because plugins can change them
323
+ siteSettings = { ...siteSettings }
324
+ const pageSettings = { ...page.get('settings') as WebsiteSettings }
325
+ // Utility function to get a setting from the page or the site settings
328
326
  function getSetting(name) {
329
327
  return (pageSettings || {})[name] || (siteSettings || [])[name] || ''
330
328
  }
331
- const component = page.getMainComponent()
332
329
 
333
330
  // Get the content from GrapesJS
334
- const cssContent = this.editor.getCss({ component })
335
- const htmlContent = this.editor.getHtml({ component })
331
+ const body = page.getMainComponent()
332
+ const cssContent = this.editor.getCss({ component: body })
333
+ const htmlContent = this.editor.getHtml({ component: body })
336
334
 
337
335
  // Transform the file paths
338
336
  const slug = getPageSlug(page.get('name'))
@@ -341,6 +339,14 @@ export class PublicationManager {
341
339
  const cssPermalink = transformPermalink(this.editor, cssInitialPath, ClientSideFileType.CSS, Initiator.HTML)
342
340
  const cssPath = transformPath(this.editor, cssInitialPath, ClientSideFileType.CSS)
343
341
  const htmlPath = transformPath(this.editor, htmlInitialPath, ClientSideFileType.HTML)
342
+
343
+ // Let plugins transform the data
344
+ this.editor.trigger(ClientEvent.PUBLISH_PAGE, { page, siteSettings, pageSettings })
345
+
346
+ // Useful data for HTML result
347
+ const title = getSetting('title')
348
+ const favicon = getSetting('favicon')
349
+ // Return the HTML file
344
350
  return {
345
351
  html: `<!DOCTYPE html>
346
352
  <html lang="${getSetting('lang')}">
@@ -349,9 +355,10 @@ export class PublicationManager {
349
355
  <link rel="stylesheet" href="${cssPermalink}" />
350
356
  ${siteSettings?.head || ''}
351
357
  ${pageSettings?.head || ''}
352
- <title>${getSetting('title')}</title>
353
- <link rel="icon" href="${getSetting('favicon')}" />
358
+ ${ title ? `<title>${ title }</title>` : '' }
359
+ ${ favicon ? `<link rel="icon" href="${favicon}" />` : '' }
354
360
  ${['description', 'og:title', 'og:description', 'og:image']
361
+ .filter(prop => !!getSetting(prop))
355
362
  .map(prop => `<meta name="${prop}" property="${prop}" content="${getSetting(prop)}"/>`)
356
363
  .join('\n')
357
364
  }
@@ -52,12 +52,13 @@ function clonePage(editor, page) {
52
52
  while(pages.find(p => p.getName() === pageName)) {
53
53
  pageName = `${newPageName} ${idx++}`
54
54
  }
55
- // Add page
56
- const newPage = editor.Pages.add({ name: pageName })
57
55
  // Clone components
58
- const clones = page.getMainComponent().components().map(c => c.clone())
59
- newPage.getMainComponent()
60
- .components(clones)
56
+ const body = page.getMainComponent().clone()
57
+ // Add page
58
+ const newPage = editor.Pages.add({
59
+ name: pageName,
60
+ component: body,
61
+ })
61
62
  // Select the new page
62
63
  editor.Pages.select(newPage)
63
64
  }
@@ -99,10 +99,9 @@ export const settingsDialog = (editor, opts) => {
99
99
  editor.on('canvas:frame:load', () => {
100
100
  updateDom(editor)
101
101
  })
102
+ // When the page changes, update the dom
102
103
  editor.on('page', (e) => {
103
- editor.Canvas.getFrameEl().addEventListener('load', () => {
104
- updateDom(editor)
105
- })
104
+ updateDom(editor)
106
105
  })
107
106
  headEditor = editor.CodeManager.createViewer({
108
107
  readOnly: false,
@@ -99,5 +99,7 @@ export async function start(options = {}): Promise<void> {
99
99
  document.querySelector('#gjs').classList.remove('silex-dialog-hide')
100
100
  config.emit(ClientEvent.STARTUP_END, { editor, config })
101
101
  }, 100)
102
+ const um = editor.UndoManager
103
+ um.clear()
102
104
  }
103
105
  }