@silexlabs/silex 3.5.0 → 3.5.1-2

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.
Files changed (95) hide show
  1. package/.silex.js +0 -3
  2. package/dist/client/client/config.d.ts +8 -0
  3. package/dist/client/client/grapesjs/PublicationManager.d.ts +43 -0
  4. package/dist/client/client/grapesjs/cms/DataSource.d.ts +43 -0
  5. package/dist/client/client/grapesjs/cms/blocks.d.ts +2 -0
  6. package/dist/client/client/grapesjs/cms/buttons.d.ts +2 -0
  7. package/dist/client/client/grapesjs/cms/collection-pages.d.ts +4 -0
  8. package/dist/client/client/grapesjs/cms/config.d.ts +9 -0
  9. package/dist/client/client/grapesjs/cms/filters.d.ts +3 -0
  10. package/dist/client/client/grapesjs/cms/index.d.ts +44 -0
  11. package/dist/client/client/grapesjs/cms/liquid.d.ts +59 -0
  12. package/dist/client/client/grapesjs/cms/page-settings.d.ts +6 -0
  13. package/dist/client/client/grapesjs/cms/publication.d.ts +60 -0
  14. package/dist/client/client/grapesjs/cms/site-settings.d.ts +3 -0
  15. package/dist/client/client/grapesjs/cms/states.d.ts +8 -0
  16. package/dist/client/client/grapesjs/cms/traits.d.ts +8 -0
  17. package/dist/client/client/grapesjs/settings.d.ts +12 -3
  18. package/dist/client/client/grapesjs/view-buttons.d.ts +2 -1
  19. package/dist/client/client/utils.d.ts +1 -0
  20. package/dist/client/constants.d.ts +2 -1
  21. package/dist/client/css/admin.css +117 -19
  22. package/dist/client/index.html +2 -2
  23. package/dist/client/js/main.js +1974 -267
  24. package/dist/client/types.d.ts +3 -1
  25. package/dist/plugins/client/plugins/client/template.js +1 -1
  26. package/dist/plugins/client/plugins/client/template.js.map +1 -1
  27. package/dist/plugins/client/types.d.ts +3 -1
  28. package/dist/plugins/client/types.js +11 -8
  29. package/dist/plugins/client/types.js.map +1 -1
  30. package/dist/plugins/server/constants.d.ts +2 -1
  31. package/dist/plugins/server/constants.js +3 -2
  32. package/dist/plugins/server/constants.js.map +1 -1
  33. package/dist/plugins/server/plugins/server/FtpConnector.js +15 -20
  34. package/dist/plugins/server/plugins/server/FtpConnector.js.map +1 -1
  35. package/dist/plugins/server/plugins/server/GitlabConnector.js +34 -7
  36. package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -1
  37. package/dist/plugins/server/server/connectors/FsStorage.js +16 -20
  38. package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -1
  39. package/dist/plugins/server/server/utils/websiteDataSerialization.d.ts +4 -0
  40. package/dist/plugins/server/server/utils/websiteDataSerialization.js +21 -12
  41. package/dist/plugins/server/server/utils/websiteDataSerialization.js.map +1 -1
  42. package/dist/plugins/server/types.d.ts +3 -1
  43. package/dist/plugins/server/types.js +12 -9
  44. package/dist/plugins/server/types.js.map +1 -1
  45. package/dist/server/constants.js +3 -2
  46. package/dist/server/server/connectors/FsStorage.js +14 -18
  47. package/dist/server/server/utils/websiteDataSerialization.js +16 -11
  48. package/dist/server/types.js +6 -2
  49. package/package.json +16 -11
  50. package/src/css/_variables.scss +2 -1
  51. package/src/css/grapesjs-plugins.scss +31 -0
  52. package/src/css/grapesjs.scss +20 -0
  53. package/src/css/page-panel.scss +25 -6
  54. package/src/css/silex.scss +64 -5
  55. package/src/ts/client/config.ts +23 -0
  56. package/src/ts/client/grapesjs/PublicationManager.ts +159 -1
  57. package/src/ts/client/grapesjs/breadcrumbs.ts +3 -2
  58. package/src/ts/client/grapesjs/cms/DataSource.ts +333 -0
  59. package/src/ts/client/grapesjs/cms/blocks.ts +124 -0
  60. package/src/ts/client/grapesjs/cms/buttons.ts +163 -0
  61. package/src/ts/client/grapesjs/cms/collection-pages.ts +214 -0
  62. package/src/ts/client/grapesjs/cms/config.ts +47 -0
  63. package/src/ts/client/grapesjs/cms/filters.ts +53 -0
  64. package/src/ts/client/grapesjs/cms/index.ts +130 -0
  65. package/src/ts/client/grapesjs/cms/liquid.mock.ts +181 -0
  66. package/src/ts/client/grapesjs/cms/liquid.test.ts +239 -0
  67. package/src/ts/client/grapesjs/cms/liquid.ts +325 -0
  68. package/src/ts/client/grapesjs/cms/page-settings.ts +285 -0
  69. package/src/ts/client/grapesjs/cms/publication.test.ts +300 -0
  70. package/src/ts/client/grapesjs/cms/publication.ts +708 -0
  71. package/src/ts/client/grapesjs/cms/site-settings.ts +79 -0
  72. package/src/ts/client/grapesjs/cms/states.ts +125 -0
  73. package/src/ts/client/grapesjs/cms/traits.ts +95 -0
  74. package/src/ts/client/grapesjs/css-props.ts +15 -16
  75. package/src/ts/client/grapesjs/flex.ts +59 -39
  76. package/src/ts/client/grapesjs/img.ts +1 -1
  77. package/src/ts/client/grapesjs/index.ts +77 -4
  78. package/src/ts/client/grapesjs/internal-links.ts +4 -2
  79. package/src/ts/client/grapesjs/page-panel.ts +126 -11
  80. package/src/ts/client/grapesjs/sectors.ts +18 -10
  81. package/src/ts/client/grapesjs/semantic.ts +4 -0
  82. package/src/ts/client/grapesjs/settings.ts +252 -101
  83. package/src/ts/client/grapesjs/storage.ts +12 -3
  84. package/src/ts/client/grapesjs/view-buttons.ts +39 -3
  85. package/src/ts/client/utils.ts +15 -2
  86. package/src/ts/constants.ts +2 -1
  87. package/src/ts/plugins/client/template.ts +1 -1
  88. package/src/ts/plugins/server/FtpConnector.test.ts +1 -0
  89. package/src/ts/plugins/server/FtpConnector.ts +20 -23
  90. package/src/ts/plugins/server/GitlabConnector.ts +40 -10
  91. package/src/ts/server/connectors/FsStorage.test.ts +3 -2
  92. package/src/ts/server/connectors/FsStorage.ts +21 -23
  93. package/src/ts/server/utils/websiteDataSerialization.test.ts +45 -13
  94. package/src/ts/server/utils/websiteDataSerialization.ts +23 -14
  95. package/src/ts/types.ts +6 -2
@@ -15,7 +15,7 @@
15
15
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
  */
17
17
 
18
- import { Editor } from 'grapesjs'
18
+ import { Component, Editor, Page } from 'grapesjs'
19
19
  import {html, render} from 'lit-html'
20
20
  import {ref} from 'lit-html/directives/ref.js'
21
21
 
@@ -30,10 +30,10 @@ export const cmdSelectNextPage = 'pages:select-next'
30
30
  export const cmdSelectPrevPage = 'pages:select-prev'
31
31
  export const cmdSelectFirstPage = 'pages:select-first'
32
32
 
33
- function selectPage(editor, page) {
33
+ function selectPage(editor: Editor, page: Page) {
34
34
  editor.Pages.select(page)
35
35
  }
36
- function addPage(editor, config) {
36
+ function addPage(editor: Editor, config: { newPageName: string, cmdOpenNewPageDialog: string }) {
37
37
  const pages = editor.Pages.getAll()
38
38
  // Get a name
39
39
  let idx = 1
@@ -50,7 +50,7 @@ function addPage(editor, config) {
50
50
  editor.runCommand(config.cmdOpenNewPageDialog, {page})
51
51
  }
52
52
 
53
- function clonePage(editor, page) {
53
+ function clonePage(editor: Editor, page: Page) {
54
54
  const pages = editor.Pages.getAll()
55
55
  // Get a name
56
56
  let idx = 1
@@ -59,13 +59,27 @@ function clonePage(editor, page) {
59
59
  while(pages.find(p => p.getName() === pageName)) {
60
60
  pageName = `${newPageName} ${idx++}`
61
61
  }
62
- // Clone components
63
- const body = page.getMainComponent().clone()
64
- // Add page
62
+
63
+ // Clone components using Backbone approach
64
+ const sourceBody = page.getMainComponent()
65
+ const clonedComponents = sourceBody.clone()
66
+
67
+ // Get custom props but exclude frames (Backbone collection) using toJSON and delete
68
+ const customProps = { ...page.toJSON() }
69
+ delete customProps.frames
70
+ delete customProps.id
71
+ delete customProps._undo
72
+
73
+ // Create new page with custom props (but not frames collection)
65
74
  const newPage = editor.Pages.add({
75
+ ...customProps,
66
76
  name: pageName,
67
- component: body,
68
77
  })
78
+
79
+ // Reset components with cloned ones
80
+ const targetBody = newPage.getMainComponent()
81
+ targetBody.components().reset(clonedComponents.components().models)
82
+
69
83
  // Select the new page
70
84
  editor.Pages.select(newPage)
71
85
  }
@@ -142,15 +156,116 @@ function renderPages(editor, config) {
142
156
  e.stopPropagation()
143
157
  return editor.Pages.get(el.getAttribute('data-page-id'))
144
158
  }
159
+
160
+ // Drag and drop handlers
161
+ let draggedPage: Page | null = null
162
+ let draggedPageElement: HTMLElement | null = null
163
+
164
+ const handleDragStart = (e: DragEvent, page: Page) => {
165
+ e.stopPropagation()
166
+ draggedPage = page
167
+ // Find the parent page element
168
+ draggedPageElement = (e.target as HTMLElement).closest('.pages__page') as HTMLElement
169
+ if (e.dataTransfer && draggedPageElement) {
170
+ e.dataTransfer.effectAllowed = 'move'
171
+ e.dataTransfer.setData('text/html', draggedPageElement.innerHTML)
172
+ draggedPageElement.classList.add('pages__page-dragging')
173
+ }
174
+ }
175
+
176
+ const handleDragEnd = (e: DragEvent) => {
177
+ if (draggedPageElement) {
178
+ draggedPageElement.classList.remove('pages__page-dragging')
179
+ }
180
+ draggedPage = null
181
+ draggedPageElement = null
182
+ }
183
+
184
+ const handleDragOver = (e: DragEvent) => {
185
+ if (!draggedPage) return
186
+ e.preventDefault()
187
+ e.stopPropagation()
188
+ if (e.dataTransfer) {
189
+ e.dataTransfer.dropEffect = 'move'
190
+ }
191
+ return false
192
+ }
193
+
194
+ const handleDragEnter = (e: DragEvent, page: Page) => {
195
+ if (draggedPage && draggedPage !== page) {
196
+ e.preventDefault()
197
+ e.stopPropagation()
198
+ }
199
+ }
200
+
201
+ const handleDragLeave = (e: DragEvent) => {
202
+ // No-op: visual indicator removed
203
+ }
204
+
205
+ const handleDrop = (e: DragEvent, targetPage: Page) => {
206
+ e.stopPropagation()
207
+ e.preventDefault()
208
+
209
+ if (draggedPage && draggedPage !== targetPage) {
210
+ const pages = editor.Pages.getAll()
211
+ const fromIndex = pages.indexOf(draggedPage)
212
+ const toIndex = pages.indexOf(targetPage)
213
+
214
+ if (fromIndex !== -1 && toIndex !== -1 && fromIndex !== toIndex) {
215
+ // Access the internal Backbone collection
216
+ const pagesCollection = (editor.Pages as any).pages
217
+
218
+ // Assign temporary order attributes for sorting
219
+ pages.forEach((page, idx) => {
220
+ let newOrder = idx
221
+ if (idx === fromIndex) {
222
+ newOrder = toIndex
223
+ } else if (fromIndex < toIndex && idx > fromIndex && idx <= toIndex) {
224
+ newOrder = idx - 1
225
+ } else if (fromIndex > toIndex && idx >= toIndex && idx < fromIndex) {
226
+ newOrder = idx + 1
227
+ }
228
+ page.set('_tempOrder', newOrder, { silent: true })
229
+ })
230
+
231
+ // Sort the collection by the temporary order
232
+ const originalComparator = pagesCollection.comparator
233
+ pagesCollection.comparator = (page: Page) => page.get('_tempOrder')
234
+ pagesCollection.sort()
235
+ pagesCollection.comparator = originalComparator
236
+
237
+ // Clean up temporary attributes
238
+ pages.forEach(page => page.unset('_tempOrder', { silent: true }))
239
+ }
240
+ }
241
+
242
+ return false
243
+ }
244
+
145
245
  return html`<section class="pages">
146
246
  <main class="pages__main ${pages.length === 1 ? 'pages__single-page' : ''}">
147
247
  <div class="pages__list">
148
- ${ pages.map(page => {
149
- const name = page.getName() || page.attributes.type
248
+ ${ pages.map((page: Page, index: number) => {
249
+ const type = page.get('type') || index === 0 ? 'main' : 'Untitled Page'
250
+ const name = page.getName() || type
150
251
  // keep the same structure as the layers panel
151
252
  return html`
152
- <div class="pages__page ${selected === page ? 'pages__page-selected' : ''}" data-page-id=${page.id} @click=${e => selectPage(editor, getPageFromEvent(e))}>
253
+ <div
254
+ class="pages__page ${selected === page ? 'pages__page-selected' : ''}"
255
+ data-page-id=${page.id}
256
+ @click=${e => selectPage(editor, getPageFromEvent(e))}
257
+ @dragover=${handleDragOver}
258
+ @dragenter=${(e: DragEvent) => handleDragEnter(e, page)}
259
+ @dragleave=${handleDragLeave}
260
+ @drop=${(e: DragEvent) => handleDrop(e, page)}
261
+ >
153
262
  <div class="pages__page-name">
263
+ <i
264
+ class="pages__icon pages__drag-handle fa fa-grip-vertical"
265
+ draggable="true"
266
+ @dragstart=${(e: DragEvent) => handleDragStart(e, page)}
267
+ @dragend=${handleDragEnd}
268
+ ></i>
154
269
  ${ name }
155
270
  </div>
156
271
  <i class="pages__icon pages__remove-btn fa fa-trash" @click=${e => removePage(editor, getPageFromEvent(e))}></i>
@@ -43,17 +43,25 @@ export function registerSector(editor: Editor, config: SectorConfig, at?: number
43
43
  }
44
44
  })
45
45
 
46
- async function applyVisibility(comp: Component = editor.getSelected()) {
46
+ // Update visibility depending on selected component
47
+ let showSector = false
48
+ editor.on('component:selected', async (comp: Component) => {
49
+ if (!comp) return // No selection yet
47
50
  const shouldShow = await config.shouldShow(comp)
48
- if (sector.get('visible') !== shouldShow) {
49
- sector.off('change:visible', applyVisibility)
50
- sector.set('visible', shouldShow)
51
- sector.on('change:visible', applyVisibility)
52
- // sector.getProperties()
53
- // .forEach(p => p.set('visible', shouldShow))
51
+ showSector = shouldShow
52
+ sector.set('visible', shouldShow)
53
+ sector.getProperties().forEach(p => p.set('visible', shouldShow))
54
+ })
55
+
56
+ // Watch changes made by grapesjs and revert them if needed
57
+ function doubleCheck() {
58
+ if (sector.get('visible') !== showSector) {
59
+ sector.off('change:visible', doubleCheck)
60
+ sector.set('visible', showSector)
61
+ sector.getProperties().forEach(p => p.set('visible', showSector))
62
+ sector.on('change:visible', doubleCheck)
54
63
  }
55
64
  }
56
-
57
- sector.on('change:visible', applyVisibility)
58
- editor.on('component:selected', comp => applyVisibility(comp))
65
+ sector.on('change:visible', doubleCheck)
59
66
  }
67
+
@@ -39,6 +39,10 @@ const tagCategories = [
39
39
  label: 'Content grouping',
40
40
  tags: ['ADDRESS', 'BLOCKQUOTE', 'PRE'],
41
41
  },
42
+ {
43
+ label: 'Lists',
44
+ tags: ['UL', 'OL', 'LI'],
45
+ },
42
46
  {
43
47
  label: 'Interactive/form',
44
48
  tags: ['BUTTON', 'LABEL', 'DETAILS', 'SUMMARY'],