From 40baf22809ffa3bece4e5f56e12ab9978a9455df Mon Sep 17 00:00:00 2001 From: Guy Sartorelli Date: Thu, 13 Feb 2025 10:30:32 +1300 Subject: [PATCH] MNT Add composer.json file --- .editorconfig | 31 + .eslintignore | 10 + .eslintrc.js | 1 + .gitignore | 7 + .nvmrc | 1 + .stylelintignore | 1 + .stylelintrc.js | 1 + _config.php | 53 + _config/config.yml | 25 + _config/injector.yml | 11 + babel.config.json | 6 + client/dist/js/TinyMCE_ssembed.js | 1 + client/dist/js/TinyMCE_sslink-anchor.js | 1 + client/dist/js/TinyMCE_sslink-email.js | 1 + client/dist/js/TinyMCE_sslink-external.js | 1 + client/dist/js/TinyMCE_sslink-file.js | 1 + client/dist/js/TinyMCE_sslink-internal.js | 1 + client/dist/js/TinyMCE_sslink.js | 1 + client/dist/js/TinyMCE_ssmedia.js | 1 + client/dist/js/bundle.js | 1 + client/dist/styles/editor.css | 1 + client/dist/tinymce/CHANGELOG.md | 3453 +++++++ client/dist/tinymce/README.md | 73 + client/dist/tinymce/README.txt | 2 + client/dist/tinymce/bower.json | 27 + client/dist/tinymce/composer.json | 52 + client/dist/tinymce/icons/default/icons.js | 1 + .../dist/tinymce/icons/default/icons.min.js | 1 + client/dist/tinymce/icons/default/index.js | 1 + client/dist/tinymce/license.txt | 21 + client/dist/tinymce/models/dom/index.js | 1 + client/dist/tinymce/models/dom/model.js | 1 + client/dist/tinymce/models/dom/model.min.js | 1 + client/dist/tinymce/package.json | 32 + .../dist/tinymce/plugins/accordion/index.js | 1 + .../dist/tinymce/plugins/accordion/plugin.js | 1 + .../tinymce/plugins/accordion/plugin.min.js | 1 + client/dist/tinymce/plugins/advlist/index.js | 1 + client/dist/tinymce/plugins/advlist/plugin.js | 1 + .../tinymce/plugins/advlist/plugin.min.js | 1 + client/dist/tinymce/plugins/anchor/index.js | 1 + client/dist/tinymce/plugins/anchor/plugin.js | 1 + .../dist/tinymce/plugins/anchor/plugin.min.js | 1 + client/dist/tinymce/plugins/autolink/index.js | 1 + .../dist/tinymce/plugins/autolink/plugin.js | 1 + .../tinymce/plugins/autolink/plugin.min.js | 1 + .../dist/tinymce/plugins/autoresize/index.js | 1 + .../dist/tinymce/plugins/autoresize/plugin.js | 1 + .../tinymce/plugins/autoresize/plugin.min.js | 1 + client/dist/tinymce/plugins/autosave/index.js | 1 + .../dist/tinymce/plugins/autosave/plugin.js | 1 + .../tinymce/plugins/autosave/plugin.min.js | 1 + client/dist/tinymce/plugins/charmap/index.js | 1 + client/dist/tinymce/plugins/charmap/plugin.js | 1 + .../tinymce/plugins/charmap/plugin.min.js | 1 + client/dist/tinymce/plugins/code/index.js | 1 + client/dist/tinymce/plugins/code/plugin.js | 1 + .../dist/tinymce/plugins/code/plugin.min.js | 1 + .../dist/tinymce/plugins/codesample/index.js | 1 + .../dist/tinymce/plugins/codesample/plugin.js | 1 + .../tinymce/plugins/codesample/plugin.min.js | 1 + .../tinymce/plugins/directionality/index.js | 1 + .../tinymce/plugins/directionality/plugin.js | 1 + .../plugins/directionality/plugin.min.js | 1 + .../dist/tinymce/plugins/emoticons/index.js | 1 + .../plugins/emoticons/js/emojiimages.js | 1 + .../plugins/emoticons/js/emojiimages.min.js | 1 + .../tinymce/plugins/emoticons/js/emojis.js | 1 + .../plugins/emoticons/js/emojis.min.js | 1 + .../dist/tinymce/plugins/emoticons/plugin.js | 1 + .../tinymce/plugins/emoticons/plugin.min.js | 1 + .../dist/tinymce/plugins/fullscreen/index.js | 1 + .../dist/tinymce/plugins/fullscreen/plugin.js | 1 + .../tinymce/plugins/fullscreen/plugin.min.js | 1 + client/dist/tinymce/plugins/help/index.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ar.js | 1 + .../plugins/help/js/i18n/keynav/bg_BG.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ca.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/cs.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/da.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/de.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/el.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/en.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/es.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/eu.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/fa.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/fi.js | 1 + .../plugins/help/js/i18n/keynav/fr_FR.js | 1 + .../plugins/help/js/i18n/keynav/he_IL.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/hi.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/hr.js | 1 + .../plugins/help/js/i18n/keynav/hu_HU.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/id.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/it.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ja.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/kk.js | 1 + .../plugins/help/js/i18n/keynav/ko_KR.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ms.js | 1 + .../plugins/help/js/i18n/keynav/nb_NO.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/nl.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/pl.js | 1 + .../plugins/help/js/i18n/keynav/pt_BR.js | 1 + .../plugins/help/js/i18n/keynav/pt_PT.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ro.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/ru.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/sk.js | 1 + .../plugins/help/js/i18n/keynav/sl_SI.js | 1 + .../plugins/help/js/i18n/keynav/sv_SE.js | 1 + .../plugins/help/js/i18n/keynav/th_TH.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/tr.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/uk.js | 1 + .../tinymce/plugins/help/js/i18n/keynav/vi.js | 1 + .../plugins/help/js/i18n/keynav/zh_CN.js | 1 + .../plugins/help/js/i18n/keynav/zh_TW.js | 1 + client/dist/tinymce/plugins/help/plugin.js | 1 + .../dist/tinymce/plugins/help/plugin.min.js | 1 + client/dist/tinymce/plugins/image/index.js | 1 + client/dist/tinymce/plugins/image/plugin.js | 1 + .../dist/tinymce/plugins/image/plugin.min.js | 1 + .../dist/tinymce/plugins/importcss/index.js | 1 + .../dist/tinymce/plugins/importcss/plugin.js | 1 + .../tinymce/plugins/importcss/plugin.min.js | 1 + .../tinymce/plugins/insertdatetime/index.js | 1 + .../tinymce/plugins/insertdatetime/plugin.js | 1 + .../plugins/insertdatetime/plugin.min.js | 1 + client/dist/tinymce/plugins/link/index.js | 1 + client/dist/tinymce/plugins/link/plugin.js | 1 + .../dist/tinymce/plugins/link/plugin.min.js | 1 + client/dist/tinymce/plugins/lists/index.js | 1 + client/dist/tinymce/plugins/lists/plugin.js | 1 + .../dist/tinymce/plugins/lists/plugin.min.js | 1 + client/dist/tinymce/plugins/media/index.js | 1 + client/dist/tinymce/plugins/media/plugin.js | 1 + .../dist/tinymce/plugins/media/plugin.min.js | 1 + .../dist/tinymce/plugins/nonbreaking/index.js | 1 + .../tinymce/plugins/nonbreaking/plugin.js | 1 + .../tinymce/plugins/nonbreaking/plugin.min.js | 1 + .../dist/tinymce/plugins/pagebreak/index.js | 1 + .../dist/tinymce/plugins/pagebreak/plugin.js | 1 + .../tinymce/plugins/pagebreak/plugin.min.js | 1 + client/dist/tinymce/plugins/preview/index.js | 1 + client/dist/tinymce/plugins/preview/plugin.js | 1 + .../tinymce/plugins/preview/plugin.min.js | 1 + .../dist/tinymce/plugins/quickbars/index.js | 1 + .../dist/tinymce/plugins/quickbars/plugin.js | 1 + .../tinymce/plugins/quickbars/plugin.min.js | 1 + client/dist/tinymce/plugins/save/index.js | 1 + client/dist/tinymce/plugins/save/plugin.js | 1 + .../dist/tinymce/plugins/save/plugin.min.js | 1 + .../tinymce/plugins/searchreplace/index.js | 1 + .../tinymce/plugins/searchreplace/plugin.js | 1 + .../plugins/searchreplace/plugin.min.js | 1 + client/dist/tinymce/plugins/table/index.js | 1 + client/dist/tinymce/plugins/table/plugin.js | 1 + .../dist/tinymce/plugins/table/plugin.min.js | 1 + client/dist/tinymce/plugins/template/index.js | 1 + .../dist/tinymce/plugins/template/plugin.js | 1 + .../tinymce/plugins/template/plugin.min.js | 1 + .../tinymce/plugins/visualblocks/index.js | 1 + .../tinymce/plugins/visualblocks/plugin.js | 1 + .../plugins/visualblocks/plugin.min.js | 1 + .../dist/tinymce/plugins/visualchars/index.js | 1 + .../tinymce/plugins/visualchars/plugin.js | 1 + .../tinymce/plugins/visualchars/plugin.min.js | 1 + .../dist/tinymce/plugins/wordcount/index.js | 1 + .../dist/tinymce/plugins/wordcount/plugin.js | 1 + .../tinymce/plugins/wordcount/plugin.min.js | 1 + .../tinymce/skins/content/dark/content.css | 66 + .../tinymce/skins/content/dark/content.js | 1 + .../skins/content/dark/content.min.css | 1 + .../tinymce/skins/content/default/content.css | 61 + .../tinymce/skins/content/default/content.js | 1 + .../skins/content/default/content.min.css | 1 + .../skins/content/document/content.css | 66 + .../tinymce/skins/content/document/content.js | 1 + .../skins/content/document/content.min.css | 1 + .../skins/content/tinymce-5-dark/content.css | 66 + .../skins/content/tinymce-5-dark/content.js | 1 + .../content/tinymce-5-dark/content.min.css | 1 + .../skins/content/tinymce-5/content.css | 61 + .../skins/content/tinymce-5/content.js | 1 + .../skins/content/tinymce-5/content.min.css | 1 + .../tinymce/skins/content/writer/content.css | 62 + .../tinymce/skins/content/writer/content.js | 1 + .../skins/content/writer/content.min.css | 1 + .../tinymce/skins/ui/oxide-dark/content.css | 766 ++ .../skins/ui/oxide-dark/content.inline.css | 779 ++ .../skins/ui/oxide-dark/content.inline.js | 1 + .../ui/oxide-dark/content.inline.min.css | 1 + .../tinymce/skins/ui/oxide-dark/content.js | 1 + .../skins/ui/oxide-dark/content.min.css | 1 + .../dist/tinymce/skins/ui/oxide-dark/skin.css | 3766 ++++++++ .../dist/tinymce/skins/ui/oxide-dark/skin.js | 1 + .../tinymce/skins/ui/oxide-dark/skin.min.css | 1 + .../skins/ui/oxide-dark/skin.shadowdom.css | 30 + .../skins/ui/oxide-dark/skin.shadowdom.js | 1 + .../ui/oxide-dark/skin.shadowdom.min.css | 1 + .../dist/tinymce/skins/ui/oxide/content.css | 785 ++ .../tinymce/skins/ui/oxide/content.inline.css | 779 ++ .../tinymce/skins/ui/oxide/content.inline.js | 1 + .../skins/ui/oxide/content.inline.min.css | 1 + client/dist/tinymce/skins/ui/oxide/content.js | 1 + .../tinymce/skins/ui/oxide/content.min.css | 1 + client/dist/tinymce/skins/ui/oxide/skin.css | 3763 ++++++++ client/dist/tinymce/skins/ui/oxide/skin.js | 1 + .../dist/tinymce/skins/ui/oxide/skin.min.css | 1 + .../tinymce/skins/ui/oxide/skin.shadowdom.css | 30 + .../tinymce/skins/ui/oxide/skin.shadowdom.js | 1 + .../skins/ui/oxide/skin.shadowdom.min.css | 1 + .../tinymce/skins/ui/silverstripe/content.css | 785 ++ .../skins/ui/silverstripe/content.inline.css | 779 ++ .../ui/silverstripe/content.inline.min.css | 2 + .../skins/ui/silverstripe/content.min.css | 2 + .../tinymce/skins/ui/silverstripe/skin.css | 3871 ++++++++ .../skins/ui/silverstripe/skin.min.css | 2 + .../skins/ui/silverstripe/skin.shadowdom.css | 30 + .../ui/silverstripe/skin.shadowdom.min.css | 2 + .../skins/ui/silverstripe/src/README.md | 19 + .../ui/silverstripe/src/content.inline.less | 1 + .../skins/ui/silverstripe/src/content.less | 9 + .../skins/ui/silverstripe/src/skin.less | 107 + .../ui/silverstripe/src/skin.shadowdom.less | 1 + .../skins/ui/tinymce-5-dark/content.css | 766 ++ .../ui/tinymce-5-dark/content.inline.css | 779 ++ .../skins/ui/tinymce-5-dark/content.inline.js | 1 + .../ui/tinymce-5-dark/content.inline.min.css | 1 + .../skins/ui/tinymce-5-dark/content.js | 1 + .../skins/ui/tinymce-5-dark/content.min.css | 1 + .../tinymce/skins/ui/tinymce-5-dark/skin.css | 3857 ++++++++ .../tinymce/skins/ui/tinymce-5-dark/skin.js | 1 + .../skins/ui/tinymce-5-dark/skin.min.css | 1 + .../ui/tinymce-5-dark/skin.shadowdom.css | 30 + .../skins/ui/tinymce-5-dark/skin.shadowdom.js | 1 + .../ui/tinymce-5-dark/skin.shadowdom.min.css | 1 + .../tinymce/skins/ui/tinymce-5/content.css | 785 ++ .../skins/ui/tinymce-5/content.inline.css | 779 ++ .../skins/ui/tinymce-5/content.inline.js | 1 + .../skins/ui/tinymce-5/content.inline.min.css | 1 + .../tinymce/skins/ui/tinymce-5/content.js | 1 + .../skins/ui/tinymce-5/content.min.css | 1 + .../dist/tinymce/skins/ui/tinymce-5/skin.css | 3857 ++++++++ .../dist/tinymce/skins/ui/tinymce-5/skin.js | 1 + .../tinymce/skins/ui/tinymce-5/skin.min.css | 1 + .../skins/ui/tinymce-5/skin.shadowdom.css | 30 + .../skins/ui/tinymce-5/skin.shadowdom.js | 1 + .../skins/ui/tinymce-5/skin.shadowdom.min.css | 1 + client/dist/tinymce/themes/silver/index.js | 1 + client/dist/tinymce/themes/silver/theme.js | 1 + .../dist/tinymce/themes/silver/theme.min.js | 1 + client/dist/tinymce/tinymce.d.ts | 3238 +++++++ client/dist/tinymce/tinymce.js | 1 + client/dist/tinymce/tinymce.min.js | 1 + client/src/boot/index.js | 6 + client/src/boot/registerComponents.js | 8 + client/src/bundle.js | 8 + .../TinyMceHtmlEditorField.js | 145 + .../tests/TinyMceHtmlEditorField-test.js | 41 + client/src/entwine/TinyMceHtmlEditorField.js | 372 + client/src/lib/TinyMCEActionRegistrar.js | 153 + .../lib/tests/TinyMCEActionRegistrar-test.js | 71 + client/src/plugins/TinyMCE_ssembed.js | 427 + client/src/plugins/TinyMCE_sslink-anchor.js | 156 + client/src/plugins/TinyMCE_sslink-email.js | 143 + client/src/plugins/TinyMCE_sslink-external.js | 107 + client/src/plugins/TinyMCE_sslink-file.js | 167 + client/src/plugins/TinyMCE_sslink-internal.js | 145 + client/src/plugins/TinyMCE_sslink.js | 284 + client/src/plugins/TinyMCE_ssmedia.js | 566 ++ .../plugins/TinyMCE_ssmedia_sizepressets.js | 145 + client/src/styles/editor.scss | 12 + client/src/tinymce/README.txt | 2 + .../tinymce/skins/ui/silverstripe/content.css | 785 ++ .../skins/ui/silverstripe/content.inline.css | 779 ++ .../ui/silverstripe/content.inline.min.css | 2 + .../skins/ui/silverstripe/content.min.css | 2 + .../tinymce/skins/ui/silverstripe/skin.css | 3871 ++++++++ .../skins/ui/silverstripe/skin.min.css | 2 + .../skins/ui/silverstripe/skin.shadowdom.css | 30 + .../ui/silverstripe/skin.shadowdom.min.css | 2 + .../skins/ui/silverstripe/src/README.md | 19 + .../ui/silverstripe/src/content.inline.less | 1 + .../skins/ui/silverstripe/src/content.less | 9 + .../skins/ui/silverstripe/src/skin.less | 107 + .../ui/silverstripe/src/skin.shadowdom.less | 1 + client/tinymce_lang/README.md | 7 + client/tinymce_lang/ar.js | 7 + client/tinymce_lang/az.js | 7 + client/tinymce_lang/bg_BG.js | 7 + client/tinymce_lang/bn_BD.js | 7 + client/tinymce_lang/ca.js | 7 + client/tinymce_lang/cs.js | 7 + client/tinymce_lang/cy.js | 7 + client/tinymce_lang/da.js | 7 + client/tinymce_lang/de.js | 7 + client/tinymce_lang/dv.js | 7 + client/tinymce_lang/el.js | 7 + client/tinymce_lang/eo.js | 7 + client/tinymce_lang/es.js | 7 + client/tinymce_lang/es_MX.js | 7 + client/tinymce_lang/et.js | 7 + client/tinymce_lang/eu.js | 7 + client/tinymce_lang/fa.js | 7 + client/tinymce_lang/fi.js | 7 + client/tinymce_lang/fr_FR.js | 7 + client/tinymce_lang/ga.js | 7 + client/tinymce_lang/gl.js | 7 + client/tinymce_lang/he_IL.js | 7 + client/tinymce_lang/hi.js | 7 + client/tinymce_lang/hr.js | 7 + client/tinymce_lang/hu_HU.js | 7 + client/tinymce_lang/hy.js | 7 + client/tinymce_lang/id.js | 7 + client/tinymce_lang/is_IS.js | 7 + client/tinymce_lang/it.js | 7 + client/tinymce_lang/ja.js | 7 + client/tinymce_lang/kab.js | 7 + client/tinymce_lang/kk.js | 7 + client/tinymce_lang/ko_KR.js | 7 + client/tinymce_lang/ku.js | 7 + client/tinymce_lang/lt.js | 7 + client/tinymce_lang/lv.js | 7 + client/tinymce_lang/nb_NO.js | 7 + client/tinymce_lang/ne.js | 7 + client/tinymce_lang/nl.js | 7 + client/tinymce_lang/nl_BE.js | 7 + client/tinymce_lang/oc.js | 7 + client/tinymce_lang/pl.js | 7 + client/tinymce_lang/pt_BR.js | 7 + client/tinymce_lang/ro.js | 7 + client/tinymce_lang/ru.js | 7 + client/tinymce_lang/sk.js | 7 + client/tinymce_lang/sl_SI.js | 7 + client/tinymce_lang/sq.js | 7 + client/tinymce_lang/sr.js | 7 + client/tinymce_lang/sv_SE.js | 7 + client/tinymce_lang/ta.js | 7 + client/tinymce_lang/tg.js | 7 + client/tinymce_lang/th_TH.js | 7 + client/tinymce_lang/tr.js | 7 + client/tinymce_lang/ug.js | 7 + client/tinymce_lang/uk.js | 7 + client/tinymce_lang/vi.js | 7 + client/tinymce_lang/zh_Hans.js | 7 + composer.json | 46 + package.json | 69 + src/Extension/AdminInitExtension.php | 33 + src/TinyMCECombinedGenerator.php | 289 + src/TinyMCEConfig.php | 1115 +++ src/TinyMCEScriptGenerator.php | 17 + tests/php/TinyMCECombinedGeneratorTest.php | 132 + .../mycode/editor.css | 1 + .../mycode/plugin1.js | 1 + .../mycode/plugin2.js | 1 + .../mycode/plugin3.js | 1 + .../mycode/plugin6.js | 1 + .../mycode/plugin8.js | 1 + .../tinymce/langs/en.js | 1 + .../tinymce/plugins/plugin4/langs/en.js | 1 + .../tinymce/plugins/plugin4/plugin.js | 1 + .../tinymce/plugins/plugin4/plugin.min.js | 1 + .../tinymce/plugins/plugin5/plugin.js | 1 + .../tinymce/themes/testtheme/langs/en.js | 1 + .../tinymce/themes/testtheme/theme.js | 1 + .../tinymce/tinymce.min.js | 1 + tests/php/TinyMCEConfigTest.php | 99 + webpack.config.js | 59 + yarn.lock | 8174 +++++++++++++++++ 367 files changed, 53844 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 .stylelintignore create mode 100644 .stylelintrc.js create mode 100644 _config.php create mode 100644 _config/config.yml create mode 100644 _config/injector.yml create mode 100644 babel.config.json create mode 100644 client/dist/js/TinyMCE_ssembed.js create mode 100644 client/dist/js/TinyMCE_sslink-anchor.js create mode 100644 client/dist/js/TinyMCE_sslink-email.js create mode 100644 client/dist/js/TinyMCE_sslink-external.js create mode 100644 client/dist/js/TinyMCE_sslink-file.js create mode 100644 client/dist/js/TinyMCE_sslink-internal.js create mode 100644 client/dist/js/TinyMCE_sslink.js create mode 100644 client/dist/js/TinyMCE_ssmedia.js create mode 100644 client/dist/js/bundle.js create mode 100644 client/dist/styles/editor.css create mode 100644 client/dist/tinymce/CHANGELOG.md create mode 100644 client/dist/tinymce/README.md create mode 100644 client/dist/tinymce/README.txt create mode 100644 client/dist/tinymce/bower.json create mode 100644 client/dist/tinymce/composer.json create mode 100644 client/dist/tinymce/icons/default/icons.js create mode 100644 client/dist/tinymce/icons/default/icons.min.js create mode 100644 client/dist/tinymce/icons/default/index.js create mode 100644 client/dist/tinymce/license.txt create mode 100644 client/dist/tinymce/models/dom/index.js create mode 100644 client/dist/tinymce/models/dom/model.js create mode 100644 client/dist/tinymce/models/dom/model.min.js create mode 100644 client/dist/tinymce/package.json create mode 100644 client/dist/tinymce/plugins/accordion/index.js create mode 100644 client/dist/tinymce/plugins/accordion/plugin.js create mode 100644 client/dist/tinymce/plugins/accordion/plugin.min.js create mode 100644 client/dist/tinymce/plugins/advlist/index.js create mode 100644 client/dist/tinymce/plugins/advlist/plugin.js create mode 100644 client/dist/tinymce/plugins/advlist/plugin.min.js create mode 100644 client/dist/tinymce/plugins/anchor/index.js create mode 100644 client/dist/tinymce/plugins/anchor/plugin.js create mode 100644 client/dist/tinymce/plugins/anchor/plugin.min.js create mode 100644 client/dist/tinymce/plugins/autolink/index.js create mode 100644 client/dist/tinymce/plugins/autolink/plugin.js create mode 100644 client/dist/tinymce/plugins/autolink/plugin.min.js create mode 100644 client/dist/tinymce/plugins/autoresize/index.js create mode 100644 client/dist/tinymce/plugins/autoresize/plugin.js create mode 100644 client/dist/tinymce/plugins/autoresize/plugin.min.js create mode 100644 client/dist/tinymce/plugins/autosave/index.js create mode 100644 client/dist/tinymce/plugins/autosave/plugin.js create mode 100644 client/dist/tinymce/plugins/autosave/plugin.min.js create mode 100644 client/dist/tinymce/plugins/charmap/index.js create mode 100644 client/dist/tinymce/plugins/charmap/plugin.js create mode 100644 client/dist/tinymce/plugins/charmap/plugin.min.js create mode 100644 client/dist/tinymce/plugins/code/index.js create mode 100644 client/dist/tinymce/plugins/code/plugin.js create mode 100644 client/dist/tinymce/plugins/code/plugin.min.js create mode 100644 client/dist/tinymce/plugins/codesample/index.js create mode 100644 client/dist/tinymce/plugins/codesample/plugin.js create mode 100644 client/dist/tinymce/plugins/codesample/plugin.min.js create mode 100644 client/dist/tinymce/plugins/directionality/index.js create mode 100644 client/dist/tinymce/plugins/directionality/plugin.js create mode 100644 client/dist/tinymce/plugins/directionality/plugin.min.js create mode 100644 client/dist/tinymce/plugins/emoticons/index.js create mode 100644 client/dist/tinymce/plugins/emoticons/js/emojiimages.js create mode 100644 client/dist/tinymce/plugins/emoticons/js/emojiimages.min.js create mode 100644 client/dist/tinymce/plugins/emoticons/js/emojis.js create mode 100644 client/dist/tinymce/plugins/emoticons/js/emojis.min.js create mode 100644 client/dist/tinymce/plugins/emoticons/plugin.js create mode 100644 client/dist/tinymce/plugins/emoticons/plugin.min.js create mode 100644 client/dist/tinymce/plugins/fullscreen/index.js create mode 100644 client/dist/tinymce/plugins/fullscreen/plugin.js create mode 100644 client/dist/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 client/dist/tinymce/plugins/help/index.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ar.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/bg_BG.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ca.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/cs.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/da.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/de.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/el.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/en.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/es.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/eu.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/fa.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/fi.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/fr_FR.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/he_IL.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/hi.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/hr.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/hu_HU.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/id.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/it.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ja.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/kk.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ko_KR.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ms.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/nb_NO.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/nl.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/pl.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/pt_BR.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/pt_PT.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ro.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/ru.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/sk.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/sl_SI.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/sv_SE.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/th_TH.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/tr.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/uk.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/vi.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/zh_CN.js create mode 100644 client/dist/tinymce/plugins/help/js/i18n/keynav/zh_TW.js create mode 100644 client/dist/tinymce/plugins/help/plugin.js create mode 100644 client/dist/tinymce/plugins/help/plugin.min.js create mode 100644 client/dist/tinymce/plugins/image/index.js create mode 100644 client/dist/tinymce/plugins/image/plugin.js create mode 100644 client/dist/tinymce/plugins/image/plugin.min.js create mode 100644 client/dist/tinymce/plugins/importcss/index.js create mode 100644 client/dist/tinymce/plugins/importcss/plugin.js create mode 100644 client/dist/tinymce/plugins/importcss/plugin.min.js create mode 100644 client/dist/tinymce/plugins/insertdatetime/index.js create mode 100644 client/dist/tinymce/plugins/insertdatetime/plugin.js create mode 100644 client/dist/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 client/dist/tinymce/plugins/link/index.js create mode 100644 client/dist/tinymce/plugins/link/plugin.js create mode 100644 client/dist/tinymce/plugins/link/plugin.min.js create mode 100644 client/dist/tinymce/plugins/lists/index.js create mode 100644 client/dist/tinymce/plugins/lists/plugin.js create mode 100644 client/dist/tinymce/plugins/lists/plugin.min.js create mode 100644 client/dist/tinymce/plugins/media/index.js create mode 100644 client/dist/tinymce/plugins/media/plugin.js create mode 100644 client/dist/tinymce/plugins/media/plugin.min.js create mode 100644 client/dist/tinymce/plugins/nonbreaking/index.js create mode 100644 client/dist/tinymce/plugins/nonbreaking/plugin.js create mode 100644 client/dist/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 client/dist/tinymce/plugins/pagebreak/index.js create mode 100644 client/dist/tinymce/plugins/pagebreak/plugin.js create mode 100644 client/dist/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 client/dist/tinymce/plugins/preview/index.js create mode 100644 client/dist/tinymce/plugins/preview/plugin.js create mode 100644 client/dist/tinymce/plugins/preview/plugin.min.js create mode 100644 client/dist/tinymce/plugins/quickbars/index.js create mode 100644 client/dist/tinymce/plugins/quickbars/plugin.js create mode 100644 client/dist/tinymce/plugins/quickbars/plugin.min.js create mode 100644 client/dist/tinymce/plugins/save/index.js create mode 100644 client/dist/tinymce/plugins/save/plugin.js create mode 100644 client/dist/tinymce/plugins/save/plugin.min.js create mode 100644 client/dist/tinymce/plugins/searchreplace/index.js create mode 100644 client/dist/tinymce/plugins/searchreplace/plugin.js create mode 100644 client/dist/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 client/dist/tinymce/plugins/table/index.js create mode 100644 client/dist/tinymce/plugins/table/plugin.js create mode 100644 client/dist/tinymce/plugins/table/plugin.min.js create mode 100644 client/dist/tinymce/plugins/template/index.js create mode 100644 client/dist/tinymce/plugins/template/plugin.js create mode 100644 client/dist/tinymce/plugins/template/plugin.min.js create mode 100644 client/dist/tinymce/plugins/visualblocks/index.js create mode 100644 client/dist/tinymce/plugins/visualblocks/plugin.js create mode 100644 client/dist/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 client/dist/tinymce/plugins/visualchars/index.js create mode 100644 client/dist/tinymce/plugins/visualchars/plugin.js create mode 100644 client/dist/tinymce/plugins/visualchars/plugin.min.js create mode 100644 client/dist/tinymce/plugins/wordcount/index.js create mode 100644 client/dist/tinymce/plugins/wordcount/plugin.js create mode 100644 client/dist/tinymce/plugins/wordcount/plugin.min.js create mode 100644 client/dist/tinymce/skins/content/dark/content.css create mode 100644 client/dist/tinymce/skins/content/dark/content.js create mode 100644 client/dist/tinymce/skins/content/dark/content.min.css create mode 100644 client/dist/tinymce/skins/content/default/content.css create mode 100644 client/dist/tinymce/skins/content/default/content.js create mode 100644 client/dist/tinymce/skins/content/default/content.min.css create mode 100644 client/dist/tinymce/skins/content/document/content.css create mode 100644 client/dist/tinymce/skins/content/document/content.js create mode 100644 client/dist/tinymce/skins/content/document/content.min.css create mode 100644 client/dist/tinymce/skins/content/tinymce-5-dark/content.css create mode 100644 client/dist/tinymce/skins/content/tinymce-5-dark/content.js create mode 100644 client/dist/tinymce/skins/content/tinymce-5-dark/content.min.css create mode 100644 client/dist/tinymce/skins/content/tinymce-5/content.css create mode 100644 client/dist/tinymce/skins/content/tinymce-5/content.js create mode 100644 client/dist/tinymce/skins/content/tinymce-5/content.min.css create mode 100644 client/dist/tinymce/skins/content/writer/content.css create mode 100644 client/dist/tinymce/skins/content/writer/content.js create mode 100644 client/dist/tinymce/skins/content/writer/content.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.inline.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.inline.js create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.inline.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.js create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/content.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.js create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.shadowdom.css create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.shadowdom.js create mode 100644 client/dist/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide/content.css create mode 100644 client/dist/tinymce/skins/ui/oxide/content.inline.css create mode 100644 client/dist/tinymce/skins/ui/oxide/content.inline.js create mode 100644 client/dist/tinymce/skins/ui/oxide/content.inline.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide/content.js create mode 100644 client/dist/tinymce/skins/ui/oxide/content.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.css create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.js create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.min.css create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.shadowdom.css create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.shadowdom.js create mode 100644 client/dist/tinymce/skins/ui/oxide/skin.shadowdom.min.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/content.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/content.inline.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/content.inline.min.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/content.min.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/skin.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/skin.min.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/skin.shadowdom.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/skin.shadowdom.min.css create mode 100644 client/dist/tinymce/skins/ui/silverstripe/src/README.md create mode 100644 client/dist/tinymce/skins/ui/silverstripe/src/content.inline.less create mode 100644 client/dist/tinymce/skins/ui/silverstripe/src/content.less create mode 100644 client/dist/tinymce/skins/ui/silverstripe/src/skin.less create mode 100644 client/dist/tinymce/skins/ui/silverstripe/src/skin.shadowdom.less create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.inline.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.inline.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/content.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.inline.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.inline.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.inline.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/content.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.min.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.shadowdom.css create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.shadowdom.js create mode 100644 client/dist/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css create mode 100644 client/dist/tinymce/themes/silver/index.js create mode 100644 client/dist/tinymce/themes/silver/theme.js create mode 100644 client/dist/tinymce/themes/silver/theme.min.js create mode 100644 client/dist/tinymce/tinymce.d.ts create mode 100644 client/dist/tinymce/tinymce.js create mode 100644 client/dist/tinymce/tinymce.min.js create mode 100644 client/src/boot/index.js create mode 100644 client/src/boot/registerComponents.js create mode 100644 client/src/bundle.js create mode 100644 client/src/components/TinyMceHtmlEditorField/TinyMceHtmlEditorField.js create mode 100644 client/src/components/TinyMceHtmlEditorField/tests/TinyMceHtmlEditorField-test.js create mode 100644 client/src/entwine/TinyMceHtmlEditorField.js create mode 100644 client/src/lib/TinyMCEActionRegistrar.js create mode 100644 client/src/lib/tests/TinyMCEActionRegistrar-test.js create mode 100644 client/src/plugins/TinyMCE_ssembed.js create mode 100644 client/src/plugins/TinyMCE_sslink-anchor.js create mode 100644 client/src/plugins/TinyMCE_sslink-email.js create mode 100644 client/src/plugins/TinyMCE_sslink-external.js create mode 100644 client/src/plugins/TinyMCE_sslink-file.js create mode 100644 client/src/plugins/TinyMCE_sslink-internal.js create mode 100644 client/src/plugins/TinyMCE_sslink.js create mode 100644 client/src/plugins/TinyMCE_ssmedia.js create mode 100644 client/src/plugins/TinyMCE_ssmedia_sizepressets.js create mode 100644 client/src/styles/editor.scss create mode 100644 client/src/tinymce/README.txt create mode 100644 client/src/tinymce/skins/ui/silverstripe/content.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/content.inline.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/content.inline.min.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/content.min.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/skin.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/skin.min.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/skin.shadowdom.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/skin.shadowdom.min.css create mode 100644 client/src/tinymce/skins/ui/silverstripe/src/README.md create mode 100644 client/src/tinymce/skins/ui/silverstripe/src/content.inline.less create mode 100644 client/src/tinymce/skins/ui/silverstripe/src/content.less create mode 100644 client/src/tinymce/skins/ui/silverstripe/src/skin.less create mode 100644 client/src/tinymce/skins/ui/silverstripe/src/skin.shadowdom.less create mode 100644 client/tinymce_lang/README.md create mode 100644 client/tinymce_lang/ar.js create mode 100644 client/tinymce_lang/az.js create mode 100644 client/tinymce_lang/bg_BG.js create mode 100644 client/tinymce_lang/bn_BD.js create mode 100644 client/tinymce_lang/ca.js create mode 100644 client/tinymce_lang/cs.js create mode 100644 client/tinymce_lang/cy.js create mode 100644 client/tinymce_lang/da.js create mode 100644 client/tinymce_lang/de.js create mode 100644 client/tinymce_lang/dv.js create mode 100644 client/tinymce_lang/el.js create mode 100644 client/tinymce_lang/eo.js create mode 100644 client/tinymce_lang/es.js create mode 100644 client/tinymce_lang/es_MX.js create mode 100644 client/tinymce_lang/et.js create mode 100644 client/tinymce_lang/eu.js create mode 100644 client/tinymce_lang/fa.js create mode 100644 client/tinymce_lang/fi.js create mode 100644 client/tinymce_lang/fr_FR.js create mode 100644 client/tinymce_lang/ga.js create mode 100644 client/tinymce_lang/gl.js create mode 100644 client/tinymce_lang/he_IL.js create mode 100644 client/tinymce_lang/hi.js create mode 100644 client/tinymce_lang/hr.js create mode 100644 client/tinymce_lang/hu_HU.js create mode 100644 client/tinymce_lang/hy.js create mode 100644 client/tinymce_lang/id.js create mode 100644 client/tinymce_lang/is_IS.js create mode 100644 client/tinymce_lang/it.js create mode 100644 client/tinymce_lang/ja.js create mode 100644 client/tinymce_lang/kab.js create mode 100644 client/tinymce_lang/kk.js create mode 100644 client/tinymce_lang/ko_KR.js create mode 100644 client/tinymce_lang/ku.js create mode 100644 client/tinymce_lang/lt.js create mode 100644 client/tinymce_lang/lv.js create mode 100644 client/tinymce_lang/nb_NO.js create mode 100644 client/tinymce_lang/ne.js create mode 100644 client/tinymce_lang/nl.js create mode 100644 client/tinymce_lang/nl_BE.js create mode 100644 client/tinymce_lang/oc.js create mode 100644 client/tinymce_lang/pl.js create mode 100644 client/tinymce_lang/pt_BR.js create mode 100644 client/tinymce_lang/ro.js create mode 100644 client/tinymce_lang/ru.js create mode 100644 client/tinymce_lang/sk.js create mode 100644 client/tinymce_lang/sl_SI.js create mode 100644 client/tinymce_lang/sq.js create mode 100644 client/tinymce_lang/sr.js create mode 100644 client/tinymce_lang/sv_SE.js create mode 100644 client/tinymce_lang/ta.js create mode 100644 client/tinymce_lang/tg.js create mode 100644 client/tinymce_lang/th_TH.js create mode 100644 client/tinymce_lang/tr.js create mode 100644 client/tinymce_lang/ug.js create mode 100644 client/tinymce_lang/uk.js create mode 100644 client/tinymce_lang/vi.js create mode 100644 client/tinymce_lang/zh_Hans.js create mode 100644 composer.json create mode 100644 package.json create mode 100644 src/Extension/AdminInitExtension.php create mode 100644 src/TinyMCECombinedGenerator.php create mode 100644 src/TinyMCEConfig.php create mode 100644 src/TinyMCEScriptGenerator.php create mode 100644 tests/php/TinyMCECombinedGeneratorTest.php create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/editor.css create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/plugin1.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/plugin2.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/plugin3.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/plugin6.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/mycode/plugin8.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/langs/en.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/plugins/plugin4/langs/en.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/plugins/plugin4/plugin.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/plugins/plugin4/plugin.min.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/plugins/plugin5/plugin.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/themes/testtheme/langs/en.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/themes/testtheme/theme.js create mode 100644 tests/php/TinyMCECombinedGeneratorTest/tinymce/tinymce.min.js create mode 100644 tests/php/TinyMCEConfigTest.php create mode 100644 webpack.config.js create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..d633fdac --- /dev/null +++ b/.editorconfig @@ -0,0 +1,31 @@ +# For more information about the properties used in +# this file, please see the EditorConfig documentation: +# http://editorconfig.org/ + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,js,json,css,scss,eslintrc,feature}] +indent_size = 2 +indent_style = space + +# Don't perform any clean-up on thirdparty files + +[client/tinymce_lang/**] +trim_trailing_whitespace = false +insert_final_newline = false + +[client/src/tinymce/**] +trim_trailing_whitespace = false +insert_final_newline = false + +[composer.json] +indent_size = 4 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..42a6859f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,10 @@ +# Ignore dist files +client/dist/ + +# Ignore vendor +node_modules/ +thirdparty/ + +# Ignore language files (auto-generated) +client/lang/ +client/tinymce_lang/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..4b81cffb --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@silverstripe/eslint-config/.eslintrc'); diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bed15206 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.sass-cache +/vendor/ +/node_modules/ +/**/*.js.map +/**/*.css.map +yarn-error.log +composer.lock diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..3c032078 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 00000000..9e682ee8 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1 @@ +client/src/tinymce/* diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 00000000..ef7353b7 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1 @@ +module.exports = require('@silverstripe/eslint-config/.stylelintrc'); diff --git a/_config.php b/_config.php new file mode 100644 index 00000000..e227334e --- /dev/null +++ b/_config.php @@ -0,0 +1,53 @@ +setOptions([ + 'friendly_name' => 'Default CMS', + 'priority' => '50', + 'skin' => 'silverstripe', + // @TODO this came straight from admin but check if ssmedia and ssembed should be conditional or not + 'contextmenu' => "searchreplace | sslink anchor ssmedia ssembed inserttable | cell row column deletetable", + 'use_native_selects' => false, + 'extended_valid_elements' => "iframe[src|name|width|height|align|frameborder|marginwidth|marginheight|scrolling]," + . "object[width|height|data|type],param[name|value],map[class|name|id],area[shape|coords|href|target|alt]" + ]); + $editorConfig->insertButtonsAfter('sslink', 'anchor'); + + // Prepare list of plugins to enable + $moduleManifest = ModuleLoader::inst()->getManifest(); + $module = $moduleManifest->getModule('silverstripe/htmleditor-tinymce'); + $plugins = [ + 'image' => null, + 'anchor' => null, + 'sslink' => $module->getResource('client/dist/js/TinyMCE_sslink.js'), + 'sslinkexternal' => $module->getResource('client/dist/js/TinyMCE_sslink-external.js'), + 'sslinkemail' => $module->getResource('client/dist/js/TinyMCE_sslink-email.js'), + ]; + + // Add plugins for managing assets if silverstripe/asset-admin is installed + if ($moduleManifest->moduleExists('silverstripe/asset-admin')) { + $plugins += [ + 'ssmedia' => $module->getResource('client/dist/js/TinyMCE_ssmedia.js'), + 'ssembed' => $module->getResource('client/dist/js/TinyMCE_ssembed.js'), + 'sslinkfile' => $module->getResource('client/dist/js/TinyMCE_sslink-file.js'), + ]; + $editorConfig->insertButtonsAfter('table', 'ssmedia'); + $editorConfig->insertButtonsAfter('ssmedia', 'ssembed'); + } + + // Add internal link plugins if silverstripe/cms is installed + if ($moduleManifest->moduleExists('silverstripe/cms')) { + TinyMCEConfig::get('cms')->enablePlugins([ + 'sslinkinternal' => $module->getResource('client/dist/js/TinyMCE_sslink-internal.js'), + 'sslinkanchor' => $module->getResource('client/dist/js/TinyMCE_sslink-anchor.js'), + ]); + } + + $editorConfig->enablePlugins($plugins); +}); diff --git a/_config/config.yml b/_config/config.yml new file mode 100644 index 00000000..c2e9da72 --- /dev/null +++ b/_config/config.yml @@ -0,0 +1,25 @@ +--- +Name: tinymce-config +--- +SilverStripe\TinyMCE\TinyMCEConfig: + base_dir: 'silverstripe/htmleditor-tinymce:client/dist/tinymce' + lang_dir: 'silverstripe/htmleditor-tinymce:thirdparty/tinymce_lang' + editor_css: + - 'silverstripe/htmleditor-tinymce:client/dist/styles/editor.css' + image_size_presets: + - width: 600 + i18n: SilverStripe\TinyMCE\TinyMCEConfig.BEST_FIT + text: Best fit + name: bestfit + default: true + - i18n: SilverStripe\TinyMCE\TinyMCEConfig.ORIGINAL + text: Original + name: originalsize + +SilverStripe\Admin\FormSchemaController: + extensions: + TinyMceInit: 'SilverStripe\TinyMCE\Extension\AdminInitExtension' + +SilverStripe\Admin\LeftAndMain: + extra_requirements_javascript: + - 'silverstripe/htmleditor-tinymce: client/dist/js/bundle.js' diff --git a/_config/injector.yml b/_config/injector.yml new file mode 100644 index 00000000..8bbc4f46 --- /dev/null +++ b/_config/injector.yml @@ -0,0 +1,11 @@ +--- +Name: tinymce-injector +--- +SilverStripe\Core\Injector\Injector: + SilverStripe\Forms\HTMLEditor\HTMLEditorConfig: + class: SilverStripe\TinyMCE\TinyMCEConfig + SilverStripe\TinyMCE\TinyMCEScriptGenerator: '%$SilverStripe\TinyMCE\TinyMCECombinedGenerator' + SilverStripe\TinyMCE\TinyMCECombinedGenerator: + class: SilverStripe\TinyMCE\TinyMCECombinedGenerator + properties: + AssetHandler: '%$SilverStripe\Assets\Storage\GeneratedAssetHandler' diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 00000000..4f06b0cd --- /dev/null +++ b/babel.config.json @@ -0,0 +1,6 @@ +{ + "presets": [ + "@babel/preset-env", + "@babel/preset-react" + ] +} diff --git a/client/dist/js/TinyMCE_ssembed.js b/client/dist/js/TinyMCE_ssembed.js new file mode 100644 index 00000000..a89abceb --- /dev/null +++ b/client/dist/js/TinyMCE_ssembed.js @@ -0,0 +1 @@ +!function(){"use strict";var e={145:function(e){e.exports=ReactDomClient},207:function(e){e.exports=Injector},502:function(e){e.exports=ShortcodeSerialiser},594:function(e){e.exports=React},669:function(e){e.exports=jQuery},815:function(e){e.exports=i18n},984:function(e){e.exports=InsertEmbedModal}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}var r=u(n(669)),o=u(n(594)),i=n(145),a=n(207),d=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=c(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=o?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(r,i,a):r[i]=e[i]}return r.default=e,n&&n.set(e,r),r}(n(502)),s=u(n(984)),l=u(n(815));function c(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(c=function(e){return e?n:t})(e)}function u(e){return e&&e.__esModule?e:{default:e}}const p=(0,a.loadComponent)(s.default),m='div[data-shortcode="embed"]';(()=>{const e=e=>{const t=l.default._t("AssetAdmin.INSERT_VIA_URL","Insert media via URL"),n=l.default._t("AssetAdmin.EDIT_MEDIA","Edit media"),o=l.default._t("AssetAdmin.DELETE_MEDIA","Delete media"),i=l.default._t("AssetAdmin.MEDIA","Media");return e.addCommand("ssembed",(()=>{(0,r.default)(`#${e.id}`).entwine("ss").openEmbedDialog()})),e.addCommand("ssembed-delete",(()=>{const t=e.selection.getNode();e.dom.is(t,m)?t.remove():e.dom.is(t.parentNode,m)?t.parentNode.remove():console.error({error:"Unexpected selection - expected embed",selectedNode:t})})),e.ui.registry.addButton("ssembed",{tooltip:t,icon:"embed",onAction:()=>e.execCommand("ssembed"),stateSelector:m}),e.ui.registry.addMenuItem("ssembed",{text:i,icon:"embed",onAction:()=>e.execCommand("ssembed")}),e.ui.registry.addButton("ssembededit",{tooltip:n,icon:"edit-block",onAction:()=>e.execCommand("ssembed")}),e.ui.registry.addButton("ssembeddelete",{tooltip:o,icon:"remove",onAction:()=>e.execCommand("ssembed-delete")}),e.ui.registry.addContextToolbar("ssembed",{predicate:t=>e.dom.is(t,m),position:"node",scope:"node",items:"alignleft aligncenter alignright | ssembededit ssembeddelete"}),e.on("BeforeExecCommand",(t=>{const n=t.command,r=t.ui,o=t.value;"mceMedia"===n&&(t.preventDefault(),e.execCommand("ssembed",r,o))})),e.on("GetContent",(e=>{const t=(0,r.default)(`
${e.content}
`);t.find(m).each((function(){const e=(0,r.default)(this),t=e.find("img.placeholder");if(0===t.length)return e.removeAttr("data-url"),void e.removeAttr("data-shortcode");const n=e.find(".caption").text(),o=parseInt(t.attr("width"),10),i=parseInt(t.attr("height"),10),a=e.data("url"),s=(0,d.sanitiseShortCodeProperties)({url:a,thumbnail:t.prop("src"),class:e.prop("class"),width:isNaN(o)?null:o,height:isNaN(i)?null:i,caption:n}),l=d.default.serialise({name:"embed",properties:s,wrapped:!0,content:s.url});e.replaceWith(l)})),e.content=t.html()})),e.on("BeforeSetContent",(e=>{let t=e.content,n=d.default.match("embed",!0,t);for(;n;){const e=n.properties,o=(0,r.default)("
").attr("data-url",e.url||n.content).attr("data-shortcode","embed").addClass(e.class).addClass("ss-htmleditorfield-file embed"),i=(0,r.default)("").attr("src",e.thumbnail).addClass("placeholder");if(e.width&&i.attr("width",e.width),e.height&&i.attr("height",e.height),o.append(i),e.caption){const t=(0,r.default)("

").addClass("caption").text(e.caption);o.append(t)}t=t.replace(n.original,(0,r.default)("

").append(o).html()),n=d.default.match("embed",!0,t)}e.content=t})),{getMetadata(){return{name:"Silverstripe Embed",url:"https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield"}}}};tinymce.PluginManager.add("ssembed",(t=>e(t)))})(),r.default.entwine("ss",(e=>{e(".js-injector-boot #insert-embed-react__dialog-wrapper").entwine({Element:null,Data:{},ReactRoot:null,onunmatch(){this._clearModal()},_clearModal(){const e=this.getReactRoot();e&&(e.unmount(),this.setReactRoot(null))},open(){this._renderModal(!0)},close(){this.setData({}),this._renderModal(!1)},_renderModal(e){var t=this;const n=this.getOriginalAttributes();let r=this.getReactRoot();r||(r=(0,i.createRoot)(this[0])),r.render(o.default.createElement(p,{isOpen:e,onCreate:function(){return t._handleCreate(...arguments)},onInsert:function(){return t._handleInsert(...arguments)},onClosed:()=>this.close(),onLoadingError:function(){return t._handleLoadingError(...arguments)},bodyClassName:"modal__dialog",className:"insert-embed-react__dialog-wrapper",fileAttributes:n})),this.setReactRoot(r)},_handleLoadingError(){this.setData({}),this.open()},_handleInsert(e){const t=this.getData();this.setData(Object.assign({Url:t.Url},e)),this.insertRemote(),this.close()},_handleCreate(e){this.setData(Object.assign({},this.getData(),e)),this.open()},getOriginalAttributes(){const t=this.getData(),n=this.getElement();if(!n)return t;const r=e(n.getEditor().getSelectedNode());if(!r.length)return t;const o=r.closest(m).add(r.filter(m));if(!o.length)return t;const i=o.find("img.placeholder");if(0===i.length)return t;const a=o.find(".caption").text(),d=parseInt(i.width(),10),s=parseInt(i.height(),10);return{Url:o.data("url")||t.Url,CaptionText:a,PreviewUrl:i.attr("src"),Width:isNaN(d)?null:d,Height:isNaN(s)?null:s,Placement:this.findPosition(o.prop("class"))}},findPosition(e){if("string"!=typeof e)return"";const t=e.split(" ");return["leftAlone","center","rightAlone","left","right"].find((e=>t.indexOf(e)>-1))},insertRemote(){const t=this.getElement();if(!t)return!1;const n=t.getEditor();if(!n)return!1;const o=this.getData(),i=(0,r.default)("
").attr("data-url",o.Url).attr("data-shortcode","embed").addClass(o.Placement).addClass("ss-htmleditorfield-file embed"),a=(0,r.default)("").attr("src",o.PreviewUrl).addClass("placeholder");if(o.Width&&a.attr("width",o.Width),o.Height&&a.attr("height",o.Height),i.append(a),o.CaptionText){const e=(0,r.default)("

").addClass("caption").text(o.CaptionText);i.append(e)}const d=e(n.getSelectedNode());let s=e(null);return d.length&&(s=d.filter(m),0===s.length&&(s=d.closest(m)),0===s.length&&(s=d.filter("img.placeholder"))),s.length?s.replaceWith(i):(n.repaint(),n.insertContent(e("

").append(i.clone()).html(),{skip_undo:1})),n.addUndo(),n.repaint(),!0}})}))}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-anchor.js b/client/dist/js/TinyMCE_sslink-anchor.js new file mode 100644 index 00000000..e3a932ad --- /dev/null +++ b/client/dist/js/TinyMCE_sslink-anchor.js @@ -0,0 +1 @@ +!function(){"use strict";var t={40:function(t){t.exports=ReactRedux},127:function(t){t.exports=InsertLinkModal},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},502:function(t){t.exports=ShortcodeSerialiser},594:function(t){t.exports=React},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const n=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,i){const o=e.priority||50,r=n(i,t),s=this.getActions(t,i,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),s.find((t=>e.text===t.text))||(this.actions[r]=[...this.getActions(t,i,!1),{...e,priority:o}]),this}getActions(t,e){let i=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const o=n(e,t);return e&&this.actions[o]&&(i=[...i,...this.actions[o]]),i}getSortedActions(t,e){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,n).sort(((t,e)=>{const n=e.priority-t.priority;return n||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return n&&(e=n),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n},918:function(t){t.exports=AnchorSelectorActions}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,n),r.exports}!function(){var t=u(n(815)),e=u(n(671)),i=u(n(594)),o=n(145),r=n(40),s=u(n(669)),a=u(n(502)),d=n(127),l=n(207),c=n(918);function u(t){return t&&t.__esModule?t:{default:t}}const m="sslinkanchor",h={init(n){e.default.addAction("sslink",{text:t.default._t("CMS.LINKLABEL_ANCHOR","Anchor on a page"),onAction:t=>t.execCommand(m),priority:60},n.getParam("editorIdentifier")).addCommandWithUrlTest(m,/^\[sitetree_link.+]#[^#\]]+$/),n.addCommand(m,(()=>{const t=(0,s.default)(`#${n.id}`).entwine("ss"),e=Number((0,s.default)("#Form_EditForm_ID").val()||0),i=(0,s.default)(n.getBody()).find("[id],[name]").toArray().map((t=>t.id||t.name));ss.store.dispatch((0,c.updatedCurrentField)(e,i,n.id)),t.openLinkAnchorDialog()}))}},p="insert-link__dialog-wrapper--anchor",f=(0,l.provideInjector)((0,d.createInsertLinkModal)("SilverStripe\\Admin\\LeftAndMain","editorAnchorLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkAnchorDialog(){let t=e(`#${p}`);t.length||(t=e(`
`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${p}`).entwine({ReactRoot:null,renderModal(n){var s=this;const a=ss.store,d=this.getOriginalAttributes(),l=this.getRequireLinkText(),c=Number(e("#Form_EditForm_ID").val()||0);let u=this.getReactRoot();u||(u=(0,o.createRoot)(this[0]),this.setReactRoot(u)),u.render(i.default.createElement(r.Provider,{store:a},i.default.createElement(f,{isOpen:n,onInsert:function(){return s.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("CMS.LINK_ANCHOR","Link to an anchor on a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--anchor",fileAttributes:d,identifier:"Admin.InsertLinkAnchorModal",requireLinkText:l,currentPageID:c})))},buildAttributes(t){return{href:`${a.default.serialise({name:"sitetree_link",properties:{id:t.PageID}},!0)}${t.Anchor&&t.Anchor.length?`#${t.Anchor}`:""}`,target:t.TargetBlank?"_blank":"",title:t.Description}},getOriginalAttributes(){const t=this.getElement().getEditor(),n=e(t.getSelectedNode()),i=(n.attr("href")||"").split("#");if(!i[0])return{};const o=a.default.match("sitetree_link",!1,i[0]);return o?{PageID:o.properties.id?parseInt(o.properties.id,10):0,Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(m,(t=>h.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-email.js b/client/dist/js/TinyMCE_sslink-email.js new file mode 100644 index 00000000..5bd7ea24 --- /dev/null +++ b/client/dist/js/TinyMCE_sslink-email.js @@ -0,0 +1 @@ +!function(){"use strict";var t={127:function(t){t.exports=InsertLinkModal},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},594:function(t){t.exports=React},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const i=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,n){const o=e.priority||50,s=i(n,t),r=this.getActions(t,n,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),r.find((t=>e.text===t.text))||(this.actions[s]=[...this.getActions(t,n,!1),{...e,priority:o}]),this}getActions(t,e){let n=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const o=i(e,t);return e&&this.actions[o]&&(n=[...n,...this.actions[o]]),n}getSortedActions(t,e){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,i).sort(((t,e)=>{const i=e.priority-t.priority;return i||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const i=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return i&&(e=i),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n}},e={};function i(n){var o=e[n];if(void 0!==o)return o.exports;var s=e[n]={exports:{}};return t[n](s,s.exports,i),s.exports}!function(){var t=d(i(815)),e=d(i(671)),n=d(i(594)),o=i(145),s=d(i(669)),r=i(127),a=i(207);function d(t){return t&&t.__esModule?t:{default:t}}const l="sslinkemail",c={init(i){e.default.addAction("sslink",{text:t.default._t("Admin.LINKLABEL_EMAIL","Link to email address"),onAction:t=>t.execCommand(l),priority:51},i.getParam("editorIdentifier")).addCommandWithUrlTest(l,/^mailto:/),i.addCommand(l,(()=>{window.jQuery(`#${i.id}`).entwine("ss").openLinkEmailDialog()}))}},m="insert-link__dialog-wrapper--email",u=(0,a.loadComponent)((0,r.createInsertLinkModal)("SilverStripe\\Admin\\LeftAndMain","EditorEmailLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkEmailDialog(){let t=e(`#${m}`);t.length||(t=e(`
`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${m}`).entwine({ReactRoot:null,renderModal(e){var i=this;const s=this.getOriginalAttributes(),r=this.getRequireLinkText();let a=this.getReactRoot();a||(a=(0,o.createRoot)(this[0]),this.setReactRoot(a)),a.render(n.default.createElement(u,{isOpen:e,onInsert:function(){return i.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("Admin.LINK_EMAIL","Insert email link"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--email",fileAttributes:s,identifier:"Admin.InsertLinkEmailModal",requireLinkText:r}))},getOriginalAttributes(){const t=this.getElement().getEditor(),i=e(t.getSelectedNode()),n=(i.attr("href")||"").split("?");let o=n[0].replace(/^mailto:/,"").split("?")[0];o.match(/.+@.+\..+/)||(o="");const s=n[1]?n[1].match(/subject=([^&]+)/):"";return{Link:o,Subject:s?decodeURIComponent(s[1]):"",Description:i.attr("title")}},buildAttributes(t){const e=this._super(t);let i="",n=e.href.replace(/^mailto:/,"").split("?")[0];return n.match(/.+@.+\..+/)||(n=""),n&&(i=`mailto:${n}`),i&&t.Subject&&(i=`${i}?subject=${encodeURIComponent(t.Subject)}`),e.href=i,delete e.target,e}})})),tinymce.PluginManager.add(l,(t=>c.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-external.js b/client/dist/js/TinyMCE_sslink-external.js new file mode 100644 index 00000000..120b00b6 --- /dev/null +++ b/client/dist/js/TinyMCE_sslink-external.js @@ -0,0 +1 @@ +!function(){"use strict";var t={127:function(t){t.exports=InsertLinkModal},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},594:function(t){t.exports=React},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const n=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,i){const o=e.priority||50,s=n(i,t),r=this.getActions(t,i,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),r.find((t=>e.text===t.text))||(this.actions[s]=[...this.getActions(t,i,!1),{...e,priority:o}]),this}getActions(t,e){let i=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const o=n(e,t);return e&&this.actions[o]&&(i=[...i,...this.actions[o]]),i}getSortedActions(t,e){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,n).sort(((t,e)=>{const n=e.priority-t.priority;return n||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return n&&(e=n),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,n),s.exports}!function(){var t=l(n(815)),e=l(n(671)),i=l(n(594)),o=n(145),s=l(n(669)),r=n(127),a=n(207);function l(t){return t&&t.__esModule?t:{default:t}}const d={init(n){e.default.addAction("sslink",{text:t.default._t("Admin.LINKLABEL_EXTERNALURL","Link to external URL"),onAction:t=>t.execCommand("sslinkexternal"),priority:70},n.getParam("editorIdentifier")),n.addCommand("sslinkexternal",(()=>{window.jQuery(`#${n.id}`).entwine("ss").openLinkExternalDialog()}))}},c="insert-link__dialog-wrapper--external",u=(0,a.loadComponent)((0,r.createInsertLinkModal)("SilverStripe\\Admin\\LeftAndMain","EditorExternalLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkExternalDialog(){let t=e(`#${c}`);t.length||(t=e(`
`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${c}`).entwine({ReactRoot:null,renderModal(e){var n=this;const s=this.getOriginalAttributes(),r=this.getRequireLinkText();let a=this.getReactRoot();a||(a=(0,o.createRoot)(this[0]),this.setReactRoot(a)),a.render(i.default.createElement(u,{isOpen:e,onInsert:function(){return n.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("Admin.LINK_EXTERNAL","Insert external link"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--external",fileAttributes:s,identifier:"Admin.InsertLinkExternalModal",requireLinkText:r}))},buildAttributes(t){const e=this._super(t);let n=e.href;return n.match(/:\/\//)||(n=`${window.location.protocol}//${n}`),n=n.replace(/.*:\/\/(#.*)$/,"$1"),n.match(/:\/\/$/)&&(n=""),e.href=n,e}})})),tinymce.PluginManager.add("sslinkexternal",(t=>d.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-file.js b/client/dist/js/TinyMCE_sslink-file.js new file mode 100644 index 00000000..5ffd52dd --- /dev/null +++ b/client/dist/js/TinyMCE_sslink-file.js @@ -0,0 +1 @@ +!function(){"use strict";var t={64:function(t){t.exports=AssetAdminModalActions},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},502:function(t){t.exports=ShortcodeSerialiser},594:function(t){t.exports=React},643:function(t){t.exports=InsertMediaModal},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const n=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,i){const r=e.priority||50,o=n(i,t),s=this.getActions(t,i,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),s.find((t=>e.text===t.text))||(this.actions[o]=[...this.getActions(t,i,!1),{...e,priority:r}]),this}getActions(t,e){let i=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const r=n(e,t);return e&&this.actions[r]&&(i=[...i,...this.actions[r]]),i}getSortedActions(t,e){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,n).sort(((t,e)=>{const n=e.priority-t.priority;return n||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return n&&(e=n),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n}},e={};function n(i){var r=e[i];if(void 0!==r)return r.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}!function(){var t=f(n(815)),e=f(n(671)),i=f(n(594)),r=n(145),o=f(n(669)),s=f(n(502)),a=f(n(643)),l=u(n(207)),d=u(n(64));function c(t){if("function"!=typeof WeakMap)return null;var e=new WeakMap,n=new WeakMap;return(c=function(t){return t?n:e})(t)}function u(t,e){if(!e&&t&&t.__esModule)return t;if(null===t||"object"!=typeof t&&"function"!=typeof t)return{default:t};var n=c(e);if(n&&n.has(t))return n.get(t);var i={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in t)if("default"!==o&&{}.hasOwnProperty.call(t,o)){var s=r?Object.getOwnPropertyDescriptor(t,o):null;s&&(s.get||s.set)?Object.defineProperty(i,o,s):i[o]=t[o]}return i.default=t,n&&n.set(t,i),i}function f(t){return t&&t.__esModule?t:{default:t}}const p="sslinkfile",m={init(n){e.default.addAction("sslink",{text:t.default._t("AssetAdmin.LINKLABEL_FILE","Link to a file"),onAction:t=>t.execCommand(p),priority:80},n.getParam("editorIdentifier")).addCommandWithUrlTest(p,/^\[file_link/),n.addCommand(p,(()=>{(0,o.default)(`#${n.id}`).entwine("ss").openLinkFileDialog()}))}},h="insert-link__dialog-wrapper--file",g=(0,l.loadComponent)(a.default);o.default.entwine("ss",(t=>{t("textarea.htmleditor").entwine({openLinkFileDialog(){let e=t(`#${h}`);e.length||(e=t(`
`),t("body").append(e)),e.addClass("insert-link__dialog-wrapper"),e.setElement(this),e.open()}}),t(`.js-injector-boot #${h}`).entwine({ReactRoot:null,renderModal(t){var e=this;const{dispatch:n}=l.default.reducer.store;n(d.initFormStack("insert-link","admin"));const o=this.getOriginalAttributes(),s=this.getFolderId(),a=this.getRequireLinkText();let c=this.getReactRoot();c||(c=(0,r.createRoot)(this[0]),this.setReactRoot(c)),c.render(i.default.createElement(g,{isOpen:t,type:"insert-link",folderId:s,onInsert:function(){return e.handleInsert(...arguments)},onClosed:()=>{n(d.reset()),this.close()},title:!1,bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:o,requireLinkText:a}))},buildAttributes(t){return{href:`${s.default.serialise({name:"file_link",properties:{id:t.ID}},!0)}${t.Anchor&&t.Anchor.length?`#${t.Anchor}`:""}`,target:t.TargetBlank?"_blank":"",title:t.Description}},getFolderId(){const t=this.getElement();if(!t)return null;const e=Number(t.data("config").upload_folder_id);return isNaN(e)?null:e},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),i=(n.attr("href")||"").split("#");if(!i[0])return{};const r=s.default.match("file_link",!1,i[0]);return r?{ID:r.properties.id?parseInt(r.properties.id,10):0,Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(p,(t=>m.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-internal.js b/client/dist/js/TinyMCE_sslink-internal.js new file mode 100644 index 00000000..be5aa402 --- /dev/null +++ b/client/dist/js/TinyMCE_sslink-internal.js @@ -0,0 +1 @@ +!function(){"use strict";var t={40:function(t){t.exports=ReactRedux},127:function(t){t.exports=InsertLinkModal},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},502:function(t){t.exports=ShortcodeSerialiser},594:function(t){t.exports=React},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const n=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,i){const r=e.priority||50,o=n(i,t),s=this.getActions(t,i,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),s.find((t=>e.text===t.text))||(this.actions[o]=[...this.getActions(t,i,!1),{...e,priority:r}]),this}getActions(t,e){let i=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const r=n(e,t);return e&&this.actions[r]&&(i=[...i,...this.actions[r]]),i}getSortedActions(t,e){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,n).sort(((t,e)=>{const n=e.priority-t.priority;return n||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return n&&(e=n),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n}},e={};function n(i){var r=e[i];if(void 0!==r)return r.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}!function(){var t=c(n(815)),e=c(n(671)),i=c(n(594)),r=n(145),o=n(40),s=c(n(669)),a=c(n(502)),d=n(127),l=n(207);function c(t){return t&&t.__esModule?t:{default:t}}const u="sslinkinternal",m={init(n){e.default.addAction("sslink",{text:t.default._t("CMS.LINKLABEL_PAGE","Page on this site"),onAction:t=>t.execCommand(u),priority:90},n.getParam("editorIdentifier")).addCommandWithUrlTest(u,/^\[sitetree_link.+]$/),n.addCommand(u,(()=>{(0,s.default)(`#${n.id}`).entwine("ss").openLinkInternalDialog()}))}},p="insert-link__dialog-wrapper--internal",h=(0,l.provideInjector)((0,d.createInsertLinkModal)("SilverStripe\\Admin\\LeftAndMain","editorInternalLink"));s.default.entwine("ss",(e=>{e("textarea.htmleditor").entwine({openLinkInternalDialog(){let t=e(`#${p}`);t.length||(t=e(`
`),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e(`#${p}`).entwine({ReactRoot:null,renderModal(e){var n=this;const s=ss.store,a=this.getOriginalAttributes(),d=this.getRequireLinkText();let l=this.getReactRoot();l||(l=(0,r.createRoot)(this[0]),this.setReactRoot(l)),l.render(i.default.createElement(o.Provider,{store:s},i.default.createElement(h,{isOpen:e,onInsert:function(){return n.handleInsert(...arguments)},onClosed:()=>this.close(),title:t.default._t("CMS.LINK_PAGE","Link to a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:a,identifier:"Admin.InsertLinkInternalModal",requireLinkText:d})))},buildAttributes(t){return{href:`${a.default.serialise({name:"sitetree_link",properties:{id:t.PageID}},!0)}${t.Anchor&&t.Anchor.length?`#${t.Anchor}`:""}`,target:t.TargetBlank?"_blank":"",title:t.Description}},getOriginalAttributes(){const t=this.getElement().getEditor(),n=e(t.getSelectedNode()),i=(n.attr("href")||"").split("#");if(!i[0])return{};const r=a.default.match("sitetree_link",!1,i[0]);return r?{PageID:r.properties.id?parseInt(r.properties.id,10):0,Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})})),tinymce.PluginManager.add(u,(t=>m.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink.js b/client/dist/js/TinyMCE_sslink.js new file mode 100644 index 00000000..8d6b0b28 --- /dev/null +++ b/client/dist/js/TinyMCE_sslink.js @@ -0,0 +1 @@ +!function(){"use strict";var t={502:function(t){t.exports=ShortcodeSerialiser},669:function(t){t.exports=jQuery},671:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;const n=(t,e)=>t?`${t}.${e}`:e;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(t,e,i){const o=e.priority||50,s=n(i,t),r=this.getActions(t,i,!0);return e.type="menuitem",e.hasOwnProperty("onclick")&&(e.onAction=e.onclick,delete e.onclick),r.find((t=>e.text===t.text))||(this.actions[s]=[...this.getActions(t,i,!1),{...e,priority:o}]),this}getActions(t,e){let i=e&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[t]?[]:this.actions[t];const o=n(e,t);return e&&this.actions[o]&&(i=[...i,...this.actions[o]]),i}getSortedActions(t,e){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(t,e,n).sort(((t,e)=>{const n=e.priority-t.priority;return n||(t.text.toLocaleLowerCase()>e.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(t,e){return this.editorCommandsToUrlTestsMap[t]=e,this}setDefaultCommand(t){return this.defaultCommand=t,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(t){let e=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((e=>this.editorCommandsToUrlTestsMap[e]&&this.editorCommandsToUrlTestsMap[e].test(t)));return n&&(e=n),e}};e.default=window.ss.tinymceactions},815:function(t){t.exports=i18n}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,n),s.exports}!function(){var t=s(n(671)),e=s(n(669)),i=n(502),o=s(n(815));function s(t){return t&&t.__esModule?t:{default:t}}const r={init(n){function i(){return t.default.getSortedActions("sslink",n.getParam("editorIdentifier"),!0).map((t=>Object.assign({},t,{onAction:()=>t.onAction(n)})))}const s=navigator.platform.toUpperCase().includes("MAC")?"⌘":"Ctrl",r=o.default._t("Admin.INSERT_LINK","Insert link"),a=o.default.inject(o.default._t("Admin.INSERT_LINK_WITH_SHORTCUT","Insert link {shortcut}"),{shortcut:`[${s}+K]`});return n.addShortcut("Meta+k","Open link menu",(()=>{(0,e.default)(`[aria-label^="${r}"] > button`,n.container).first().click()})),n.ui.registry.addMenuButton("sslink",{icon:"link",tooltip:a,fetch:t=>t(i())}),n.ui.registry.addNestedMenuItem("sslink",{icon:"link",text:r,getSubmenuItems:i}),n.ui.registry.addButton("sslink-edit",{text:o.default._t("Admin.EDIT_LINK","Edit link"),onAction:function(){const i=(0,e.default)(tinymce.activeEditor.selection.getNode()).closest("a");tinymce.activeEditor.selection.select(i[0]);const o=tinymce.activeEditor.selection.getNode().getAttribute("href");o&&n.execCommand(t.default.getEditorCommandFromUrl(o))}}),n.ui.registry.addButton("sslink-remove",{text:o.default._t("Admin.REMOVE_LINK","Remove link"),onAction:()=>this.handleRemoveLinkClick(n)}),n.ui.registry.addContextToolbar("sslink",{predicate:t=>n.dom.is(t,"a[href]"),position:"node",scope:"node",items:"sslink-edit sslink-remove"}),{getMetadata(){return{name:"Silverstripe Link",url:"https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield"}}}},handleRemoveLinkClick(t){const e=t.execCommand("unlink"),n=t.selection.getNode();return n&&void 0!==n.normalize&&n.normalize(),e}};e.default.entwine("ss",(t=>{t(".insert-link__dialog-wrapper").entwine({Element:null,Data:{},Bookmark:null,onunmatch(){this._clearModal()},_clearModal(){const t=this.getReactRoot();t&&(t.unmount(),this.setReactRoot(null))},open(){const t=this.getElement().getEditor().getInstance();this.setBookmark(t.selection.getBookmark(2,!0)),this.renderModal(!0)},close(){this.setData({}),this.renderModal(!1)},renderModal(){},checkNodeMatches(t,e){return t===e||1===e.children.length&&t===e.children[0]},linkCanWrapSelection(t,e){const n=t.getSelection()||"",i=e.getNode();if(n)return""!==n.trim();const o=document.createElement(i.nodeName);if(o.textContent="Check the outer HTML",o.outerHTML.includes("Check the outer HTML"))return!1;if(this.checkNodeMatches(i,e.getSel().focusNode)&&this.checkNodeMatches(i,e.getSel().anchorNode)){if(1===tinymce.activeEditor.dom.createFragment(`${i.outerHTML}`).childNodes.length)return!0}return!1},getRequireLinkText(){const e=this.getElement().getEditor();let n=e.getInstance().selection;const i=t(n.getNode()).closest("a");e.getInstance().selection.select(i[0]),n=e.getInstance().selection;const o=this.linkCanWrapSelection(e,n);return"A"!==n.getNode().tagName&&!o},handleInsert(t){this.getElement().getEditor().getInstance().selection.moveToBookmark(this.getBookmark());const e=this.buildAttributes(t),n=(0,i.createHTMLSanitiser)()(t.Text);return this.insertLinkInEditor(e,n),this.close(),Promise.resolve()},buildAttributes(t){let{Anchor:e,Link:n,TargetBlank:i,Description:o}=t,s=e&&e.length?`#${e}`:"";s=s.replace(/^#+/,"#");return{href:`${n}${s}`,target:i?"_blank":"",title:o}},insertLinkInEditor(t,e){const n=this.getElement().getEditor();n.insertLink(t,null,e),n.addUndo(),n.repaint();const i=n.getInstance().selection;setTimeout((()=>i&&i.collapse()),0)},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),i=(n.attr("href")||"").split("#");return{Link:i[0]||"",Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}}})})),tinymce.PluginManager.add("sslink",(t=>r.init(t)))}()}(); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_ssmedia.js b/client/dist/js/TinyMCE_ssmedia.js new file mode 100644 index 00000000..2da9622a --- /dev/null +++ b/client/dist/js/TinyMCE_ssmedia.js @@ -0,0 +1 @@ +!function(){"use strict";var t={64:function(t){t.exports=AssetAdminModalActions},145:function(t){t.exports=ReactDomClient},207:function(t){t.exports=Injector},502:function(t){t.exports=ShortcodeSerialiser},594:function(t){t.exports=React},643:function(t){t.exports=InsertMediaModal},669:function(t){t.exports=jQuery},759:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.imageSizePresetButtons=function(t,e){return e.map((e=>function(t,e){const{name:i,width:n,text:a}=e,r=`ssmedia${i}`;t.on("init",(()=>{t.formatter.register(r,{selector:"img",attributes:{width:n?n.toString():""}})}));const o=()=>{let e=t.selection.getNode();return"IMG"!==e.tagName&&e.children.item("img")&&(e=e.children.item("img")),e&&"IMG"===e.tagName?e:void 0},s=t=>{const e=o();t.disabled(!(!e||!n)&&e.naturalWidth{if(t.formatter.match(r))return!0;const e=o();if(!n&&e){const t=e.getAttribute("width");return!t||t.toString()===e.naturalWidth.toString()}return!1},l=e=>{const i=e.target,a=()=>{i.active(d())};if(t.on("NodeChange",(()=>{s(i),a()})),s(i),t.formatter&&(t.formatter.formatChanged(r,a),d())){t.formatter.apply(r);const e=o();e&&e.setAttribute("width",n||e.naturalWidth)}},c=()=>{const e=o();e&&(e.removeAttribute("height"),e.removeAttribute("width"),t.formatter.apply(r),n?e.setAttribute("height",e.clientHeight):(e.setAttribute("width",e.naturalWidth),e.setAttribute("height",e.naturalHeight)))};return t.ui.registry.addButton(r,{text:a,onAction:c,onPostRender:l}),r}(t,e)))}},815:function(t){t.exports=i18n}},e={};function i(n){var a=e[n];if(void 0!==a)return a.exports;var r=e[n]={exports:{}};return t[n](r,r.exports,i),r.exports}var n=p(i(669)),a=p(i(815)),r=p(i(594)),o=i(145),s=g(i(207)),d=p(i(643)),l=g(i(502)),c=g(i(64)),u=i(759);function m(t){if("function"!=typeof WeakMap)return null;var e=new WeakMap,i=new WeakMap;return(m=function(t){return t?i:e})(t)}function g(t,e){if(!e&&t&&t.__esModule)return t;if(null===t||"object"!=typeof t&&"function"!=typeof t)return{default:t};var i=m(e);if(i&&i.has(t))return i.get(t);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var r in t)if("default"!==r&&{}.hasOwnProperty.call(t,r)){var o=a?Object.getOwnPropertyDescriptor(t,r):null;o&&(o.get||o.set)?Object.defineProperty(n,r,o):n[r]=t[r]}return n.default=t,i&&i.set(t,n),n}function p(t){return t&&t.__esModule?t:{default:t}}const f=(0,s.loadComponent)(d.default),h='img[data-shortcode="image"]';(()=>{const t={init(t){const e=a.default._t("AssetAdmin.INSERT_FROM_FILES","Insert from Files"),i=a.default._t("AssetAdmin.EDIT_IMAGE","Edit image"),r=a.default._t("AssetAdmin.DELETE_IMAGE","Delete image"),o=a.default._t("AssetAdmin.FILE","File");t.addCommand("ssmedia",(()=>{(0,n.default)(`#${t.id}`).entwine("ss").openMediaDialog()})),t.addCommand("ssmedia-delete",(()=>{const e=t.selection.getNode();t.dom.is(e,h)?e.remove():console.error({error:"Unexpected selection - expected image",selectedNode:e})})),t.ui.registry.addButton("ssmedia",{tooltip:e,icon:"image",onAction:()=>t.execCommand("ssmedia"),stateSelector:h}),t.ui.registry.addMenuItem("ssmedia",{text:o,icon:"image",onAction:()=>t.execCommand("ssmedia")}),t.ui.registry.addButton("ssmediaedit",{tooltip:i,icon:"edit-block",onAction:()=>t.execCommand("ssmedia")}),t.ui.registry.addButton("ssmediadelete",{tooltip:r,icon:"remove",onAction:()=>t.execCommand("ssmedia-delete")});const s=t.getParam("image_size_presets");let d=[];return s&&(d=(0,u.imageSizePresetButtons)(t,s)),t.ui.registry.addContextToolbar("ssmedia",{predicate:e=>t.dom.is(e,h),position:"node",scope:"node",items:`${d.join(" ")} | ssmediaedit ssmediadelete`}),t.on("BeforeExecCommand",(e=>{const i=e.command,n=e.ui,a=e.value;"mceEditImage"!==i&&"mceImage"!==i||(e.preventDefault(),t.execCommand("ssmedia",n,a))})),t.on("GetContent",(t=>{const e=(0,n.default)(`
${t.content}
`);e.find(h).add(e.filter(h)).each((function(){const t=(0,n.default)(this),e={src:t.attr("src"),id:t.data("id"),width:t.attr("width"),height:t.attr("height"),class:t.attr("class"),title:t.attr("title"),alt:t.attr("alt"),loading:t.data("loading")},i=l.default.serialise({name:"image",properties:(0,l.sanitiseShortCodeProperties)(e),wrapped:!1});t.replaceWith(i)})),t.content="",e.each((function(){void 0!==this.innerHTML&&(t.content+=this.innerHTML)}))})),t.on("BeforeSetContent",(t=>{let e=t.content,i=l.default.match("image",!1,e);for(;i;){const t=i.properties,a=(0,n.default)("").attr(Object.assign({},t,{id:void 0,"data-id":t.id,"data-shortcode":"image","data-loading":t.loading})).addClass("ss-htmleditorfield-file image");e=e.replace(i.original,(0,n.default)("
").append(a).html()),i=l.default.match("image",!1,e)}t.content=e})),{getMetadata(){return{name:"Silverstripe Media",url:"https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield"}}}}};tinymce.PluginManager.add("ssmedia",(e=>t.init(e)))})(),n.default.entwine("ss",(t=>{t(".js-injector-boot #insert-media-react__dialog-wrapper").entwine({Element:null,Data:{},ReactRoot:null,onunmatch(){this._clearModal()},_clearModal(){const t=this.getReactRoot();t&&(t.unmount(),this.setReactRoot(null))},open(){const{dispatch:t}=s.default.reducer.store;t(c.initFormStack("insert-media","admin"));const e=tinymce.activeEditor.getParam("image_size_presets");t(c.defineImageSizePresets(e)),this._renderModal(!0)},close(){const{dispatch:t}=s.default.reducer.store;t(c.reset()),this._renderModal(!1)},_renderModal(t){var e=this;const{url:i,...n}=this.getOriginalAttributes(),a=n.hasOwnProperty("ID")&&null!==n.ID,s=this.getFolderId(),d=this.getElement().getEditor(),l=d.getInstance().selection,c=d.getSelection(),u=l.getNode().tagName,m="A"!==u&&("IMG"===u||""===c.trim());let g=this.getReactRoot();g||(g=(0,o.createRoot)(this[0])),g.render(r.default.createElement(f,{title:!1,isOpen:t,folderId:s,onInsert:function(){return e._handleInsert(...arguments)},onClosed:()=>this.close(),bodyClassName:"modal__dialog",className:"insert-media-react__dialog-wrapper",requireLinkText:m,fileAttributes:n,fileSelected:a})),this.setReactRoot(g)},_handleInsert(t,e){let i=!1;this.setData(Object.assign({},t,e));try{let t=null;if(t=e?e.category:"image","image"===t)i=this.insertImage();else i=this.insertFile()}catch(t){this.statusMessage(t,"bad")}return i&&this.close(),Promise.resolve()},getFolderId(){const t=this.getElement();if(!t)return null;const e=Number(t.data("config").upload_folder_id);return isNaN(e)?null:e},getOriginalAttributes(){const e=this.getElement();if(!e)return{};const i=e.getEditor().getSelectedNode();if(!i)return{};const n=t(i),a=(n.attr("href")||"").split("#");if(a[0]){const t=l.default.match("file_link",!1,a[0]);if(t)return{ID:t.properties.id?parseInt(t.properties.id,10):0,Anchor:a[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}}const r=n.parent(".captionImage").find(".caption"),o={url:n.attr("src"),AltText:n.attr("alt"),Width:n.attr("width"),Height:n.attr("height"),Loading:n.attr("data-loading"),TitleTooltip:n.attr("title"),Alignment:this.findPosition(n.attr("class")),Caption:r.text(),ID:n.attr("data-id")};return["Width","Height","ID"].forEach((t=>{o[t]="string"==typeof o[t]?parseInt(o[t],10):null})),o},findPosition(t){if("string"!=typeof t)return"";const e=t.split(" ");return["leftAlone","center","rightAlone","left","right"].find((t=>e.indexOf(t)>-1))},getAttributes(){const t=this.getData();return{src:t.url,alt:t.AltText,width:t.Width,height:t.Height,title:t.TitleTooltip,class:t.Alignment,"data-id":t.ID,"data-shortcode":"image","data-loading":t.Loading}},getExtraData(){const t=this.getData();return{CaptionText:t&&t.Caption}},insertFile(){const e=this.getData(),i=this.getElement().getEditor(),n=t(i.getSelectedNode()),a=l.default.serialise({name:"file_link",properties:{id:e.ID}},!0);let r=i.getSelection()||e.Text||e.filename;n.is("a")&&n.html()&&(r="");const o={href:a,target:e.TargetBlank?"_blank":"",title:e.Description};if(n.is("img")){r=e.Text||e.filename;const a=t("").attr(o).text(r);n.replaceWith(a),i.addUndo(),i.repaint()}else this.insertLinkInEditor(o,r);return!0},insertImage(){const e=this.getElement();if(!e)return!1;const i=e.getEditor();if(!i)return!1;const n=t(i.getSelectedNode()),a=this.getAttributes(),r=this.getExtraData();let o=n&&n.is("img,a")?n:null;o&&o.parent().is(".captionImage")&&(o=o.parent());const s=n&&n.is("img")?n:t("");s.attr(a).addClass("ss-htmleditorfield-file image");let d=s.parent(".captionImage"),l=d.find(".caption");r.CaptionText?(d.length||(d=t("
")),d.attr("class",`captionImage ${a.class}`).removeAttr("data-mce-style").width(a.width),l.length||(l=t('

').appendTo(d)),l.attr("class",`caption ${a.class}`).text(r.CaptionText)):(d=null,l=null);const c=d||s;return o&&o.not(c).length&&o.replaceWith(c),d&&d.prepend(s),o||(i.repaint(),i.insertContent(t("
").append(c).html(),{skip_undo:1})),i.addUndo(),i.repaint(),!0},statusMessage(e,i){const a=t("
").text(e).html();n.default.noticeAdd({text:a,type:i,stayTime:5e3,inEffect:{left:"0",opacity:"show"}})}})}))}(); \ No newline at end of file diff --git a/client/dist/js/bundle.js b/client/dist/js/bundle.js new file mode 100644 index 00000000..271d8b8b --- /dev/null +++ b/client/dist/js/bundle.js @@ -0,0 +1 @@ +(function(){var __webpack_modules__={38:function(e,t,n){"use strict";var r,o=(r=n(121))&&r.__esModule?r:{default:r};document.addEventListener("DOMContentLoaded",(()=>{(0,o.default)()}))},121:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=i(n(207)),o=i(n(517));function i(e){return e&&e.__esModule?e:{default:e}}t.default=()=>{r.default.component.registerMany({TinyMceHtmlEditorField:o.default})}},160:function(e,t,n){"use strict";e.exports=function(){if("object"==typeof globalThis)return globalThis;var e;try{e=this||new Function("return this")()}catch(e){if("object"==typeof window)return window;if("object"==typeof self)return self;if(void 0!==n.g)return n.g}return e}()},207:function(e){"use strict";e.exports=Injector},227:function(__unused_webpack_module,__unused_webpack_exports,__webpack_require__){"use strict";var _jquery=_interopRequireDefault(__webpack_require__(669)),_lodash=_interopRequireDefault(__webpack_require__(912));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const ss=void 0!==window.ss?window.ss:{};ss.editorWrappers.tinyMCE=function(){let editorID;return{init(e){editorID=e,this.create()},destroy(){tinymce.EditorManager.execCommand("mceRemoveEditor",!1,editorID)},getInstance(){return tinymce.EditorManager.get(editorID)},onopen(){},onclose(){},setHeight(e,t){if(void 0!==t&&e.target&&e.target.iframeElement){e.target.iframeElement.height=""!==t?"auto":t;const n=e.target.iframeElement.closest(".tox-sidebar-wrap");n&&(n.style.height=t)}},getRawConfig(){const e=`#${editorID}`;return(0,_jquery.default)(e).data("config")},getConfig(){const e=this.getRawConfig(),t=e.row_height?e.row_height:void 0,n=this;return e.selector=`#${editorID}`,e.setup=function(e){e.on("change",(()=>{n.save()})),e.on("init",(e=>{n.setHeight(e,t)})),e.on("ResizeEditor",(e=>{n.setHeight(e,"")}))},e},save(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const t=this.getInstance();t.save(),e.silent||((0,_jquery.default)(t.getElement()).trigger("change"),t.getElement().dispatchEvent(new Event("input",{bubbles:!0})))},create(){let e,t,n;function r(r){const o=r.target;!e||(new Date-e)/100>500?(n=(0,_jquery.default)(o).scrollTop(),(0,_jquery.default)(".mce-floatpanel").css("opacity","0")):window.clearTimeout(t),e=new Date,t=window.setTimeout((()=>function(t,n){const r=(0,_jquery.default)(t).scrollTop();(0,_jquery.default)(".mce-floatpanel").each(((e,t)=>{const o=parseFloat(t.style.top);(0,_jquery.default)(t).css("top",o-(r-n)+"px")})),(0,_jquery.default)(".mce-floatpanel").css("opacity","1"),e=void 0}(o,n)),500)}const o=this.getConfig();void 0!==o.baseURL&&(tinymce.EditorManager.baseURL=o.baseURL),o.skin=o.skin||"silverstripe",tinymce.init(o).then((e=>{if(e.length>0&&e[0].container){(0,_jquery.default)(e[0].container).closest(".panel--scrollable").on("scroll",(e=>r(e)))}}))},repaint(){},isDirty(){return this.getInstance().isDirty()},prepValueForChangeTracker(e){const t=_jquery.default.extend({forced_root_block:"p"},this.getRawConfig()),n=tinymce.html.Serializer(t),r=tinymce.html.DomParser(t);return n.serialize(r.parse(e))},getContent(){return this.getInstance().getContent()},getSelection(){return this.getInstance().selection.getSel().toString()||""},getDOM(){return this.getInstance().getElement()},getContainer(){return this.getInstance().getContainer()},getSelectedNode(){return this.getInstance().selection.getNode()},selectNode(e){this.getInstance().selection.select(e)},setContent(e,t){this.getInstance().setContent(e,t)},insertContent(e,t){this.getInstance().insertContent(e,t)},replaceContent(e,t){this.getInstance().execCommand("mceReplaceContent",!1,e,t)},insertLink(e,t,n){if(n){n=n.replaceAll("<","<").replaceAll(">",">");const t=this.getInstance().dom.create("a",e,n);this.getInstance().selection.setNode(t)}else this.getInstance().execCommand("mceInsertLink",!1,e,t)},removeLink(){this.getInstance().execCommand("unlink",!1)},cleanLink(href,node){const settings=this.getConfig,cb=settings.urlconverter_callback,cu=tinyMCE.settings.convert_urls;return cb&&(href=eval(`${cb}(href, node, true);`)),cu&&href.match(new RegExp(`^${(0,_lodash.default)(tinyMCE.settings.document_base_url)}(.*)$`))&&(href=RegExp.$1),href.match(/^javascript:\s*mctmp/)&&(href=""),href},createBookmark(){return this.getInstance().selection.getBookmark()},moveToBookmark(e){this.getInstance().selection.moveToBookmark(e),this.getInstance().focus()},blur(){this.getInstance().selection.collapse()},addUndo(){this.getInstance().undoManager.add()}}},ss.editorWrappers.default=ss.editorWrappers.tinyMCE},256:function(e,t,n){var r=n(671),o=n(160);void 0===o.TinyMCEActionRegistrar&&(o.TinyMCEActionRegistrar=r),e.exports=r},517:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Component=void 0;var r=c(n(594)),o=c(n(921)),i=n(556),s=c(n(623));function c(e){return e&&e.__esModule?e:{default:e}}class a extends i.Component{constructor(e){super(e),this.state={isReady:!e.data.editorjs},this.inputRef=null,this.handleReady=this.handleReady.bind(this)}getInputProps(){return{...super.getInputProps(),...this.props.data.attributes,innerRef:e=>{this.inputRef=e}}}getEditorElement(){return document.getElementById(this.getInputProps().id)}getEditor(){return window.TinyMCE&&window.TinyMCE.get(this.getInputProps().id)}handleReady(){!window.TinyMCE&&window.tinymce&&(window.TinyMCE=window.tinymce),this.setState({isReady:!0})}registerChangeListener(){const e=this.getEditorElement();this.getEditor().on("change keyup",(()=>{super.handleChange({target:e})}))}renderDependencyScript(){return window.tinymce||window.TinyMCE?(setTimeout((()=>{this.handleReady()}),0),null):r.default.createElement(o.default,{url:this.props.data.editorjs,onLoad:this.handleReady})}render(){return this.state.isReady?super.render():this.renderDependencyScript()}componentDidUpdate(e,t){const{isReady:n}=this.state;if(!n)return;n!==t.isReady&&setTimeout((()=>{const{document:e,jQuery:t}=window,n=t?t.Event("EntwineElementsAdded"):new Event("noop"),r=this.getEditorElement();n.targets=[r],t&&t(e).triggerHandler(n),this.registerChangeListener()}),1);const{value:r}=this.props;if(r!==e.value){const e=new Event("change",{bubbles:!0});e.simulated=!0,e.value=r,this.inputRef.dispatchEvent(e)}}componentWillUnmount(){if(!this.state.isReady)return;const{document:e,jQuery:t}=window,n=t?t.Event("EntwineElementsRemoved"):new Event("noop"),r=this.getEditorElement(),o=this.getEditor();o&&o.save(),n.targets=[r],super.handleChange({target:r}),t&&t(e).triggerHandler(n)}}t.Component=a;t.default=(0,s.default)(a)},556:function(e){"use strict";e.exports=TextField},594:function(e){"use strict";e.exports=React},623:function(e){"use strict";e.exports=FieldHolder},669:function(e){"use strict";e.exports=jQuery},671:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;const n=(e,t)=>e?`${e}.${t}`:t;window.ss=window.ss||{},window.ss.tinymceactions=window.ss.tinymceactions||new class{constructor(){this.actions={},this.editorCommandsToUrlTestsMap={},this.defaultCommand="sslinkexternal"}addAction(e,t,r){const o=t.priority||50,i=n(r,e),s=this.getActions(e,r,!0);return t.type="menuitem",t.hasOwnProperty("onclick")&&(t.onAction=t.onclick,delete t.onclick),s.find((e=>t.text===e.text))||(this.actions[i]=[...this.getActions(e,r,!1),{...t,priority:o}]),this}getActions(e,t){let r=t&&!(!(arguments.length>2&&void 0!==arguments[2])||arguments[2])||!this.actions[e]?[]:this.actions[e];const o=n(t,e);return t&&this.actions[o]&&(r=[...r,...this.actions[o]]),r}getSortedActions(e,t){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.getActions(e,t,n).sort(((e,t)=>{const n=t.priority-e.priority;return n||(e.text.toLocaleLowerCase()>t.text.toLocaleLowerCase()?1:-1)}))}addCommandWithUrlTest(e,t){return this.editorCommandsToUrlTestsMap[e]=t,this}setDefaultCommand(e){return this.defaultCommand=e,this}getDefaultCommand(){return this.defaultCommand}getEditorCommandFromUrl(e){let t=this.getDefaultCommand();const n=Object.keys(this.editorCommandsToUrlTestsMap).find((t=>this.editorCommandsToUrlTestsMap[t]&&this.editorCommandsToUrlTestsMap[t].test(e)));return n&&(t=n),t}};t.default=window.ss.tinymceactions},912:function(e,t,n){var r="[object Symbol]",o=/[\\^$.*+?()[\]{}|]/g,i=RegExp(o.source),s="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,c="object"==typeof self&&self&&self.Object===Object&&self,a=s||c||Function("return this")(),u=Object.prototype.toString,d=a.Symbol,l=d?d.prototype:void 0,p=l?l.toString:void 0;function f(e){if("string"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&u.call(e)==r}(e))return p?p.call(e):"";var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}e.exports=function(e){var t;return(e=null==(t=e)?"":f(t))&&i.test(e)?e.replace(o,"\\$&"):e}},921:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o=function(){function e(e,t){for(var n=0;n` and `` elements will be converted to more restrictive alternatives, namely `` for image MIME types, `