@silexlabs/silex 3.0.0-alpha.100
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.
- package/.env.default +19 -0
- package/.silex.js +37 -0
- package/LICENSE +661 -0
- package/README.md +96 -0
- package/dist/client/client/api.d.ts +85 -0
- package/dist/client/client/assetUrl.d.ts +51 -0
- package/dist/client/client/config.d.ts +58 -0
- package/dist/client/client/events.d.ts +14 -0
- package/dist/client/client/expose.d.ts +8 -0
- package/dist/client/client/grapesjs/LoginDialog.d.ts +15 -0
- package/dist/client/client/grapesjs/PublicationManager.d.ts +72 -0
- package/dist/client/client/grapesjs/PublicationUi.d.ts +62 -0
- package/dist/client/client/grapesjs/blocks.d.ts +1 -0
- package/dist/client/client/grapesjs/breadcrumbs.d.ts +1 -0
- package/dist/client/client/grapesjs/footer.d.ts +2 -0
- package/dist/client/client/grapesjs/index.d.ts +5 -0
- package/dist/client/client/grapesjs/internal-links.d.ts +1 -0
- package/dist/client/client/grapesjs/new-page-dialog.d.ts +2 -0
- package/dist/client/client/grapesjs/openImport.d.ts +9 -0
- package/dist/client/client/grapesjs/page-panel.d.ts +3 -0
- package/dist/client/client/grapesjs/project-bar.d.ts +1 -0
- package/dist/client/client/grapesjs/rich-text.d.ts +1 -0
- package/dist/client/client/grapesjs/semantic.d.ts +1 -0
- package/dist/client/client/grapesjs/settings.d.ts +2 -0
- package/dist/client/client/grapesjs/storage.d.ts +1 -0
- package/dist/client/client/grapesjs/symbolDialogs.d.ts +3 -0
- package/dist/client/client/index.d.ts +5 -0
- package/dist/client/client/publication-transformers.d.ts +41 -0
- package/dist/client/client/utils.d.ts +2 -0
- package/dist/client/constants.d.ts +29 -0
- package/dist/client/css/admin.css +4491 -0
- package/dist/client/index.html +9 -0
- package/dist/client/js/main.js +321 -0
- package/dist/client/js/main.js.LICENSE.txt +24 -0
- package/dist/client/page.d.ts +2 -0
- package/dist/client/types.d.ts +334 -0
- package/dist/plugins/client/client/api.d.ts +85 -0
- package/dist/plugins/client/client/api.js +114 -0
- package/dist/plugins/client/client/api.js.map +1 -0
- package/dist/plugins/client/client/assetUrl.d.ts +51 -0
- package/dist/plugins/client/client/assetUrl.js +224 -0
- package/dist/plugins/client/client/assetUrl.js.map +1 -0
- package/dist/plugins/client/client/config.d.ts +58 -0
- package/dist/plugins/client/client/config.js +90 -0
- package/dist/plugins/client/client/config.js.map +1 -0
- package/dist/plugins/client/client/events.d.ts +14 -0
- package/dist/plugins/client/client/events.js +34 -0
- package/dist/plugins/client/client/events.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/LoginDialog.d.ts +15 -0
- package/dist/plugins/client/client/grapesjs/LoginDialog.js +195 -0
- package/dist/plugins/client/client/grapesjs/LoginDialog.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/PublicationManager.d.ts +72 -0
- package/dist/plugins/client/client/grapesjs/PublicationManager.js +356 -0
- package/dist/plugins/client/client/grapesjs/PublicationManager.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/PublicationUi.d.ts +62 -0
- package/dist/plugins/client/client/grapesjs/PublicationUi.js +336 -0
- package/dist/plugins/client/client/grapesjs/PublicationUi.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/blocks.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/blocks.js +37 -0
- package/dist/plugins/client/client/grapesjs/blocks.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/breadcrumbs.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/breadcrumbs.js +75 -0
- package/dist/plugins/client/client/grapesjs/breadcrumbs.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/footer.d.ts +2 -0
- package/dist/plugins/client/client/grapesjs/footer.js +28 -0
- package/dist/plugins/client/client/grapesjs/footer.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/index.d.ts +5 -0
- package/dist/plugins/client/client/grapesjs/index.js +313 -0
- package/dist/plugins/client/client/grapesjs/index.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/internal-links.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/internal-links.js +219 -0
- package/dist/plugins/client/client/grapesjs/internal-links.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/new-page-dialog.d.ts +2 -0
- package/dist/plugins/client/client/grapesjs/new-page-dialog.js +83 -0
- package/dist/plugins/client/client/grapesjs/new-page-dialog.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/openImport.d.ts +9 -0
- package/dist/plugins/client/client/grapesjs/openImport.js +74 -0
- package/dist/plugins/client/client/grapesjs/openImport.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/page-panel.d.ts +3 -0
- package/dist/plugins/client/client/grapesjs/page-panel.js +113 -0
- package/dist/plugins/client/client/grapesjs/page-panel.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/project-bar.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/project-bar.js +104 -0
- package/dist/plugins/client/client/grapesjs/project-bar.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/rich-text.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/rich-text.js +31 -0
- package/dist/plugins/client/client/grapesjs/rich-text.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/semantic.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/semantic.js +110 -0
- package/dist/plugins/client/client/grapesjs/semantic.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/settings.d.ts +2 -0
- package/dist/plugins/client/client/grapesjs/settings.js +198 -0
- package/dist/plugins/client/client/grapesjs/settings.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/storage.d.ts +1 -0
- package/dist/plugins/client/client/grapesjs/storage.js +126 -0
- package/dist/plugins/client/client/grapesjs/storage.js.map +1 -0
- package/dist/plugins/client/client/grapesjs/symbolDialogs.d.ts +3 -0
- package/dist/plugins/client/client/grapesjs/symbolDialogs.js +36 -0
- package/dist/plugins/client/client/grapesjs/symbolDialogs.js.map +1 -0
- package/dist/plugins/client/client/publication-transformers.d.ts +41 -0
- package/dist/plugins/client/client/publication-transformers.js +238 -0
- package/dist/plugins/client/client/publication-transformers.js.map +1 -0
- package/dist/plugins/client/client/utils.d.ts +2 -0
- package/dist/plugins/client/client/utils.js +25 -0
- package/dist/plugins/client/client/utils.js.map +1 -0
- package/dist/plugins/client/constants.d.ts +29 -0
- package/dist/plugins/client/constants.js +46 -0
- package/dist/plugins/client/constants.js.map +1 -0
- package/dist/plugins/client/page.d.ts +2 -0
- package/dist/plugins/client/page.js +31 -0
- package/dist/plugins/client/page.js.map +1 -0
- package/dist/plugins/client/plugins/client/11ty.d.ts +17 -0
- package/dist/plugins/client/plugins/client/11ty.js +86 -0
- package/dist/plugins/client/plugins/client/11ty.js.map +1 -0
- package/dist/plugins/client/plugins/client/publicationRenderer.d.ts +2 -0
- package/dist/plugins/client/plugins/client/publicationRenderer.js +170 -0
- package/dist/plugins/client/plugins/client/publicationRenderer.js.map +1 -0
- package/dist/plugins/client/plugins/client/template.d.ts +2 -0
- package/dist/plugins/client/plugins/client/template.js +183 -0
- package/dist/plugins/client/plugins/client/template.js.map +1 -0
- package/dist/plugins/client/plugins/client/website-info.d.ts +1 -0
- package/dist/plugins/client/plugins/client/website-info.js +72 -0
- package/dist/plugins/client/plugins/client/website-info.js.map +1 -0
- package/dist/plugins/client/types.d.ts +334 -0
- package/dist/plugins/client/types.js +74 -0
- package/dist/plugins/client/types.js.map +1 -0
- package/dist/plugins/server/constants.d.ts +29 -0
- package/dist/plugins/server/constants.js +49 -0
- package/dist/plugins/server/constants.js.map +1 -0
- package/dist/plugins/server/plugins/server/AuthPlugin.d.ts +1 -0
- package/dist/plugins/server/plugins/server/AuthPlugin.js +40 -0
- package/dist/plugins/server/plugins/server/AuthPlugin.js.map +1 -0
- package/dist/plugins/server/plugins/server/Cache.d.ts +2 -0
- package/dist/plugins/server/plugins/server/Cache.js +32 -0
- package/dist/plugins/server/plugins/server/Cache.js.map +1 -0
- package/dist/plugins/server/plugins/server/DownloadConnector.d.ts +29 -0
- package/dist/plugins/server/plugins/server/DownloadConnector.js +129 -0
- package/dist/plugins/server/plugins/server/DownloadConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/FtpConnector.d.ts +86 -0
- package/dist/plugins/server/plugins/server/FtpConnector.js +526 -0
- package/dist/plugins/server/plugins/server/FtpConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +87 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.js +564 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/PublicationOptimizer.d.ts +0 -0
- package/dist/plugins/server/plugins/server/PublicationOptimizer.js +14 -0
- package/dist/plugins/server/plugins/server/PublicationOptimizer.js.map +1 -0
- package/dist/plugins/server/plugins/server/SslPlugin.d.ts +1 -0
- package/dist/plugins/server/plugins/server/SslPlugin.js +86 -0
- package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.d.ts +1 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.js +78 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -0
- package/dist/plugins/server/server/config.d.ts +59 -0
- package/dist/plugins/server/server/config.js +181 -0
- package/dist/plugins/server/server/config.js.map +1 -0
- package/dist/plugins/server/server/connectors/FsHosting.d.ts +13 -0
- package/dist/plugins/server/server/connectors/FsHosting.js +54 -0
- package/dist/plugins/server/server/connectors/FsHosting.js.map +1 -0
- package/dist/plugins/server/server/connectors/FsStorage.d.ts +43 -0
- package/dist/plugins/server/server/connectors/FsStorage.js +257 -0
- package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -0
- package/dist/plugins/server/server/connectors/connectors.d.ts +87 -0
- package/dist/plugins/server/server/connectors/connectors.js +127 -0
- package/dist/plugins/server/server/connectors/connectors.js.map +1 -0
- package/dist/plugins/server/server/events.d.ts +26 -0
- package/dist/plugins/server/server/events.js +31 -0
- package/dist/plugins/server/server/events.js.map +1 -0
- package/dist/plugins/server/server/jobs.d.ts +12 -0
- package/dist/plugins/server/server/jobs.js +77 -0
- package/dist/plugins/server/server/jobs.js.map +1 -0
- package/dist/plugins/server/server/utils/validation.d.ts +7 -0
- package/dist/plugins/server/server/utils/validation.js +38 -0
- package/dist/plugins/server/server/utils/validation.js.map +1 -0
- package/dist/plugins/server/types.d.ts +334 -0
- package/dist/plugins/server/types.js +78 -0
- package/dist/plugins/server/types.js.map +1 -0
- package/dist/server/constants.js +29 -0
- package/dist/server/plugins/server/Cache.js +15 -0
- package/dist/server/server/api/api.js +20 -0
- package/dist/server/server/api/connectorApi.js +216 -0
- package/dist/server/server/api/publicationApi.js +108 -0
- package/dist/server/server/api/websiteApi.js +296 -0
- package/dist/server/server/cli.js +68 -0
- package/dist/server/server/config.js +120 -0
- package/dist/server/server/connectors/FsHosting.js +35 -0
- package/dist/server/server/connectors/FsStorage.js +225 -0
- package/dist/server/server/connectors/connectors.js +89 -0
- package/dist/server/server/events.js +14 -0
- package/dist/server/server/expose.js +27 -0
- package/dist/server/server/express.js +47 -0
- package/dist/server/server/index.js +90 -0
- package/dist/server/server/jobs.js +48 -0
- package/dist/server/server/utils/validation.js +15 -0
- package/dist/server/types.js +34 -0
- package/package.json +209 -0
- package/public/assets/container.png +0 -0
- package/public/assets/favicon.png +0 -0
- package/public/assets/logo-silex-small.png +0 -0
- package/public/robots.txt +2 -0
- package/public/silex.js +24 -0
- package/src/css/_mixins.scss +8 -0
- package/src/css/_variables.scss +33 -0
- package/src/css/dialog.scss +41 -0
- package/src/css/footer.scss +12 -0
- package/src/css/grapesjs-light.scss +180 -0
- package/src/css/grapesjs.scss +152 -0
- package/src/css/index.scss +32 -0
- package/src/css/light.scss +7 -0
- package/src/css/loader.scss +12 -0
- package/src/css/page-panel.scss +65 -0
- package/src/css/project-bar.scss +102 -0
- package/src/css/silex.scss +189 -0
- package/src/css/website-info.scss +14 -0
- package/src/html/debug.pug +8 -0
- package/src/html/index.pug +39 -0
- package/src/html/templates/includes.pug +1 -0
- package/src/html/templates/workspace.pug +2 -0
- package/src/ts/client/api.ts +144 -0
- package/src/ts/client/assetUrl.test.ts +125 -0
- package/src/ts/client/assetUrl.ts +235 -0
- package/src/ts/client/config.ts +105 -0
- package/src/ts/client/events.ts +34 -0
- package/src/ts/client/expose.ts +30 -0
- package/src/ts/client/grapesjs/LoginDialog.ts +204 -0
- package/src/ts/client/grapesjs/PublicationManager.ts +370 -0
- package/src/ts/client/grapesjs/PublicationUi.ts +342 -0
- package/src/ts/client/grapesjs/blocks.ts +37 -0
- package/src/ts/client/grapesjs/breadcrumbs.ts +79 -0
- package/src/ts/client/grapesjs/eleventy.ts +47 -0
- package/src/ts/client/grapesjs/footer.ts +27 -0
- package/src/ts/client/grapesjs/index.ts +335 -0
- package/src/ts/client/grapesjs/internal-links.test.ts +105 -0
- package/src/ts/client/grapesjs/internal-links.ts +225 -0
- package/src/ts/client/grapesjs/new-page-dialog.ts +90 -0
- package/src/ts/client/grapesjs/openImport.ts +81 -0
- package/src/ts/client/grapesjs/page-panel.ts +118 -0
- package/src/ts/client/grapesjs/project-bar.ts +107 -0
- package/src/ts/client/grapesjs/rich-text.ts +33 -0
- package/src/ts/client/grapesjs/semantic.ts +114 -0
- package/src/ts/client/grapesjs/settings.ts +208 -0
- package/src/ts/client/grapesjs/storage.ts +121 -0
- package/src/ts/client/grapesjs/symbolDialogs.ts +38 -0
- package/src/ts/client/index.ts +98 -0
- package/src/ts/client/publication-transformers.test.ts +199 -0
- package/src/ts/client/publication-transformers.ts +263 -0
- package/src/ts/client/utils.ts +28 -0
- package/src/ts/constants.ts +52 -0
- package/src/ts/externs.ts +18 -0
- package/src/ts/page.ts +31 -0
- package/src/ts/plugins/client/11ty.ts +104 -0
- package/src/ts/plugins/client/publicationRenderer.ts +174 -0
- package/src/ts/plugins/client/template.ts +192 -0
- package/src/ts/plugins/client/website-info.ts +84 -0
- package/src/ts/plugins/server/AuthPlugin.ts +38 -0
- package/src/ts/plugins/server/Cache.ts +28 -0
- package/src/ts/plugins/server/DownloadConnector.ts +148 -0
- package/src/ts/plugins/server/FtpConnector.test.ts +82 -0
- package/src/ts/plugins/server/FtpConnector.ts +609 -0
- package/src/ts/plugins/server/GitlabConnector.ts +644 -0
- package/src/ts/plugins/server/PublicationOptimizer.ts +14 -0
- package/src/ts/plugins/server/SslPlugin.ts +84 -0
- package/src/ts/plugins/server/StaticPlugin.ts +79 -0
- package/src/ts/server/api/api.ts +19 -0
- package/src/ts/server/api/connectorApi.ts +345 -0
- package/src/ts/server/api/publicationApi.ts +159 -0
- package/src/ts/server/api/websiteApi.ts +432 -0
- package/src/ts/server/cli.ts +65 -0
- package/src/ts/server/config.ts +189 -0
- package/src/ts/server/connectors/FsHosting.ts +60 -0
- package/src/ts/server/connectors/FsStorage.test.ts +51 -0
- package/src/ts/server/connectors/FsStorage.ts +261 -0
- package/src/ts/server/connectors/connectors.ts +203 -0
- package/src/ts/server/events.ts +37 -0
- package/src/ts/server/expose.ts +19 -0
- package/src/ts/server/express.ts +70 -0
- package/src/ts/server/index.ts +100 -0
- package/src/ts/server/jobs.test.ts +75 -0
- package/src/ts/server/jobs.ts +87 -0
- package/src/ts/server/utils/BackwardCompat.ts +552 -0
- package/src/ts/server/utils/validation.ts +34 -0
- package/src/ts/types.ts +339 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Silex website builder, free/libre no-code tool for makers.
|
|
3
|
+
* Copyright (c) 2023 lexoyo and Silex Labs foundation
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import grapesjs, { Editor, EditorConfig } from 'grapesjs'
|
|
19
|
+
import openImport from './openImport'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @fileoverview This is where grapes config gets created
|
|
23
|
+
* Handle plugins, options and initialization of the editor
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
// ////////////////////
|
|
27
|
+
// Plugins
|
|
28
|
+
// ////////////////////
|
|
29
|
+
import blocksBasicPlugin from 'grapesjs-blocks-basic'
|
|
30
|
+
import styleFilterPlugin from 'grapesjs-style-filter'
|
|
31
|
+
import formPlugin from 'grapesjs-plugin-forms'
|
|
32
|
+
import codePlugin from 'grapesjs-custom-code'
|
|
33
|
+
import uiSuggestClasses from '@silexlabs/grapesjs-ui-suggest-classes'
|
|
34
|
+
import symbolsPlugin from '@silexlabs/grapesjs-symbols'
|
|
35
|
+
import loadingPlugin from '@silexlabs/grapesjs-loading'
|
|
36
|
+
import fontsDialogPlugin, { cmdOpenFonts } from '@silexlabs/grapesjs-fonts'
|
|
37
|
+
import symbolDialogsPlugin, { cmdPromptAddSymbol } from './symbolDialogs'
|
|
38
|
+
import loginDialogPlugin, { LoginDialogOptions, cmdLogout } from './LoginDialog'
|
|
39
|
+
import footerPlugin from './footer'
|
|
40
|
+
import breadcrumbsPlugin from './breadcrumbs'
|
|
41
|
+
import rateLimitPlugin from '@silexlabs/grapesjs-storage-rate-limit'
|
|
42
|
+
|
|
43
|
+
import { pagePanelPlugin, cmdTogglePages, cmdAddPage } from './page-panel'
|
|
44
|
+
import { newPageDialog, cmdOpenNewPageDialog } from './new-page-dialog'
|
|
45
|
+
import { projectBarPlugin } from './project-bar'
|
|
46
|
+
import { settingsDialog, cmdOpenSettings } from './settings'
|
|
47
|
+
import { blocksPlugin } from './blocks'
|
|
48
|
+
import { semanticPlugin } from './semantic'
|
|
49
|
+
import { richTextPlugin } from './rich-text'
|
|
50
|
+
import { internalLinksPlugin } from './internal-links'
|
|
51
|
+
import publicationManagerPlugin, { PublicationManagerOptions } from './PublicationManager'
|
|
52
|
+
import { storagePlugin } from './storage'
|
|
53
|
+
import { ConnectorId, WebsiteId } from '../../types'
|
|
54
|
+
import { API_PATH, API_WEBSITE_ASSETS_WRITE, API_WEBSITE_PATH } from '../../constants'
|
|
55
|
+
|
|
56
|
+
const plugins = [
|
|
57
|
+
{name: './project-bar', value: projectBarPlugin}, // has to be before panels and dialogs
|
|
58
|
+
{name: './settings', value: settingsDialog},
|
|
59
|
+
{name: '@silexlabs/grapesjs-fonts', value: fontsDialogPlugin},
|
|
60
|
+
{name: './new-page-dialog', value: newPageDialog},
|
|
61
|
+
{name: './page-panel', value: pagePanelPlugin},
|
|
62
|
+
{name: 'grapesjs-blocks-basic', value: blocksBasicPlugin},
|
|
63
|
+
{name: './blocks', value: blocksPlugin},
|
|
64
|
+
{name: './semantic', value: semanticPlugin},
|
|
65
|
+
{name: './rich-text', value: richTextPlugin},
|
|
66
|
+
{name: 'grapesjs-style-filter', value: styleFilterPlugin},
|
|
67
|
+
{name: 'grapesjs-plugin-forms', value: formPlugin},
|
|
68
|
+
{name: 'grapesjs-custom-code', value: codePlugin},
|
|
69
|
+
{name: './internal-links', value: internalLinksPlugin},
|
|
70
|
+
{name: '@silexlabs/grapesjs-ui-suggest-classes', value: uiSuggestClasses},
|
|
71
|
+
{name: './symbolDialogs', value: symbolDialogsPlugin},
|
|
72
|
+
{name: '@silexlabs/grapesjs-symbols', value: symbolsPlugin},
|
|
73
|
+
{name: './PublicationManager', value: publicationManagerPlugin},
|
|
74
|
+
{name: './storage', value: storagePlugin},
|
|
75
|
+
{name: './LoginDialog', value: loginDialogPlugin},
|
|
76
|
+
{name: '@silexlabs/grapesjs-loading', value: loadingPlugin},
|
|
77
|
+
{name: './breadcrumbs', value: breadcrumbsPlugin},
|
|
78
|
+
{name: './footer', value: footerPlugin},
|
|
79
|
+
{name: '@silexlabs/grapesjs-storage-rate-limit', value: rateLimitPlugin},
|
|
80
|
+
]
|
|
81
|
+
// Check that all plugins are loaded correctly
|
|
82
|
+
plugins
|
|
83
|
+
.filter(p => typeof p.value !== 'function')
|
|
84
|
+
.forEach(p => {
|
|
85
|
+
throw new Error(`Plugin ${p.name} could not be loaded correctly (${p.value})`)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// Constants
|
|
89
|
+
const PRIMARY_COLOR = '#333333'
|
|
90
|
+
const SECONDARY_COLOR = '#ddd'
|
|
91
|
+
const TERTIARY_COLOR = '#8873FE'
|
|
92
|
+
const QUATERNARY_COLOR = '#A291FF'
|
|
93
|
+
const DARKER_PRIMARY_COLOR = '#363636'
|
|
94
|
+
const LIGHTER_PRIMARY_COLOR = '#575757'
|
|
95
|
+
|
|
96
|
+
// ////////////////////
|
|
97
|
+
// Config
|
|
98
|
+
// ////////////////////
|
|
99
|
+
const catBasic = 'Containers'
|
|
100
|
+
const catComponents = 'Components'
|
|
101
|
+
|
|
102
|
+
export function getEditorConfig(id: WebsiteId, connectorId: ConnectorId, rootUrl: string): EditorConfig {
|
|
103
|
+
return {
|
|
104
|
+
container: '#gjs',
|
|
105
|
+
height: '100%',
|
|
106
|
+
showOffsets: true,
|
|
107
|
+
showDevices: true,
|
|
108
|
+
|
|
109
|
+
//pageManager: {},
|
|
110
|
+
|
|
111
|
+
layerManager: {
|
|
112
|
+
appendTo: '.layer-manager-container',
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
blockManager: {
|
|
116
|
+
appendTo: '.block-manager-container',
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
assetManager: {
|
|
120
|
+
upload: `${rootUrl}${API_PATH}${API_WEBSITE_PATH}${API_WEBSITE_ASSETS_WRITE}/?websiteId=${id}${ connectorId ? `&connectorId=${connectorId}` : ''}`,
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
storageManager: {
|
|
124
|
+
autoload: false,
|
|
125
|
+
type: 'connector',
|
|
126
|
+
options: {
|
|
127
|
+
connector: {
|
|
128
|
+
id,
|
|
129
|
+
connectorId,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
cssIcons: './css/all.min.css',
|
|
135
|
+
canvasCss: `
|
|
136
|
+
:root {
|
|
137
|
+
--primaryColor: ${PRIMARY_COLOR};
|
|
138
|
+
--secondaryColor: ${SECONDARY_COLOR};
|
|
139
|
+
--tertiaryColor: ${TERTIARY_COLOR};
|
|
140
|
+
--quaternaryColor: ${QUATERNARY_COLOR};
|
|
141
|
+
--darkerPrimaryColor: ${DARKER_PRIMARY_COLOR};
|
|
142
|
+
--lighterPrimaryColor: ${LIGHTER_PRIMARY_COLOR};
|
|
143
|
+
}
|
|
144
|
+
.gjs-frame-selected {
|
|
145
|
+
box-shadow: 0 0 0 2px rgba(255, 0, 0, 0.5) !important; // Change to red border
|
|
146
|
+
}
|
|
147
|
+
.gjs-selected {
|
|
148
|
+
outline: 2px solid var(--tertiaryColor) !important;
|
|
149
|
+
outline-offset: -2px;
|
|
150
|
+
}
|
|
151
|
+
`,
|
|
152
|
+
|
|
153
|
+
plugins: plugins.map(p => p.value),
|
|
154
|
+
|
|
155
|
+
pluginsOpts: {
|
|
156
|
+
[blocksBasicPlugin as any]: {
|
|
157
|
+
blocks: ['text', 'image', 'video', 'map'],
|
|
158
|
+
category: catBasic,
|
|
159
|
+
//flexGrid: true,
|
|
160
|
+
},
|
|
161
|
+
[projectBarPlugin as any]: {
|
|
162
|
+
panels: [
|
|
163
|
+
{
|
|
164
|
+
id: 'dash',
|
|
165
|
+
className: 'logo',
|
|
166
|
+
attributes: { title: 'Dashboard' },
|
|
167
|
+
command: () => {
|
|
168
|
+
window.location.href = '/'
|
|
169
|
+
},
|
|
170
|
+
}, {
|
|
171
|
+
id: 'block-manager-btn',
|
|
172
|
+
className: 'block-manager-btn fa fa-fw fa-plus',
|
|
173
|
+
attributes: { title: 'Blocks', containerClassName: 'block-manager-container', },
|
|
174
|
+
command: 'open-blocks',
|
|
175
|
+
}, {
|
|
176
|
+
id: 'symbols-btn',
|
|
177
|
+
className: 'symbols-btn fa-regular fa-gem',
|
|
178
|
+
attributes: { title: 'Symbols', containerClassName: 'symbols-list-container', },
|
|
179
|
+
command: 'open-symbols',
|
|
180
|
+
buttons: [
|
|
181
|
+
{
|
|
182
|
+
id: 'symbol-create-button',
|
|
183
|
+
className: 'pages__add-page fa-solid fa-plus',
|
|
184
|
+
label: 'Create symbol from selection',
|
|
185
|
+
command: cmdPromptAddSymbol,
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
}, {
|
|
189
|
+
id: 'page-panel-btn',
|
|
190
|
+
className: 'page-panel-btn fa fa-fw fa-file',
|
|
191
|
+
attributes: { title: 'Pages', containerClassName: 'page-panel-container', },
|
|
192
|
+
command: cmdTogglePages,
|
|
193
|
+
buttons: [{
|
|
194
|
+
className: 'pages__add-page fa fa-file',
|
|
195
|
+
command: cmdAddPage,
|
|
196
|
+
text: '+',
|
|
197
|
+
}],
|
|
198
|
+
}, {
|
|
199
|
+
id: 'layer-manager-btn',
|
|
200
|
+
className: 'layer-manager-btn fa-solid fa-layer-group',
|
|
201
|
+
attributes: { title: 'Layers', containerClassName: 'layer-manager-container', },
|
|
202
|
+
command: 'open-layers',
|
|
203
|
+
}, {
|
|
204
|
+
id: 'font-dialog-btn',
|
|
205
|
+
className: 'font-manager-btn fa-solid fa-font',
|
|
206
|
+
attributes: { title: 'Fonts' },
|
|
207
|
+
command: () => {
|
|
208
|
+
editor.runCommand(cmdOpenFonts)
|
|
209
|
+
},
|
|
210
|
+
}, {
|
|
211
|
+
id: 'settings-dialog-btn',
|
|
212
|
+
className: 'page-panel-btn fa-solid fa-gears',
|
|
213
|
+
attributes: { title: 'Settings' },
|
|
214
|
+
command: cmdOpenSettings,
|
|
215
|
+
}, {
|
|
216
|
+
id: 'spacer',
|
|
217
|
+
attributes: {},
|
|
218
|
+
className: 'project-bar-spacer',
|
|
219
|
+
}, {
|
|
220
|
+
id: 'dash2',
|
|
221
|
+
className: 'fa-solid fa-house',
|
|
222
|
+
attributes: { title: 'Dashboard' },
|
|
223
|
+
command: () => {
|
|
224
|
+
window.location.href = '/'
|
|
225
|
+
},
|
|
226
|
+
}, {
|
|
227
|
+
id: 'help',
|
|
228
|
+
className: 'fa fa-fw fa-question-circle',
|
|
229
|
+
attributes: { title: 'Documentation' },
|
|
230
|
+
command: () => {
|
|
231
|
+
window.open('https://docs.silex.me/', '_blank')
|
|
232
|
+
},
|
|
233
|
+
}, {
|
|
234
|
+
id: 'logout-button',
|
|
235
|
+
className: 'page-panel-btn fa fa-fw fa-sign-out',
|
|
236
|
+
attributes: { title: 'Sign out' },
|
|
237
|
+
command: cmdLogout,
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
[publicationManagerPlugin as any]: {
|
|
242
|
+
appendTo: 'options',
|
|
243
|
+
websiteId: id,
|
|
244
|
+
} as PublicationManagerOptions,
|
|
245
|
+
[pagePanelPlugin as any]: {
|
|
246
|
+
cmdOpenNewPageDialog,
|
|
247
|
+
cmdOpenSettings,
|
|
248
|
+
appendTo: '.page-panel-container',
|
|
249
|
+
},
|
|
250
|
+
[uiSuggestClasses as any]: {
|
|
251
|
+
enableCount: false,
|
|
252
|
+
enablePerformance: false,
|
|
253
|
+
},
|
|
254
|
+
[internalLinksPlugin as any]: {
|
|
255
|
+
// FIXME: warn the user about links in error
|
|
256
|
+
onError: (errors) => console.warn('Links errors:', errors),
|
|
257
|
+
},
|
|
258
|
+
[codePlugin as any]: {
|
|
259
|
+
blockLabel: 'HTML',
|
|
260
|
+
blockCustomCode: {
|
|
261
|
+
category: catComponents,
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
[symbolsPlugin as any]: {
|
|
265
|
+
appendTo: '.symbols-list-container',
|
|
266
|
+
emptyText: 'No symbol yet.',
|
|
267
|
+
primaryColor: PRIMARY_COLOR,
|
|
268
|
+
secondaryColor: SECONDARY_COLOR,
|
|
269
|
+
highlightColor: TERTIARY_COLOR,
|
|
270
|
+
},
|
|
271
|
+
[fontsDialogPlugin as any]: {
|
|
272
|
+
api_key: 'AIzaSyAdJTYSLPlKz4w5Iqyy-JAF2o8uQKd1FKc',
|
|
273
|
+
},
|
|
274
|
+
[loginDialogPlugin as any]: {
|
|
275
|
+
id,
|
|
276
|
+
} as LoginDialogOptions,
|
|
277
|
+
[rateLimitPlugin as any]: {
|
|
278
|
+
time: 5000,
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ////////////////////
|
|
285
|
+
// Initialize editor
|
|
286
|
+
// ////////////////////
|
|
287
|
+
// Keep a ref to the editor singleton
|
|
288
|
+
let editor: Editor
|
|
289
|
+
export async function initEditor(config: EditorConfig) {
|
|
290
|
+
if(editor) throw new Error('Grapesjs editor already created')
|
|
291
|
+
return new Promise<Editor>((resolve, reject) => {
|
|
292
|
+
try {
|
|
293
|
+
editor = grapesjs.init(config)
|
|
294
|
+
} catch(e) {
|
|
295
|
+
console.error('Error initializing GrapesJs with plugins:', plugins, e)
|
|
296
|
+
reject(e)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// customize the editor
|
|
300
|
+
['text']
|
|
301
|
+
.forEach(id => editor.Blocks.get(id)?.set('category', 'Basics'))
|
|
302
|
+
;['image', 'video']
|
|
303
|
+
.forEach(id => editor.Blocks.get(id)?.set('category', 'Media'))
|
|
304
|
+
;['map']
|
|
305
|
+
.forEach(id => editor.Blocks.get(id)?.set('category', 'Components'))
|
|
306
|
+
editor.Blocks.render([])
|
|
307
|
+
|
|
308
|
+
editor.Commands.add('gjs-open-import-webpage', openImport(editor, {
|
|
309
|
+
modalImportLabel: '',
|
|
310
|
+
modalImportContent: 'Paste a web page HTML code here.',
|
|
311
|
+
modalImportButton: 'Import',
|
|
312
|
+
modalImportTitle: 'Import from website',
|
|
313
|
+
}))
|
|
314
|
+
|
|
315
|
+
editor.on('load', () => {
|
|
316
|
+
// remove blocks and layers buttons from the properties
|
|
317
|
+
editor.Panels.getPanel('views').buttons.remove('open-blocks')
|
|
318
|
+
editor.Panels.getPanel('views').buttons.remove('open-layers')
|
|
319
|
+
editor.Panels.getPanel('views').view.el.firstChild.style.justifyContent = 'initial' // align left
|
|
320
|
+
editor.Panels.getPanel('options').buttons.remove('export-template')
|
|
321
|
+
|
|
322
|
+
editor.BlockManager.render(null)
|
|
323
|
+
|
|
324
|
+
// use the style filter plugin
|
|
325
|
+
editor.StyleManager.addProperty('extra',{ extend: 'filter' })
|
|
326
|
+
|
|
327
|
+
// GrapesJs editor is ready
|
|
328
|
+
resolve(editor)
|
|
329
|
+
})
|
|
330
|
+
})
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function getEditor() {
|
|
334
|
+
return editor
|
|
335
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Silex website builder, free/libre no-code tool for makers.
|
|
3
|
+
* Copyright (c) 2023 lexoyo and Silex Labs foundation
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { internalLinksPlugin } from './internal-links'
|
|
19
|
+
import { expect, test, beforeEach } from '@jest/globals'
|
|
20
|
+
import grapesjs from 'grapesjs'
|
|
21
|
+
|
|
22
|
+
let editor
|
|
23
|
+
let nextId = 1
|
|
24
|
+
function getNewId() {
|
|
25
|
+
return (nextId++).toString()
|
|
26
|
+
}
|
|
27
|
+
const comp1 = {
|
|
28
|
+
tagName: 'a',
|
|
29
|
+
content: 'link to main',
|
|
30
|
+
attributes: { href: './index.html' },
|
|
31
|
+
}
|
|
32
|
+
const comp2 = {
|
|
33
|
+
tagName: 'a',
|
|
34
|
+
content: 'link to page 1',
|
|
35
|
+
attributes: { href: './page-1.html' },
|
|
36
|
+
}
|
|
37
|
+
const comp3 = {
|
|
38
|
+
tagName: 'a',
|
|
39
|
+
content: 'link to page 2',
|
|
40
|
+
attributes: { href: './page-2.html' },
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const pageMain = {
|
|
44
|
+
id: getNewId(),
|
|
45
|
+
type: 'main',
|
|
46
|
+
component: {
|
|
47
|
+
tagName: 'div',
|
|
48
|
+
components: [comp1, comp2],
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
const page1 = {
|
|
52
|
+
id: getNewId(),
|
|
53
|
+
name: 'Page 1',
|
|
54
|
+
component: {
|
|
55
|
+
tagName: 'div',
|
|
56
|
+
components: [comp3],
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
const page2 = {
|
|
60
|
+
id: getNewId(),
|
|
61
|
+
name: 'Page 2',
|
|
62
|
+
component: {
|
|
63
|
+
tagName: 'div',
|
|
64
|
+
components: [comp1, comp2, comp3],
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
editor = grapesjs.init({
|
|
69
|
+
headless: true,
|
|
70
|
+
storageManager: { autoload: false },
|
|
71
|
+
pageManager: {
|
|
72
|
+
pages: [pageMain, page1, page2],
|
|
73
|
+
},
|
|
74
|
+
plugins: [internalLinksPlugin],
|
|
75
|
+
})
|
|
76
|
+
expect(editor).not.toBeUndefined()
|
|
77
|
+
})
|
|
78
|
+
test('init', () => {
|
|
79
|
+
expect(editor.getComponents()).toHaveLength(pageMain.component.components.length)
|
|
80
|
+
})
|
|
81
|
+
test('rename page and rewrite links in current page', () => {
|
|
82
|
+
const page = editor.Pages.getSelected()
|
|
83
|
+
expect(page.id).toBe(pageMain.id)
|
|
84
|
+
expect(page.getName()).toBeUndefined()
|
|
85
|
+
const newName = 'Home page'
|
|
86
|
+
const newPath = './home-page.html'
|
|
87
|
+
// Do not work: page.setName(newName)
|
|
88
|
+
page.set('name', newName)
|
|
89
|
+
expect(page.getName()).toBe(newName)
|
|
90
|
+
const comp1Model = page.getMainComponent().components().find(c => c.attributes.content === comp1.content)
|
|
91
|
+
expect(comp1Model).toBeTruthy()
|
|
92
|
+
expect(comp1Model.attributes.attributes.href).toBe(newPath)
|
|
93
|
+
})
|
|
94
|
+
test('rename page and rewrite links in another page', () => {
|
|
95
|
+
const page = editor.Pages.get(page2.id)
|
|
96
|
+
expect(page.get('name')).toBe(page2.name)
|
|
97
|
+
const newName = 'Page 2 new-name'
|
|
98
|
+
const newPath = './page-2-new-name.html'
|
|
99
|
+
// Do not work: page.setName(newName)
|
|
100
|
+
page.set('name', newName)
|
|
101
|
+
expect(page.get('name')).toBe(newName)
|
|
102
|
+
const comp1Model = page.getMainComponent().components().find(c => c.attributes.content === comp3.content)
|
|
103
|
+
expect(comp1Model).toBeTruthy()
|
|
104
|
+
expect(comp1Model.attributes.attributes.href).toBe(newPath)
|
|
105
|
+
})
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Silex website builder, free/libre no-code tool for makers.
|
|
3
|
+
* Copyright (c) 2023 lexoyo and Silex Labs foundation
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {html, render} from 'lit-html'
|
|
19
|
+
import {map} from 'lit-html/directives/map.js'
|
|
20
|
+
import grapesjs from 'grapesjs/dist/grapes.min.js'
|
|
21
|
+
import { getPageLink } from '../../page'
|
|
22
|
+
|
|
23
|
+
// constants
|
|
24
|
+
const pluginName = 'internal-links'
|
|
25
|
+
const options: grapesjs.SelectOption = [
|
|
26
|
+
{ id: '', name: '-' },
|
|
27
|
+
{ id: 'url', name: 'URL' },
|
|
28
|
+
{ id: 'email', name: 'Email' },
|
|
29
|
+
{ id: 'page', name: 'Page' },
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
// plugin code
|
|
33
|
+
export const internalLinksPlugin = (editor, opts) => {
|
|
34
|
+
// update links when a page link changes
|
|
35
|
+
function onAll(cbk) {
|
|
36
|
+
editor.Pages.getAll()
|
|
37
|
+
.forEach(page => {
|
|
38
|
+
page.getMainComponent()
|
|
39
|
+
.onAll(cbk)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
editor.on('page', ({ event, page }) => {
|
|
43
|
+
if(!page) return // fixes UT
|
|
44
|
+
switch (event) {
|
|
45
|
+
case 'change:name':
|
|
46
|
+
// update all links to this page
|
|
47
|
+
onAll(component => {
|
|
48
|
+
if(component.getAttributes().href === getPageLink(page.previous('name'))) {
|
|
49
|
+
component.setAttributes({
|
|
50
|
+
href: getPageLink(page.get('name')),
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
break
|
|
55
|
+
case 'remove':
|
|
56
|
+
// mark all links as issues
|
|
57
|
+
const issues = []
|
|
58
|
+
onAll(component => {
|
|
59
|
+
console.log(component.getAttributes().href, getPageLink(page.previous('name')), page.previous('name'))
|
|
60
|
+
if(component.getAttributes().href === getPageLink(page.previous('name'))) {
|
|
61
|
+
issues.push(component)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
opts?.onError(issues)
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
// utility functions to render the UI
|
|
69
|
+
function getUi(type, href) {
|
|
70
|
+
switch (type) {
|
|
71
|
+
case 'email':
|
|
72
|
+
const mailTo = href.replace('mailto:', '').split('?')
|
|
73
|
+
const email = mailTo[0]
|
|
74
|
+
const params = (mailTo[1] || '').split('&').reduce((acc, item) => {
|
|
75
|
+
const items = item.split('=')
|
|
76
|
+
acc[items[0]] = items[1]
|
|
77
|
+
return acc
|
|
78
|
+
}, {})
|
|
79
|
+
return html`<div class="href-next__email-inputs">
|
|
80
|
+
<label for="href-next__email" class="gjs-one-bg silex-label">Email address</label>
|
|
81
|
+
<input class="href-next__email" placeholder="Insert email" type="email" value=${email || ''}/>
|
|
82
|
+
<label for="href-next__email-subject" class="gjs-one-bg silex-label">Subject</label>
|
|
83
|
+
<input class="href-next__email-subject" placeholder="Insert subject" value=${ params.subject || '' }/>
|
|
84
|
+
</div>`
|
|
85
|
+
case 'page':
|
|
86
|
+
return html`<div class="href-next__page-inputs">
|
|
87
|
+
<label for="href-next__page" class="gjs-one-bg silex-label">Page name</label>
|
|
88
|
+
<select id="href-next__page" class="href-next__page">
|
|
89
|
+
${
|
|
90
|
+
map<grapesjs.Page>(editor.Pages.getAll(), page => html`<option
|
|
91
|
+
?selected=${getPageLink(page.getName()) === href}
|
|
92
|
+
value=${getPageLink(page.getName())}>
|
|
93
|
+
${page.getName() || 'Main'}
|
|
94
|
+
</option>`)
|
|
95
|
+
}
|
|
96
|
+
</select>
|
|
97
|
+
</div>`
|
|
98
|
+
case 'url':
|
|
99
|
+
return html`<div class="href-next__url-inputs">
|
|
100
|
+
<label for="href-next__url" class="gjs-one-bg silex-label">URL</label>
|
|
101
|
+
<input class="href-next__url" placeholder="Insert URL" type="url" value=${ href }/>
|
|
102
|
+
</div>`
|
|
103
|
+
default:
|
|
104
|
+
return ''
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getDefaultHref(type) {
|
|
108
|
+
switch(type) {
|
|
109
|
+
case 'email': return 'mailto:'
|
|
110
|
+
case 'page': return getPageLink(null)
|
|
111
|
+
case 'url': return 'https://'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function doRender(el: HTMLElement, href = '') {
|
|
115
|
+
const type = getType(href)
|
|
116
|
+
const ui = getUi(type, href)
|
|
117
|
+
|
|
118
|
+
render(html`
|
|
119
|
+
<label for="href-next__type" class="gjs-one-bg silex-label">Type</label>
|
|
120
|
+
<select id="href-next__type" class="href-next__type" @change=${event => doRender(el, getDefaultHref(event.target.value))}>
|
|
121
|
+
${map<grapesjs.SelectOption>(options, opt => html`
|
|
122
|
+
<option value="${opt.id}" ?selected=${type === opt.id}>${opt.name}</option>
|
|
123
|
+
`)}
|
|
124
|
+
</select>
|
|
125
|
+
${ ui }
|
|
126
|
+
`, el)
|
|
127
|
+
}
|
|
128
|
+
function getType(href: string) {
|
|
129
|
+
if (href.indexOf('mailto:') === 0) {
|
|
130
|
+
return 'email'
|
|
131
|
+
} else if(href.indexOf('./') === 0){
|
|
132
|
+
return 'page'
|
|
133
|
+
} else if(href){
|
|
134
|
+
return 'url'
|
|
135
|
+
}
|
|
136
|
+
return ''
|
|
137
|
+
}
|
|
138
|
+
function doRenderCurrent(el) {
|
|
139
|
+
doRender(el, editor.getSelected()?.getAttributes().href || '')
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Add the new trait to all component types
|
|
143
|
+
editor.DomComponents.getTypes().map(type => {
|
|
144
|
+
editor.DomComponents.addType(type.id, {
|
|
145
|
+
model: {
|
|
146
|
+
defaults: {
|
|
147
|
+
traits: [
|
|
148
|
+
// Keep the type original traits
|
|
149
|
+
...editor.DomComponents.getType(type.id).model.prototype.defaults.traits
|
|
150
|
+
// Filter original href trait
|
|
151
|
+
.filter(trait => trait.name ? trait.name !== 'href' : trait !== 'href'),
|
|
152
|
+
// Add the new trait
|
|
153
|
+
{
|
|
154
|
+
label: 'Link',
|
|
155
|
+
type: 'href-next',
|
|
156
|
+
name: 'href',
|
|
157
|
+
},
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
editor.TraitManager.addType('href-next', {
|
|
165
|
+
createInput({ trait }) {
|
|
166
|
+
// Create a new element container and add some content
|
|
167
|
+
const el = document.createElement('div')
|
|
168
|
+
// update the UI when a page is added/renamed/removed
|
|
169
|
+
editor.on('page', () => doRenderCurrent(el))
|
|
170
|
+
doRenderCurrent(el)
|
|
171
|
+
// this will be the element passed to onEvent and onUpdate
|
|
172
|
+
return el
|
|
173
|
+
},
|
|
174
|
+
// Update the component based on UI changes
|
|
175
|
+
// `elInput` is the result HTMLElement you get from `createInput`
|
|
176
|
+
onEvent({ elInput, component, event }) {
|
|
177
|
+
const inputType = elInput.querySelector('.href-next__type')
|
|
178
|
+
let href = ''
|
|
179
|
+
// Compute the new HREF value
|
|
180
|
+
switch (inputType.value) {
|
|
181
|
+
case 'page':
|
|
182
|
+
const valPage = elInput.querySelector('.href-next__page')?.value
|
|
183
|
+
href = valPage || getDefaultHref('page')
|
|
184
|
+
break
|
|
185
|
+
case 'url':
|
|
186
|
+
const valUrl = elInput.querySelector('.href-next__url')?.value
|
|
187
|
+
href = valUrl || getDefaultHref('url')
|
|
188
|
+
break
|
|
189
|
+
case 'email':
|
|
190
|
+
const valEmail = elInput.querySelector('.href-next__email')?.value
|
|
191
|
+
const valSubj = elInput.querySelector('.href-next__email-subject')?.value
|
|
192
|
+
href = valEmail ? `mailto:${valEmail}${valSubj ? `?subject=${valSubj}` : ''}` : getDefaultHref('email')
|
|
193
|
+
break
|
|
194
|
+
default:
|
|
195
|
+
href = ''
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Store the new HREF value
|
|
199
|
+
component.addAttributes({ href })
|
|
200
|
+
|
|
201
|
+
// Handle the tag name
|
|
202
|
+
if(href === '') {
|
|
203
|
+
// Not a link
|
|
204
|
+
if(component.get('tagName').toUpperCase() === 'A'){
|
|
205
|
+
// Retrieve the original stored value
|
|
206
|
+
const original = component.get('originalTagName') ?? 'DIV'
|
|
207
|
+
// Case of the inline A tags inserted by the text bar
|
|
208
|
+
const value = original.toUpperCase() === 'A' ? 'SPAN' : original
|
|
209
|
+
component.set('tagName', value)
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
// Link
|
|
213
|
+
if(component.get('tagName').toUpperCase() !== 'A') {
|
|
214
|
+
component.set('originalTagName', component.get('tagName'))
|
|
215
|
+
component.set('tagName', 'A')
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
// Update UI on the component change
|
|
220
|
+
onUpdate({ elInput, component }) {
|
|
221
|
+
const href = component.getAttributes().href || ''
|
|
222
|
+
doRender(elInput, href)
|
|
223
|
+
},
|
|
224
|
+
})
|
|
225
|
+
}
|