create-nextjs-cms 0.5.19 → 0.5.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -0
- package/package.json +4 -4
- package/templates/default/.uploads/.photos/categories/000e56fada378de1a84a4 +0 -0
- package/templates/default/.uploads/.photos/categories/121e7d13ee3b5fa03795b +0 -0
- package/templates/default/.uploads/.photos/categories/17a55c5a53eb62293c69e +0 -0
- package/templates/default/.uploads/.photos/categories/4c86ad8c1f51f1e3a953b +0 -0
- package/templates/default/.uploads/.photos/categories/4d360813741a45744327c +0 -0
- package/templates/default/.uploads/.photos/categories/5238fefaa3cbebf388178 +0 -0
- package/templates/default/.uploads/.photos/categories/541d7cf8c69895bcb15cd +0 -0
- package/templates/default/.uploads/.photos/categories/57a2f689a910a378247ea +0 -0
- package/templates/default/.uploads/.photos/categories/6de4bdb341a3e1f70ddc3 +0 -0
- package/templates/default/.uploads/.photos/categories/6f52739eaa686441a28f4 +0 -0
- package/templates/default/.uploads/.photos/categories/8a21b9fa8ecd88f460a15 +0 -0
- package/templates/default/.uploads/.photos/categories/91948abcb073c9445fdec +0 -0
- package/templates/default/.uploads/.photos/categories/9ae700d1abfd6b85780e8 +0 -0
- package/templates/default/.uploads/.photos/categories/9edee86e932985fc589b5 +0 -0
- package/templates/default/.uploads/.photos/categories/a520e77b082f35b575dba +0 -0
- package/templates/default/.uploads/.photos/categories/b19c449029330f0a74b20 +0 -0
- package/templates/default/.uploads/.photos/categories/b9802010f68afd4edb0e8 +0 -0
- package/templates/default/.uploads/.photos/categories/c1d7c3b986739bf496730 +0 -0
- package/templates/default/.uploads/.photos/categories/c25dc38567384513ffe93 +0 -0
- package/templates/default/.uploads/.photos/categories/cbe3874a3d13afba388df +0 -0
- package/templates/default/.uploads/.photos/categories/d450fdeb04f0d070442d6 +0 -0
- package/templates/default/.uploads/.photos/categories/f80bf3a4515680ead5a5c +0 -0
- package/templates/default/.uploads/.photos/categories/f8639c2d5b0d24cb76fb1 +0 -0
- package/templates/default/.uploads/.photos/categories/f8d997149d10aab046e40 +0 -0
- package/templates/default/.uploads/.photos/categories/fa2c55690ff96e33a16fe +0 -0
- package/templates/default/.uploads/.photos/featured_slider/d00be4edb4c38ca34b5a5 +0 -0
- package/templates/default/.uploads/.thumbs/categories/000e56fada378de1a84a4 +0 -0
- package/templates/default/.uploads/.thumbs/categories/121e7d13ee3b5fa03795b +0 -0
- package/templates/default/.uploads/.thumbs/categories/17a55c5a53eb62293c69e +0 -0
- package/templates/default/.uploads/.thumbs/categories/4c86ad8c1f51f1e3a953b +0 -0
- package/templates/default/.uploads/.thumbs/categories/4d360813741a45744327c +0 -0
- package/templates/default/.uploads/.thumbs/categories/5238fefaa3cbebf388178 +0 -0
- package/templates/default/.uploads/.thumbs/categories/541d7cf8c69895bcb15cd +0 -0
- package/templates/default/.uploads/.thumbs/categories/57a2f689a910a378247ea +0 -0
- package/templates/default/.uploads/.thumbs/categories/6de4bdb341a3e1f70ddc3 +0 -0
- package/templates/default/.uploads/.thumbs/categories/6f52739eaa686441a28f4 +0 -0
- package/templates/default/.uploads/.thumbs/categories/8a21b9fa8ecd88f460a15 +0 -0
- package/templates/default/.uploads/.thumbs/categories/91948abcb073c9445fdec +0 -0
- package/templates/default/.uploads/.thumbs/categories/9ae700d1abfd6b85780e8 +0 -0
- package/templates/default/.uploads/.thumbs/categories/9edee86e932985fc589b5 +0 -0
- package/templates/default/.uploads/.thumbs/categories/a520e77b082f35b575dba +0 -0
- package/templates/default/.uploads/.thumbs/categories/b19c449029330f0a74b20 +0 -0
- package/templates/default/.uploads/.thumbs/categories/b9802010f68afd4edb0e8 +0 -0
- package/templates/default/.uploads/.thumbs/categories/c1d7c3b986739bf496730 +0 -0
- package/templates/default/.uploads/.thumbs/categories/c25dc38567384513ffe93 +0 -0
- package/templates/default/.uploads/.thumbs/categories/cbe3874a3d13afba388df +0 -0
- package/templates/default/.uploads/.thumbs/categories/d450fdeb04f0d070442d6 +0 -0
- package/templates/default/.uploads/.thumbs/categories/f80bf3a4515680ead5a5c +0 -0
- package/templates/default/.uploads/.thumbs/categories/f8639c2d5b0d24cb76fb1 +0 -0
- package/templates/default/.uploads/.thumbs/categories/f8d997149d10aab046e40 +0 -0
- package/templates/default/.uploads/.thumbs/categories/fa2c55690ff96e33a16fe +0 -0
- package/templates/default/_gitignore +57 -0
- package/templates/default/components/form/helpers/_section-hot-reload.ts +11 -0
- package/templates/default/next-env.d.ts +6 -0
- package/templates/default/package.json +2 -2
- package/templates/default/public/tinymce/CHANGELOG.md +3785 -0
- package/templates/default/public/tinymce/README.md +77 -0
- package/templates/default/public/tinymce/bower.json +27 -0
- package/templates/default/public/tinymce/composer.json +52 -0
- package/templates/default/public/tinymce/icons/default/icons.js +231 -0
- package/templates/default/public/tinymce/icons/default/icons.min.js +1 -0
- package/templates/default/public/tinymce/icons/default/index.js +7 -0
- package/templates/default/public/tinymce/license.md +6 -0
- package/templates/default/public/tinymce/models/dom/index.js +7 -0
- package/templates/default/public/tinymce/models/dom/model.js +8994 -0
- package/templates/default/public/tinymce/models/dom/model.min.js +1 -0
- package/templates/default/public/tinymce/notices.txt +21 -0
- package/templates/default/public/tinymce/package.json +32 -0
- package/templates/default/public/tinymce/plugins/accordion/index.js +7 -0
- package/templates/default/public/tinymce/plugins/accordion/plugin.js +1349 -0
- package/templates/default/public/tinymce/plugins/accordion/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/advlist/index.js +7 -0
- package/templates/default/public/tinymce/plugins/advlist/plugin.js +471 -0
- package/templates/default/public/tinymce/plugins/advlist/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/anchor/index.js +7 -0
- package/templates/default/public/tinymce/plugins/anchor/plugin.js +237 -0
- package/templates/default/public/tinymce/plugins/anchor/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/autolink/index.js +7 -0
- package/templates/default/public/tinymce/plugins/autolink/plugin.js +318 -0
- package/templates/default/public/tinymce/plugins/autolink/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/autoresize/index.js +7 -0
- package/templates/default/public/tinymce/plugins/autoresize/plugin.js +223 -0
- package/templates/default/public/tinymce/plugins/autoresize/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/autosave/index.js +7 -0
- package/templates/default/public/tinymce/plugins/autosave/plugin.js +252 -0
- package/templates/default/public/tinymce/plugins/autosave/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/charmap/index.js +7 -0
- package/templates/default/public/tinymce/plugins/charmap/plugin.js +997 -0
- package/templates/default/public/tinymce/plugins/charmap/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/code/index.js +7 -0
- package/templates/default/public/tinymce/plugins/code/plugin.js +97 -0
- package/templates/default/public/tinymce/plugins/code/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/codesample/index.js +7 -0
- package/templates/default/public/tinymce/plugins/codesample/plugin.js +3654 -0
- package/templates/default/public/tinymce/plugins/codesample/plugin.min.js +9 -0
- package/templates/default/public/tinymce/plugins/directionality/index.js +7 -0
- package/templates/default/public/tinymce/plugins/directionality/plugin.js +636 -0
- package/templates/default/public/tinymce/plugins/directionality/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/emoticons/index.js +7 -0
- package/templates/default/public/tinymce/plugins/emoticons/js/emojiimages.js +1 -0
- package/templates/default/public/tinymce/plugins/emoticons/js/emojiimages.min.js +1 -0
- package/templates/default/public/tinymce/plugins/emoticons/js/emojis.js +1 -0
- package/templates/default/public/tinymce/plugins/emoticons/js/emojis.min.js +1 -0
- package/templates/default/public/tinymce/plugins/emoticons/plugin.js +809 -0
- package/templates/default/public/tinymce/plugins/emoticons/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/fullscreen/index.js +7 -0
- package/templates/default/public/tinymce/plugins/fullscreen/plugin.js +1609 -0
- package/templates/default/public/tinymce/plugins/fullscreen/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/help/index.js +7 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ar.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/bg_BG.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ca.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/cs.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/da.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/de.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/el.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/en.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/es.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/eu.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/fa.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/fi.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/fr_FR.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/he_IL.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/hi.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/hr.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/hu_HU.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/id.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/it.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ja.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/kk.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ko_KR.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ms.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/nb_NO.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/nl.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/pl.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/pt_BR.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/pt_PT.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ro.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ru.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/sk.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/sl_SI.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/sv_SE.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/th_TH.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/tr.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/uk.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/vi.js +93 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/zh_CN.js +87 -0
- package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/zh_TW.js +93 -0
- package/templates/default/public/tinymce/plugins/help/plugin.js +828 -0
- package/templates/default/public/tinymce/plugins/help/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/image/index.js +7 -0
- package/templates/default/public/tinymce/plugins/image/plugin.js +1689 -0
- package/templates/default/public/tinymce/plugins/image/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/importcss/index.js +7 -0
- package/templates/default/public/tinymce/plugins/importcss/plugin.js +403 -0
- package/templates/default/public/tinymce/plugins/importcss/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/insertdatetime/index.js +7 -0
- package/templates/default/public/tinymce/plugins/insertdatetime/plugin.js +186 -0
- package/templates/default/public/tinymce/plugins/insertdatetime/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/link/index.js +7 -0
- package/templates/default/public/tinymce/plugins/link/plugin.js +1577 -0
- package/templates/default/public/tinymce/plugins/link/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/lists/index.js +7 -0
- package/templates/default/public/tinymce/plugins/lists/plugin.js +2544 -0
- package/templates/default/public/tinymce/plugins/lists/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/media/index.js +7 -0
- package/templates/default/public/tinymce/plugins/media/plugin.js +1450 -0
- package/templates/default/public/tinymce/plugins/media/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/nonbreaking/index.js +7 -0
- package/templates/default/public/tinymce/plugins/nonbreaking/plugin.js +128 -0
- package/templates/default/public/tinymce/plugins/nonbreaking/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/pagebreak/index.js +7 -0
- package/templates/default/public/tinymce/plugins/pagebreak/plugin.js +123 -0
- package/templates/default/public/tinymce/plugins/pagebreak/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/preview/index.js +7 -0
- package/templates/default/public/tinymce/plugins/preview/plugin.js +765 -0
- package/templates/default/public/tinymce/plugins/preview/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/quickbars/index.js +7 -0
- package/templates/default/public/tinymce/plugins/quickbars/plugin.js +654 -0
- package/templates/default/public/tinymce/plugins/quickbars/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/save/index.js +7 -0
- package/templates/default/public/tinymce/plugins/save/plugin.js +136 -0
- package/templates/default/public/tinymce/plugins/save/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/searchreplace/index.js +7 -0
- package/templates/default/public/tinymce/plugins/searchreplace/plugin.js +1370 -0
- package/templates/default/public/tinymce/plugins/searchreplace/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/table/index.js +7 -0
- package/templates/default/public/tinymce/plugins/table/plugin.js +4019 -0
- package/templates/default/public/tinymce/plugins/table/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/visualblocks/index.js +7 -0
- package/templates/default/public/tinymce/plugins/visualblocks/plugin.js +106 -0
- package/templates/default/public/tinymce/plugins/visualblocks/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/visualchars/index.js +7 -0
- package/templates/default/public/tinymce/plugins/visualchars/plugin.js +809 -0
- package/templates/default/public/tinymce/plugins/visualchars/plugin.min.js +1 -0
- package/templates/default/public/tinymce/plugins/wordcount/index.js +7 -0
- package/templates/default/public/tinymce/plugins/wordcount/plugin.js +480 -0
- package/templates/default/public/tinymce/plugins/wordcount/plugin.min.js +1 -0
- package/templates/default/public/tinymce/skins/content/dark/content.css +75 -0
- package/templates/default/public/tinymce/skins/content/dark/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/dark/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/content/default/content.css +70 -0
- package/templates/default/public/tinymce/skins/content/default/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/default/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/content/document/content.css +75 -0
- package/templates/default/public/tinymce/skins/content/document/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/document/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5/content.css +70 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5-dark/content.css +75 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5-dark/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/tinymce-5-dark/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/content/writer/content.css +71 -0
- package/templates/default/public/tinymce/skins/content/writer/content.js +10 -0
- package/templates/default/public/tinymce/skins/content/writer/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.css +893 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.inline.css +887 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.inline.js +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.inline.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.js +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.css +5141 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.js +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.shadowdom.css +30 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.shadowdom.js +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide/skin.shadowdom.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.css +881 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.css +887 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.js +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.js +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.css +5144 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.js +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.css +30 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.js +1 -0
- package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.css +893 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.css +887 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.js +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.js +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.css +5260 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.js +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.css +30 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.js +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.css +881 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.css +887 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.js +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.js +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.min.css +10 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.css +5260 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.css +30 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.js +1 -0
- package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css +1 -0
- package/templates/default/public/tinymce/themes/silver/index.js +7 -0
- package/templates/default/public/tinymce/themes/silver/theme.js +34798 -0
- package/templates/default/public/tinymce/themes/silver/theme.min.js +1 -0
- package/templates/default/public/tinymce/tinymce.d.ts +3350 -0
- package/templates/default/public/tinymce/tinymce.js +38694 -0
- package/templates/default/public/tinymce/tinymce.min.js +11 -0
|
@@ -0,0 +1,1450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyMCE version 7.9.1 (2025-05-29)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
(function () {
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
var global$6 = tinymce.util.Tools.resolve('tinymce.PluginManager');
|
|
9
|
+
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
|
|
11
|
+
const hasProto = (v, constructor, predicate) => {
|
|
12
|
+
var _a;
|
|
13
|
+
if (predicate(v, constructor.prototype)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// String-based fallback time
|
|
18
|
+
return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const typeOf = (x) => {
|
|
22
|
+
const t = typeof x;
|
|
23
|
+
if (x === null) {
|
|
24
|
+
return 'null';
|
|
25
|
+
}
|
|
26
|
+
else if (t === 'object' && Array.isArray(x)) {
|
|
27
|
+
return 'array';
|
|
28
|
+
}
|
|
29
|
+
else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
|
|
30
|
+
return 'string';
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return t;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const isType = (type) => (value) => typeOf(value) === type;
|
|
37
|
+
const isSimpleType = (type) => (value) => typeof value === type;
|
|
38
|
+
const isString = isType('string');
|
|
39
|
+
const isObject = isType('object');
|
|
40
|
+
const isArray = isType('array');
|
|
41
|
+
const isNullable = (a) => a === null || a === undefined;
|
|
42
|
+
const isNonNullable = (a) => !isNullable(a);
|
|
43
|
+
const isFunction = isSimpleType('function');
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The `Optional` type represents a value (of any type) that potentially does
|
|
47
|
+
* not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
|
|
48
|
+
* value does exist) or a `None` (in which case the value does not exist). This
|
|
49
|
+
* module defines a whole lot of FP-inspired utility functions for dealing with
|
|
50
|
+
* `Optional` objects.
|
|
51
|
+
*
|
|
52
|
+
* Comparison with null or undefined:
|
|
53
|
+
* - We don't get fancy null coalescing operators with `Optional`
|
|
54
|
+
* - We do get fancy helper functions with `Optional`
|
|
55
|
+
* - `Optional` support nesting, and allow for the type to still be nullable (or
|
|
56
|
+
* another `Optional`)
|
|
57
|
+
* - There is no option to turn off strict-optional-checks like there is for
|
|
58
|
+
* strict-null-checks
|
|
59
|
+
*/
|
|
60
|
+
class Optional {
|
|
61
|
+
// The internal representation has a `tag` and a `value`, but both are
|
|
62
|
+
// private: able to be console.logged, but not able to be accessed by code
|
|
63
|
+
constructor(tag, value) {
|
|
64
|
+
this.tag = tag;
|
|
65
|
+
this.value = value;
|
|
66
|
+
}
|
|
67
|
+
// --- Identities ---
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new `Optional<T>` that **does** contain a value.
|
|
70
|
+
*/
|
|
71
|
+
static some(value) {
|
|
72
|
+
return new Optional(true, value);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a new `Optional<T>` that **does not** contain a value. `T` can be
|
|
76
|
+
* any type because we don't actually have a `T`.
|
|
77
|
+
*/
|
|
78
|
+
static none() {
|
|
79
|
+
return Optional.singletonNone;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Perform a transform on an `Optional` type. Regardless of whether this
|
|
83
|
+
* `Optional` contains a value or not, `fold` will return a value of type `U`.
|
|
84
|
+
* If this `Optional` does not contain a value, the `U` will be created by
|
|
85
|
+
* calling `onNone`. If this `Optional` does contain a value, the `U` will be
|
|
86
|
+
* created by calling `onSome`.
|
|
87
|
+
*
|
|
88
|
+
* For the FP enthusiasts in the room, this function:
|
|
89
|
+
* 1. Could be used to implement all of the functions below
|
|
90
|
+
* 2. Forms a catamorphism
|
|
91
|
+
*/
|
|
92
|
+
fold(onNone, onSome) {
|
|
93
|
+
if (this.tag) {
|
|
94
|
+
return onSome(this.value);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return onNone();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Determine if this `Optional` object contains a value.
|
|
102
|
+
*/
|
|
103
|
+
isSome() {
|
|
104
|
+
return this.tag;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Determine if this `Optional` object **does not** contain a value.
|
|
108
|
+
*/
|
|
109
|
+
isNone() {
|
|
110
|
+
return !this.tag;
|
|
111
|
+
}
|
|
112
|
+
// --- Functor (name stolen from Haskell / maths) ---
|
|
113
|
+
/**
|
|
114
|
+
* Perform a transform on an `Optional` object, **if** there is a value. If
|
|
115
|
+
* you provide a function to turn a T into a U, this is the function you use
|
|
116
|
+
* to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
|
|
117
|
+
* a value then the output will also contain a value (that value being the
|
|
118
|
+
* output of `mapper(this.value)`), and if this **does not** contain a value
|
|
119
|
+
* then neither will the output.
|
|
120
|
+
*/
|
|
121
|
+
map(mapper) {
|
|
122
|
+
if (this.tag) {
|
|
123
|
+
return Optional.some(mapper(this.value));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return Optional.none();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// --- Monad (name stolen from Haskell / maths) ---
|
|
130
|
+
/**
|
|
131
|
+
* Perform a transform on an `Optional` object, **if** there is a value.
|
|
132
|
+
* Unlike `map`, here the transform itself also returns an `Optional`.
|
|
133
|
+
*/
|
|
134
|
+
bind(binder) {
|
|
135
|
+
if (this.tag) {
|
|
136
|
+
return binder(this.value);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return Optional.none();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// --- Traversable (name stolen from Haskell / maths) ---
|
|
143
|
+
/**
|
|
144
|
+
* For a given predicate, this function finds out if there **exists** a value
|
|
145
|
+
* inside this `Optional` object that meets the predicate. In practice, this
|
|
146
|
+
* means that for `Optional`s that do not contain a value it returns false (as
|
|
147
|
+
* no predicate-meeting value exists).
|
|
148
|
+
*/
|
|
149
|
+
exists(predicate) {
|
|
150
|
+
return this.tag && predicate(this.value);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* For a given predicate, this function finds out if **all** the values inside
|
|
154
|
+
* this `Optional` object meet the predicate. In practice, this means that
|
|
155
|
+
* for `Optional`s that do not contain a value it returns true (as all 0
|
|
156
|
+
* objects do meet the predicate).
|
|
157
|
+
*/
|
|
158
|
+
forall(predicate) {
|
|
159
|
+
return !this.tag || predicate(this.value);
|
|
160
|
+
}
|
|
161
|
+
filter(predicate) {
|
|
162
|
+
if (!this.tag || predicate(this.value)) {
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return Optional.none();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// --- Getters ---
|
|
170
|
+
/**
|
|
171
|
+
* Get the value out of the inside of the `Optional` object, using a default
|
|
172
|
+
* `replacement` value if the provided `Optional` object does not contain a
|
|
173
|
+
* value.
|
|
174
|
+
*/
|
|
175
|
+
getOr(replacement) {
|
|
176
|
+
return this.tag ? this.value : replacement;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get the value out of the inside of the `Optional` object, using a default
|
|
180
|
+
* `replacement` value if the provided `Optional` object does not contain a
|
|
181
|
+
* value. Unlike `getOr`, in this method the `replacement` object is also
|
|
182
|
+
* `Optional` - meaning that this method will always return an `Optional`.
|
|
183
|
+
*/
|
|
184
|
+
or(replacement) {
|
|
185
|
+
return this.tag ? this : replacement;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get the value out of the inside of the `Optional` object, using a default
|
|
189
|
+
* `replacement` value if the provided `Optional` object does not contain a
|
|
190
|
+
* value. Unlike `getOr`, in this method the `replacement` value is
|
|
191
|
+
* "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
|
|
192
|
+
* pass a function which (if called) will **return** the `value` you want to
|
|
193
|
+
* use.
|
|
194
|
+
*/
|
|
195
|
+
getOrThunk(thunk) {
|
|
196
|
+
return this.tag ? this.value : thunk();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get the value out of the inside of the `Optional` object, using a default
|
|
200
|
+
* `replacement` value if the provided Optional object does not contain a
|
|
201
|
+
* value.
|
|
202
|
+
*
|
|
203
|
+
* Unlike `or`, in this method the `replacement` value is "thunked" - that is
|
|
204
|
+
* to say that you don't pass a value to `orThunk`, you pass a function which
|
|
205
|
+
* (if called) will **return** the `value` you want to use.
|
|
206
|
+
*
|
|
207
|
+
* Unlike `getOrThunk`, in this method the `replacement` value is also
|
|
208
|
+
* `Optional`, meaning that this method will always return an `Optional`.
|
|
209
|
+
*/
|
|
210
|
+
orThunk(thunk) {
|
|
211
|
+
return this.tag ? this : thunk();
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get the value out of the inside of the `Optional` object, throwing an
|
|
215
|
+
* exception if the provided `Optional` object does not contain a value.
|
|
216
|
+
*
|
|
217
|
+
* WARNING:
|
|
218
|
+
* You should only be using this function if you know that the `Optional`
|
|
219
|
+
* object **is not** empty (otherwise you're throwing exceptions in production
|
|
220
|
+
* code, which is bad).
|
|
221
|
+
*
|
|
222
|
+
* In tests this is more acceptable.
|
|
223
|
+
*
|
|
224
|
+
* Prefer other methods to this, such as `.each`.
|
|
225
|
+
*/
|
|
226
|
+
getOrDie(message) {
|
|
227
|
+
if (!this.tag) {
|
|
228
|
+
throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return this.value;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// --- Interop with null and undefined ---
|
|
235
|
+
/**
|
|
236
|
+
* Creates an `Optional` value from a nullable (or undefined-able) input.
|
|
237
|
+
* Null, or undefined, is converted to `None`, and anything else is converted
|
|
238
|
+
* to `Some`.
|
|
239
|
+
*/
|
|
240
|
+
static from(value) {
|
|
241
|
+
return isNonNullable(value) ? Optional.some(value) : Optional.none();
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Converts an `Optional` to a nullable type, by getting the value if it
|
|
245
|
+
* exists, or returning `null` if it does not.
|
|
246
|
+
*/
|
|
247
|
+
getOrNull() {
|
|
248
|
+
return this.tag ? this.value : null;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Converts an `Optional` to an undefined-able type, by getting the value if
|
|
252
|
+
* it exists, or returning `undefined` if it does not.
|
|
253
|
+
*/
|
|
254
|
+
getOrUndefined() {
|
|
255
|
+
return this.value;
|
|
256
|
+
}
|
|
257
|
+
// --- Utilities ---
|
|
258
|
+
/**
|
|
259
|
+
* If the `Optional` contains a value, perform an action on that value.
|
|
260
|
+
* Unlike the rest of the methods on this type, `.each` has side-effects. If
|
|
261
|
+
* you want to transform an `Optional<T>` **into** something, then this is not
|
|
262
|
+
* the method for you. If you want to use an `Optional<T>` to **do**
|
|
263
|
+
* something, then this is the method for you - provided you're okay with not
|
|
264
|
+
* doing anything in the case where the `Optional` doesn't have a value inside
|
|
265
|
+
* it. If you're not sure whether your use-case fits into transforming
|
|
266
|
+
* **into** something or **doing** something, check whether it has a return
|
|
267
|
+
* value. If it does, you should be performing a transform.
|
|
268
|
+
*/
|
|
269
|
+
each(worker) {
|
|
270
|
+
if (this.tag) {
|
|
271
|
+
worker(this.value);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Turn the `Optional` object into an array that contains all of the values
|
|
276
|
+
* stored inside the `Optional`. In practice, this means the output will have
|
|
277
|
+
* either 0 or 1 elements.
|
|
278
|
+
*/
|
|
279
|
+
toArray() {
|
|
280
|
+
return this.tag ? [this.value] : [];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Turn the `Optional` object into a string for debugging or printing. Not
|
|
284
|
+
* recommended for production code, but good for debugging. Also note that
|
|
285
|
+
* these days an `Optional` object can be logged to the console directly, and
|
|
286
|
+
* its inner value (if it exists) will be visible.
|
|
287
|
+
*/
|
|
288
|
+
toString() {
|
|
289
|
+
return this.tag ? `some(${this.value})` : 'none()';
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Sneaky optimisation: every instance of Optional.none is identical, so just
|
|
293
|
+
// reuse the same object
|
|
294
|
+
Optional.singletonNone = new Optional(false);
|
|
295
|
+
|
|
296
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
297
|
+
const nativeSlice = Array.prototype.slice;
|
|
298
|
+
const nativePush = Array.prototype.push;
|
|
299
|
+
// Unwound implementing other functions in terms of each.
|
|
300
|
+
// The code size is roughly the same, and it should allow for better optimisation.
|
|
301
|
+
// const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
|
|
302
|
+
const each$1 = (xs, f) => {
|
|
303
|
+
for (let i = 0, len = xs.length; i < len; i++) {
|
|
304
|
+
const x = xs[i];
|
|
305
|
+
f(x, i);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
const flatten = (xs) => {
|
|
309
|
+
// Note, this is possible because push supports multiple arguments:
|
|
310
|
+
// http://jsperf.com/concat-push/6
|
|
311
|
+
// Note that in the past, concat() would silently work (very slowly) for array-like objects.
|
|
312
|
+
// With this change it will throw an error.
|
|
313
|
+
const r = [];
|
|
314
|
+
for (let i = 0, len = xs.length; i < len; ++i) {
|
|
315
|
+
// Ensure that each value is an array itself
|
|
316
|
+
if (!isArray(xs[i])) {
|
|
317
|
+
throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
|
|
318
|
+
}
|
|
319
|
+
nativePush.apply(r, xs[i]);
|
|
320
|
+
}
|
|
321
|
+
return r;
|
|
322
|
+
};
|
|
323
|
+
isFunction(Array.from) ? Array.from : (x) => nativeSlice.call(x);
|
|
324
|
+
|
|
325
|
+
// There are many variations of Object iteration that are faster than the 'for-in' style:
|
|
326
|
+
// http://jsperf.com/object-keys-iteration/107
|
|
327
|
+
//
|
|
328
|
+
// Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
|
|
329
|
+
const keys = Object.keys;
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
331
|
+
const hasOwnProperty = Object.hasOwnProperty;
|
|
332
|
+
const each = (obj, f) => {
|
|
333
|
+
const props = keys(obj);
|
|
334
|
+
for (let k = 0, len = props.length; k < len; k++) {
|
|
335
|
+
const i = props[k];
|
|
336
|
+
const x = obj[i];
|
|
337
|
+
f(x, i);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
const get$1 = (obj, key) => {
|
|
341
|
+
return has(obj, key) ? Optional.from(obj[key]) : Optional.none();
|
|
342
|
+
};
|
|
343
|
+
const has = (obj, key) => hasOwnProperty.call(obj, key);
|
|
344
|
+
|
|
345
|
+
const Cell = (initial) => {
|
|
346
|
+
let value = initial;
|
|
347
|
+
const get = () => {
|
|
348
|
+
return value;
|
|
349
|
+
};
|
|
350
|
+
const set = (v) => {
|
|
351
|
+
value = v;
|
|
352
|
+
};
|
|
353
|
+
return {
|
|
354
|
+
get,
|
|
355
|
+
set
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
|
|
360
|
+
/** Does 'str' start with 'prefix'?
|
|
361
|
+
* Note: all strings start with the empty string.
|
|
362
|
+
* More formally, for all strings x, startsWith(x, "").
|
|
363
|
+
* This is so that for all strings x and y, startsWith(y + x, y)
|
|
364
|
+
*/
|
|
365
|
+
const startsWith = (str, prefix) => {
|
|
366
|
+
return checkRange(str, prefix, 0);
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const option = (name) => (editor) => editor.options.get(name);
|
|
370
|
+
const register$2 = (editor) => {
|
|
371
|
+
const registerOption = editor.options.register;
|
|
372
|
+
registerOption('audio_template_callback', {
|
|
373
|
+
processor: 'function'
|
|
374
|
+
});
|
|
375
|
+
registerOption('video_template_callback', {
|
|
376
|
+
processor: 'function'
|
|
377
|
+
});
|
|
378
|
+
registerOption('iframe_template_callback', {
|
|
379
|
+
processor: 'function'
|
|
380
|
+
});
|
|
381
|
+
registerOption('media_live_embeds', {
|
|
382
|
+
processor: 'boolean',
|
|
383
|
+
default: true
|
|
384
|
+
});
|
|
385
|
+
registerOption('media_filter_html', {
|
|
386
|
+
processor: 'boolean',
|
|
387
|
+
default: true
|
|
388
|
+
});
|
|
389
|
+
registerOption('media_url_resolver', {
|
|
390
|
+
processor: 'function'
|
|
391
|
+
});
|
|
392
|
+
registerOption('media_alt_source', {
|
|
393
|
+
processor: 'boolean',
|
|
394
|
+
default: true
|
|
395
|
+
});
|
|
396
|
+
registerOption('media_poster', {
|
|
397
|
+
processor: 'boolean',
|
|
398
|
+
default: true
|
|
399
|
+
});
|
|
400
|
+
registerOption('media_dimensions', {
|
|
401
|
+
processor: 'boolean',
|
|
402
|
+
default: true
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
const getAudioTemplateCallback = option('audio_template_callback');
|
|
406
|
+
const getVideoTemplateCallback = option('video_template_callback');
|
|
407
|
+
const getIframeTemplateCallback = option('iframe_template_callback');
|
|
408
|
+
const hasLiveEmbeds = option('media_live_embeds');
|
|
409
|
+
const shouldFilterHtml = option('media_filter_html');
|
|
410
|
+
const getUrlResolver = option('media_url_resolver');
|
|
411
|
+
const hasAltSource = option('media_alt_source');
|
|
412
|
+
const hasPoster = option('media_poster');
|
|
413
|
+
const hasDimensions = option('media_dimensions');
|
|
414
|
+
|
|
415
|
+
var global$5 = tinymce.util.Tools.resolve('tinymce.util.Tools');
|
|
416
|
+
|
|
417
|
+
var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
|
|
418
|
+
|
|
419
|
+
var global$3 = tinymce.util.Tools.resolve('tinymce.html.DomParser');
|
|
420
|
+
|
|
421
|
+
const DOM$1 = global$4.DOM;
|
|
422
|
+
const trimPx = (value) => value.replace(/px$/, '');
|
|
423
|
+
const getEphoxEmbedData = (node) => {
|
|
424
|
+
const style = node.attr('style');
|
|
425
|
+
const styles = style ? DOM$1.parseStyle(style) : {};
|
|
426
|
+
return {
|
|
427
|
+
type: 'ephox-embed-iri',
|
|
428
|
+
source: node.attr('data-ephox-embed-iri'),
|
|
429
|
+
altsource: '',
|
|
430
|
+
poster: '',
|
|
431
|
+
width: get$1(styles, 'max-width').map(trimPx).getOr(''),
|
|
432
|
+
height: get$1(styles, 'max-height').map(trimPx).getOr('')
|
|
433
|
+
};
|
|
434
|
+
};
|
|
435
|
+
const htmlToData = (html, schema) => {
|
|
436
|
+
let data = {};
|
|
437
|
+
const parser = global$3({ validate: false, forced_root_block: false }, schema);
|
|
438
|
+
const rootNode = parser.parse(html);
|
|
439
|
+
for (let node = rootNode; node; node = node.walk()) {
|
|
440
|
+
if (node.type === 1) {
|
|
441
|
+
const name = node.name;
|
|
442
|
+
if (node.attr('data-ephox-embed-iri')) {
|
|
443
|
+
data = getEphoxEmbedData(node);
|
|
444
|
+
// Don't continue to collect if we find an EME embed
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
if (!data.source && name === 'param') {
|
|
449
|
+
data.source = node.attr('movie');
|
|
450
|
+
}
|
|
451
|
+
if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') {
|
|
452
|
+
if (!data.type) {
|
|
453
|
+
data.type = name;
|
|
454
|
+
}
|
|
455
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
456
|
+
data = global$5.extend(node.attributes.map, data);
|
|
457
|
+
}
|
|
458
|
+
if (name === 'source') {
|
|
459
|
+
if (!data.source) {
|
|
460
|
+
data.source = node.attr('src');
|
|
461
|
+
}
|
|
462
|
+
else if (!data.altsource) {
|
|
463
|
+
data.altsource = node.attr('src');
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (name === 'img' && !data.poster) {
|
|
467
|
+
data.poster = node.attr('src');
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
data.source = data.source || data.src || '';
|
|
473
|
+
data.altsource = data.altsource || '';
|
|
474
|
+
data.poster = data.poster || '';
|
|
475
|
+
return data;
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const guess = (url) => {
|
|
479
|
+
var _a;
|
|
480
|
+
const mimes = {
|
|
481
|
+
mp3: 'audio/mpeg',
|
|
482
|
+
m4a: 'audio/x-m4a',
|
|
483
|
+
wav: 'audio/wav',
|
|
484
|
+
mp4: 'video/mp4',
|
|
485
|
+
webm: 'video/webm',
|
|
486
|
+
ogg: 'video/ogg',
|
|
487
|
+
swf: 'application/x-shockwave-flash'
|
|
488
|
+
};
|
|
489
|
+
const fileEnd = (_a = url.toLowerCase().split('.').pop()) !== null && _a !== void 0 ? _a : '';
|
|
490
|
+
return get$1(mimes, fileEnd).getOr('');
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
var global$2 = tinymce.util.Tools.resolve('tinymce.html.Node');
|
|
494
|
+
|
|
495
|
+
var global$1 = tinymce.util.Tools.resolve('tinymce.html.Serializer');
|
|
496
|
+
|
|
497
|
+
const Parser = (schema, settings = {}) => global$3({
|
|
498
|
+
forced_root_block: false,
|
|
499
|
+
validate: false,
|
|
500
|
+
allow_conditional_comments: true,
|
|
501
|
+
...settings
|
|
502
|
+
}, schema);
|
|
503
|
+
|
|
504
|
+
const DOM = global$4.DOM;
|
|
505
|
+
const addPx = (value) => /^[0-9.]+$/.test(value) ? (value + 'px') : value;
|
|
506
|
+
const updateEphoxEmbed = (data, node) => {
|
|
507
|
+
const style = node.attr('style');
|
|
508
|
+
const styleMap = style ? DOM.parseStyle(style) : {};
|
|
509
|
+
if (isNonNullable(data.width)) {
|
|
510
|
+
styleMap['max-width'] = addPx(data.width);
|
|
511
|
+
}
|
|
512
|
+
if (isNonNullable(data.height)) {
|
|
513
|
+
styleMap['max-height'] = addPx(data.height);
|
|
514
|
+
}
|
|
515
|
+
node.attr('style', DOM.serializeStyle(styleMap));
|
|
516
|
+
};
|
|
517
|
+
const sources = ['source', 'altsource'];
|
|
518
|
+
const updateHtml = (html, data, updateAll, schema) => {
|
|
519
|
+
let numSources = 0;
|
|
520
|
+
let sourceCount = 0;
|
|
521
|
+
const parser = Parser(schema);
|
|
522
|
+
parser.addNodeFilter('source', (nodes) => numSources = nodes.length);
|
|
523
|
+
const rootNode = parser.parse(html);
|
|
524
|
+
for (let node = rootNode; node; node = node.walk()) {
|
|
525
|
+
if (node.type === 1) {
|
|
526
|
+
const name = node.name;
|
|
527
|
+
if (node.attr('data-ephox-embed-iri')) {
|
|
528
|
+
updateEphoxEmbed(data, node);
|
|
529
|
+
// Don't continue to update if we find an EME embed
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
switch (name) {
|
|
534
|
+
case 'video':
|
|
535
|
+
case 'object':
|
|
536
|
+
case 'embed':
|
|
537
|
+
case 'img':
|
|
538
|
+
case 'iframe':
|
|
539
|
+
if (data.height !== undefined && data.width !== undefined) {
|
|
540
|
+
node.attr('width', data.width);
|
|
541
|
+
node.attr('height', data.height);
|
|
542
|
+
}
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
if (updateAll) {
|
|
546
|
+
switch (name) {
|
|
547
|
+
case 'video':
|
|
548
|
+
node.attr('poster', data.poster);
|
|
549
|
+
node.attr('src', null);
|
|
550
|
+
// Add <source> child elements
|
|
551
|
+
for (let index = numSources; index < 2; index++) {
|
|
552
|
+
if (data[sources[index]]) {
|
|
553
|
+
const source = new global$2('source', 1);
|
|
554
|
+
source.attr('src', data[sources[index]]);
|
|
555
|
+
source.attr('type', data[sources[index] + 'mime'] || null);
|
|
556
|
+
node.append(source);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
break;
|
|
560
|
+
case 'iframe':
|
|
561
|
+
node.attr('src', data.source);
|
|
562
|
+
break;
|
|
563
|
+
case 'object':
|
|
564
|
+
const hasImage = node.getAll('img').length > 0;
|
|
565
|
+
if (data.poster && !hasImage) {
|
|
566
|
+
node.attr('src', data.poster);
|
|
567
|
+
const img = new global$2('img', 1);
|
|
568
|
+
img.attr('src', data.poster);
|
|
569
|
+
img.attr('width', data.width);
|
|
570
|
+
img.attr('height', data.height);
|
|
571
|
+
node.append(img);
|
|
572
|
+
}
|
|
573
|
+
break;
|
|
574
|
+
case 'source':
|
|
575
|
+
if (sourceCount < 2) {
|
|
576
|
+
node.attr('src', data[sources[sourceCount]]);
|
|
577
|
+
node.attr('type', data[sources[sourceCount] + 'mime'] || null);
|
|
578
|
+
if (!data[sources[sourceCount]]) {
|
|
579
|
+
node.remove();
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
sourceCount++;
|
|
584
|
+
break;
|
|
585
|
+
case 'img':
|
|
586
|
+
if (!data.poster) {
|
|
587
|
+
node.remove();
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return global$1({}, schema).serialize(rootNode);
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const urlPatterns = [
|
|
599
|
+
{
|
|
600
|
+
regex: /youtu\.be\/([\w\-_\?&=.]+)/i,
|
|
601
|
+
type: 'iframe', w: 560, h: 314,
|
|
602
|
+
url: 'www.youtube.com/embed/$1',
|
|
603
|
+
allowFullscreen: true
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
regex: /youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i,
|
|
607
|
+
type: 'iframe', w: 560, h: 314,
|
|
608
|
+
url: 'www.youtube.com/embed/$2?$4',
|
|
609
|
+
allowFullscreen: true
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,
|
|
613
|
+
type: 'iframe', w: 560, h: 314,
|
|
614
|
+
url: 'www.youtube.com/embed/$1',
|
|
615
|
+
allowFullscreen: true
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
regex: /vimeo\.com\/([0-9]+)\?h=(\w+)/,
|
|
619
|
+
type: 'iframe', w: 425, h: 350,
|
|
620
|
+
url: 'player.vimeo.com/video/$1?h=$2&title=0&byline=0&portrait=0&color=8dc7dc',
|
|
621
|
+
allowFullscreen: true
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
regex: /vimeo\.com\/(.*)\/([0-9]+)\?h=(\w+)/,
|
|
625
|
+
type: 'iframe', w: 425, h: 350,
|
|
626
|
+
url: 'player.vimeo.com/video/$2?h=$3&title=0&byline=0',
|
|
627
|
+
allowFullscreen: true
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
regex: /vimeo\.com\/([0-9]+)/,
|
|
631
|
+
type: 'iframe', w: 425, h: 350,
|
|
632
|
+
url: 'player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc',
|
|
633
|
+
allowFullscreen: true
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
regex: /vimeo\.com\/(.*)\/([0-9]+)/,
|
|
637
|
+
type: 'iframe', w: 425, h: 350,
|
|
638
|
+
url: 'player.vimeo.com/video/$2?title=0&byline=0',
|
|
639
|
+
allowFullscreen: true
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,
|
|
643
|
+
type: 'iframe', w: 425, h: 350,
|
|
644
|
+
url: 'maps.google.com/maps/ms?msid=$2&output=embed"',
|
|
645
|
+
allowFullscreen: false
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
regex: /dailymotion\.com\/video\/([^_]+)/,
|
|
649
|
+
type: 'iframe', w: 480, h: 270,
|
|
650
|
+
url: 'www.dailymotion.com/embed/video/$1',
|
|
651
|
+
allowFullscreen: true
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
regex: /dai\.ly\/([^_]+)/,
|
|
655
|
+
type: 'iframe', w: 480, h: 270,
|
|
656
|
+
url: 'www.dailymotion.com/embed/video/$1',
|
|
657
|
+
allowFullscreen: true
|
|
658
|
+
}
|
|
659
|
+
];
|
|
660
|
+
const getProtocol = (url) => {
|
|
661
|
+
const protocolMatches = url.match(/^(https?:\/\/|www\.)(.+)$/i);
|
|
662
|
+
if (protocolMatches && protocolMatches.length > 1) {
|
|
663
|
+
return protocolMatches[1] === 'www.' ? 'https://' : protocolMatches[1];
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
return 'https://';
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
const getUrl = (pattern, url) => {
|
|
670
|
+
const protocol = getProtocol(url);
|
|
671
|
+
const match = pattern.regex.exec(url);
|
|
672
|
+
let newUrl = protocol + pattern.url;
|
|
673
|
+
if (isNonNullable(match)) {
|
|
674
|
+
for (let i = 0; i < match.length; i++) {
|
|
675
|
+
newUrl = newUrl.replace('$' + i, () => match[i] ? match[i] : '');
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return newUrl.replace(/\?$/, '');
|
|
679
|
+
};
|
|
680
|
+
const matchPattern = (url) => {
|
|
681
|
+
const patterns = urlPatterns.filter((pattern) => pattern.regex.test(url));
|
|
682
|
+
if (patterns.length > 0) {
|
|
683
|
+
return global$5.extend({}, patterns[0], { url: getUrl(patterns[0], url) });
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const getIframeHtml = (data, iframeTemplateCallback) => {
|
|
691
|
+
if (iframeTemplateCallback) {
|
|
692
|
+
return iframeTemplateCallback(data);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
const allowFullscreen = data.allowfullscreen ? ' allowFullscreen="1"' : '';
|
|
696
|
+
return '<iframe src="' + data.source + '" width="' + data.width + '" height="' + data.height + '"' + allowFullscreen + '></iframe>';
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
const getFlashHtml = (data) => {
|
|
700
|
+
let html = '<object data="' + data.source + '" width="' + data.width + '" height="' + data.height + '" type="application/x-shockwave-flash">';
|
|
701
|
+
if (data.poster) {
|
|
702
|
+
html += '<img src="' + data.poster + '" width="' + data.width + '" height="' + data.height + '" />';
|
|
703
|
+
}
|
|
704
|
+
html += '</object>';
|
|
705
|
+
return html;
|
|
706
|
+
};
|
|
707
|
+
const getAudioHtml = (data, audioTemplateCallback) => {
|
|
708
|
+
if (audioTemplateCallback) {
|
|
709
|
+
return audioTemplateCallback(data);
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
return ('<audio controls="controls" src="' + data.source + '">' +
|
|
713
|
+
(data.altsource ?
|
|
714
|
+
'\n<source src="' + data.altsource + '"' +
|
|
715
|
+
(data.altsourcemime ? ' type="' + data.altsourcemime + '"' : '') +
|
|
716
|
+
' />\n' : '') +
|
|
717
|
+
'</audio>');
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
const getVideoHtml = (data, videoTemplateCallback) => {
|
|
721
|
+
if (videoTemplateCallback) {
|
|
722
|
+
return videoTemplateCallback(data);
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
return ('<video width="' + data.width +
|
|
726
|
+
'" height="' + data.height + '"' +
|
|
727
|
+
(data.poster ? ' poster="' + data.poster + '"' : '') + ' controls="controls">\n' +
|
|
728
|
+
'<source src="' + data.source + '"' +
|
|
729
|
+
(data.sourcemime ? ' type="' + data.sourcemime + '"' : '') + ' />\n' +
|
|
730
|
+
(data.altsource ? '<source src="' + data.altsource + '"' +
|
|
731
|
+
(data.altsourcemime ? ' type="' + data.altsourcemime + '"' : '') + ' />\n' : '') +
|
|
732
|
+
'</video>');
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
const dataToHtml = (editor, dataIn) => {
|
|
736
|
+
var _a;
|
|
737
|
+
const data = global$5.extend({}, dataIn);
|
|
738
|
+
if (!data.source) {
|
|
739
|
+
global$5.extend(data, htmlToData((_a = data.embed) !== null && _a !== void 0 ? _a : '', editor.schema));
|
|
740
|
+
if (!data.source) {
|
|
741
|
+
return '';
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
if (!data.altsource) {
|
|
745
|
+
data.altsource = '';
|
|
746
|
+
}
|
|
747
|
+
if (!data.poster) {
|
|
748
|
+
data.poster = '';
|
|
749
|
+
}
|
|
750
|
+
data.source = editor.convertURL(data.source, 'source');
|
|
751
|
+
data.altsource = editor.convertURL(data.altsource, 'source');
|
|
752
|
+
data.sourcemime = guess(data.source);
|
|
753
|
+
data.altsourcemime = guess(data.altsource);
|
|
754
|
+
data.poster = editor.convertURL(data.poster, 'poster');
|
|
755
|
+
const pattern = matchPattern(data.source);
|
|
756
|
+
if (pattern) {
|
|
757
|
+
data.source = pattern.url;
|
|
758
|
+
data.type = pattern.type;
|
|
759
|
+
data.allowfullscreen = pattern.allowFullscreen;
|
|
760
|
+
data.width = data.width || String(pattern.w);
|
|
761
|
+
data.height = data.height || String(pattern.h);
|
|
762
|
+
}
|
|
763
|
+
if (data.embed) {
|
|
764
|
+
return updateHtml(data.embed, data, true, editor.schema);
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
const audioTemplateCallback = getAudioTemplateCallback(editor);
|
|
768
|
+
const videoTemplateCallback = getVideoTemplateCallback(editor);
|
|
769
|
+
const iframeTemplateCallback = getIframeTemplateCallback(editor);
|
|
770
|
+
data.width = data.width || '300';
|
|
771
|
+
data.height = data.height || '150';
|
|
772
|
+
global$5.each(data, (value, key) => {
|
|
773
|
+
data[key] = editor.dom.encode('' + value);
|
|
774
|
+
});
|
|
775
|
+
if (data.type === 'iframe') {
|
|
776
|
+
return getIframeHtml(data, iframeTemplateCallback);
|
|
777
|
+
}
|
|
778
|
+
else if (data.sourcemime === 'application/x-shockwave-flash') {
|
|
779
|
+
return getFlashHtml(data);
|
|
780
|
+
}
|
|
781
|
+
else if (data.sourcemime.indexOf('audio') !== -1) {
|
|
782
|
+
return getAudioHtml(data, audioTemplateCallback);
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
return getVideoHtml(data, videoTemplateCallback);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
const isMediaElement = (element) => element.hasAttribute('data-mce-object') || element.hasAttribute('data-ephox-embed-iri');
|
|
791
|
+
const setup$2 = (editor) => {
|
|
792
|
+
// TINY-10774: On Safari all events bubble out even if you click on the video play button on other browsers the video element doesn't bubble the event
|
|
793
|
+
editor.on('mousedown', (e) => {
|
|
794
|
+
const previewObj = editor.dom.getParent(e.target, '.mce-preview-object');
|
|
795
|
+
if (previewObj && editor.dom.getAttrib(previewObj, 'data-mce-selected') === '2') {
|
|
796
|
+
e.stopImmediatePropagation();
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
editor.on('click keyup touchend', () => {
|
|
800
|
+
const selectedNode = editor.selection.getNode();
|
|
801
|
+
if (selectedNode && editor.dom.hasClass(selectedNode, 'mce-preview-object')) {
|
|
802
|
+
if (editor.dom.getAttrib(selectedNode, 'data-mce-selected')) {
|
|
803
|
+
selectedNode.setAttribute('data-mce-selected', '2');
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
editor.on('ObjectResized', (e) => {
|
|
808
|
+
const target = e.target;
|
|
809
|
+
if (target.getAttribute('data-mce-object')) {
|
|
810
|
+
let html = target.getAttribute('data-mce-html');
|
|
811
|
+
if (html) {
|
|
812
|
+
html = unescape(html);
|
|
813
|
+
target.setAttribute('data-mce-html', escape(updateHtml(html, {
|
|
814
|
+
width: String(e.width),
|
|
815
|
+
height: String(e.height)
|
|
816
|
+
}, false, editor.schema)));
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
const cache = {};
|
|
823
|
+
const embedPromise = (data, dataToHtml, handler) => {
|
|
824
|
+
return new Promise((res, rej) => {
|
|
825
|
+
const wrappedResolve = (response) => {
|
|
826
|
+
if (response.html) {
|
|
827
|
+
cache[data.source] = response;
|
|
828
|
+
}
|
|
829
|
+
return res({
|
|
830
|
+
url: data.source,
|
|
831
|
+
html: response.html ? response.html : dataToHtml(data)
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
if (cache[data.source]) {
|
|
835
|
+
wrappedResolve(cache[data.source]);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
handler({ url: data.source }).then(wrappedResolve).catch(rej);
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
};
|
|
842
|
+
const defaultPromise = (data, dataToHtml) => Promise.resolve({ html: dataToHtml(data), url: data.source });
|
|
843
|
+
const loadedData = (editor) => (data) => dataToHtml(editor, data);
|
|
844
|
+
const getEmbedHtml = (editor, data) => {
|
|
845
|
+
const embedHandler = getUrlResolver(editor);
|
|
846
|
+
return embedHandler ? embedPromise(data, loadedData(editor), embedHandler) : defaultPromise(data, loadedData(editor));
|
|
847
|
+
};
|
|
848
|
+
const isCached = (url) => has(cache, url);
|
|
849
|
+
|
|
850
|
+
const extractMeta = (sourceInput, data) => get$1(data, sourceInput).bind((mainData) => get$1(mainData, 'meta'));
|
|
851
|
+
const getValue = (data, metaData, sourceInput) => (prop) => {
|
|
852
|
+
// Cases:
|
|
853
|
+
// 1. Get the nested value prop (component is the executed urlinput)
|
|
854
|
+
// 2. Get from metadata (a urlinput was executed but urlinput != this component)
|
|
855
|
+
// 3. Not a urlinput so just get string
|
|
856
|
+
// If prop === sourceInput do 1, 2 then 3, else do 2 then 1 or 3
|
|
857
|
+
// ASSUMPTION: we only want to get values for props that already exist in data
|
|
858
|
+
const getFromData = () => get$1(data, prop);
|
|
859
|
+
const getFromMetaData = () => get$1(metaData, prop);
|
|
860
|
+
const getNonEmptyValue = (c) => get$1(c, 'value').bind((v) => v.length > 0 ? Optional.some(v) : Optional.none());
|
|
861
|
+
const getFromValueFirst = () => getFromData().bind((child) => isObject(child)
|
|
862
|
+
? getNonEmptyValue(child).orThunk(getFromMetaData)
|
|
863
|
+
: getFromMetaData().orThunk(() => Optional.from(child)));
|
|
864
|
+
const getFromMetaFirst = () => getFromMetaData().orThunk(() => getFromData().bind((child) => isObject(child)
|
|
865
|
+
? getNonEmptyValue(child)
|
|
866
|
+
: Optional.from(child)));
|
|
867
|
+
return { [prop]: (prop === sourceInput ? getFromValueFirst() : getFromMetaFirst()).getOr('') };
|
|
868
|
+
};
|
|
869
|
+
const getDimensions = (data, metaData) => {
|
|
870
|
+
const dimensions = {};
|
|
871
|
+
get$1(data, 'dimensions').each((dims) => {
|
|
872
|
+
each$1(['width', 'height'], (prop) => {
|
|
873
|
+
get$1(metaData, prop).orThunk(() => get$1(dims, prop)).each((value) => dimensions[prop] = value);
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
return dimensions;
|
|
877
|
+
};
|
|
878
|
+
const unwrap = (data, sourceInput) => {
|
|
879
|
+
const metaData = sourceInput && sourceInput !== 'dimensions' ? extractMeta(sourceInput, data).getOr({}) : {};
|
|
880
|
+
const get = getValue(data, metaData, sourceInput);
|
|
881
|
+
return {
|
|
882
|
+
...get('source'),
|
|
883
|
+
...get('altsource'),
|
|
884
|
+
...get('poster'),
|
|
885
|
+
...get('embed'),
|
|
886
|
+
...getDimensions(data, metaData)
|
|
887
|
+
};
|
|
888
|
+
};
|
|
889
|
+
const wrap = (data) => {
|
|
890
|
+
const wrapped = {
|
|
891
|
+
...data,
|
|
892
|
+
source: { value: get$1(data, 'source').getOr('') },
|
|
893
|
+
altsource: { value: get$1(data, 'altsource').getOr('') },
|
|
894
|
+
poster: { value: get$1(data, 'poster').getOr('') }
|
|
895
|
+
};
|
|
896
|
+
// Add additional size values that may or may not have been in the html
|
|
897
|
+
each$1(['width', 'height'], (prop) => {
|
|
898
|
+
get$1(data, prop).each((value) => {
|
|
899
|
+
const dimensions = wrapped.dimensions || {};
|
|
900
|
+
dimensions[prop] = value;
|
|
901
|
+
wrapped.dimensions = dimensions;
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
return wrapped;
|
|
905
|
+
};
|
|
906
|
+
const handleError = (editor) => (error) => {
|
|
907
|
+
const errorMessage = error && error.msg ?
|
|
908
|
+
'Media embed handler error: ' + error.msg :
|
|
909
|
+
'Media embed handler threw unknown error.';
|
|
910
|
+
editor.notificationManager.open({ type: 'error', text: errorMessage });
|
|
911
|
+
};
|
|
912
|
+
const getEditorData = (editor) => {
|
|
913
|
+
const element = editor.selection.getNode();
|
|
914
|
+
const snippet = isMediaElement(element) ? editor.serializer.serialize(element, { selection: true }) : '';
|
|
915
|
+
const data = htmlToData(snippet, editor.schema);
|
|
916
|
+
const getDimensionsOfElement = () => {
|
|
917
|
+
if (isEmbedIframe(data.source, data.type)) {
|
|
918
|
+
const rect = editor.dom.getRect(element);
|
|
919
|
+
return {
|
|
920
|
+
width: rect.w.toString().replace(/px$/, ''),
|
|
921
|
+
height: rect.h.toString().replace(/px$/, ''),
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
return {};
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
const dimensions = getDimensionsOfElement();
|
|
929
|
+
return {
|
|
930
|
+
embed: snippet,
|
|
931
|
+
...data,
|
|
932
|
+
...dimensions
|
|
933
|
+
};
|
|
934
|
+
};
|
|
935
|
+
const addEmbedHtml = (api, editor) => (response) => {
|
|
936
|
+
// Only set values if a URL has been defined
|
|
937
|
+
if (isString(response.url) && response.url.trim().length > 0) {
|
|
938
|
+
const html = response.html;
|
|
939
|
+
const snippetData = htmlToData(html, editor.schema);
|
|
940
|
+
const nuData = {
|
|
941
|
+
...snippetData,
|
|
942
|
+
source: response.url,
|
|
943
|
+
embed: html
|
|
944
|
+
};
|
|
945
|
+
api.setData(wrap(nuData));
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
const selectPlaceholder = (editor, beforeObjects) => {
|
|
949
|
+
const afterObjects = editor.dom.select('*[data-mce-object]');
|
|
950
|
+
// Find new image placeholder so we can select it
|
|
951
|
+
for (let i = 0; i < beforeObjects.length; i++) {
|
|
952
|
+
for (let y = afterObjects.length - 1; y >= 0; y--) {
|
|
953
|
+
if (beforeObjects[i] === afterObjects[y]) {
|
|
954
|
+
afterObjects.splice(y, 1);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
editor.selection.select(afterObjects[0]);
|
|
959
|
+
};
|
|
960
|
+
const handleInsert = (editor, html) => {
|
|
961
|
+
const beforeObjects = editor.dom.select('*[data-mce-object]');
|
|
962
|
+
editor.insertContent(html);
|
|
963
|
+
selectPlaceholder(editor, beforeObjects);
|
|
964
|
+
editor.nodeChanged();
|
|
965
|
+
};
|
|
966
|
+
const isEmbedIframe = (url, mediaDataType) => isNonNullable(mediaDataType) && mediaDataType === 'ephox-embed-iri' && isNonNullable(matchPattern(url));
|
|
967
|
+
const shouldInsertAsNewIframe = (prevData, newData) => {
|
|
968
|
+
const hasDimensionsChanged = (prevData, newData) => prevData.width !== newData.width || prevData.height !== newData.height;
|
|
969
|
+
return hasDimensionsChanged(prevData, newData) && isEmbedIframe(newData.source, prevData.type);
|
|
970
|
+
};
|
|
971
|
+
const submitForm = (prevData, newData, editor) => {
|
|
972
|
+
var _a;
|
|
973
|
+
newData.embed =
|
|
974
|
+
shouldInsertAsNewIframe(prevData, newData) && hasDimensions(editor)
|
|
975
|
+
? dataToHtml(editor, { ...newData, embed: '' })
|
|
976
|
+
: updateHtml((_a = newData.embed) !== null && _a !== void 0 ? _a : '', newData, false, editor.schema);
|
|
977
|
+
// Only fetch the embed HTML content if the URL has changed from what it previously was
|
|
978
|
+
if (newData.embed && (prevData.source === newData.source || isCached(newData.source))) {
|
|
979
|
+
handleInsert(editor, newData.embed);
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
getEmbedHtml(editor, newData)
|
|
983
|
+
.then((response) => {
|
|
984
|
+
handleInsert(editor, response.html);
|
|
985
|
+
}).catch(handleError(editor));
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
const showDialog = (editor) => {
|
|
989
|
+
const editorData = getEditorData(editor);
|
|
990
|
+
const currentData = Cell(editorData);
|
|
991
|
+
const initialData = wrap(editorData);
|
|
992
|
+
const handleSource = (prevData, api) => {
|
|
993
|
+
const serviceData = unwrap(api.getData(), 'source');
|
|
994
|
+
// If a new URL is entered, then clear the embed html and fetch the new data
|
|
995
|
+
if (prevData.source !== serviceData.source) {
|
|
996
|
+
addEmbedHtml(win, editor)({ url: serviceData.source, html: '' });
|
|
997
|
+
getEmbedHtml(editor, serviceData)
|
|
998
|
+
.then(addEmbedHtml(win, editor))
|
|
999
|
+
.catch(handleError(editor));
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
const handleEmbed = (api) => {
|
|
1003
|
+
var _a;
|
|
1004
|
+
const data = unwrap(api.getData());
|
|
1005
|
+
const dataFromEmbed = htmlToData((_a = data.embed) !== null && _a !== void 0 ? _a : '', editor.schema);
|
|
1006
|
+
api.setData(wrap(dataFromEmbed));
|
|
1007
|
+
};
|
|
1008
|
+
const handleUpdate = (api, sourceInput, prevData) => {
|
|
1009
|
+
const dialogData = unwrap(api.getData(), sourceInput);
|
|
1010
|
+
const data = shouldInsertAsNewIframe(prevData, dialogData) && hasDimensions(editor)
|
|
1011
|
+
? { ...dialogData, embed: '' }
|
|
1012
|
+
: dialogData;
|
|
1013
|
+
const embed = dataToHtml(editor, data);
|
|
1014
|
+
api.setData(wrap({
|
|
1015
|
+
...data,
|
|
1016
|
+
embed
|
|
1017
|
+
}));
|
|
1018
|
+
};
|
|
1019
|
+
const mediaInput = [{
|
|
1020
|
+
name: 'source',
|
|
1021
|
+
type: 'urlinput',
|
|
1022
|
+
filetype: 'media',
|
|
1023
|
+
label: 'Source',
|
|
1024
|
+
picker_text: 'Browse files'
|
|
1025
|
+
}];
|
|
1026
|
+
const sizeInput = !hasDimensions(editor) ? [] : [{
|
|
1027
|
+
type: 'sizeinput',
|
|
1028
|
+
name: 'dimensions',
|
|
1029
|
+
label: 'Constrain proportions',
|
|
1030
|
+
constrain: true
|
|
1031
|
+
}];
|
|
1032
|
+
const generalTab = {
|
|
1033
|
+
title: 'General',
|
|
1034
|
+
name: 'general',
|
|
1035
|
+
items: flatten([mediaInput, sizeInput])
|
|
1036
|
+
};
|
|
1037
|
+
const embedTextarea = {
|
|
1038
|
+
type: 'textarea',
|
|
1039
|
+
name: 'embed',
|
|
1040
|
+
label: 'Paste your embed code below:'
|
|
1041
|
+
};
|
|
1042
|
+
const embedTab = {
|
|
1043
|
+
title: 'Embed',
|
|
1044
|
+
items: [
|
|
1045
|
+
embedTextarea
|
|
1046
|
+
]
|
|
1047
|
+
};
|
|
1048
|
+
const advancedFormItems = [];
|
|
1049
|
+
if (hasAltSource(editor)) {
|
|
1050
|
+
advancedFormItems.push({
|
|
1051
|
+
name: 'altsource',
|
|
1052
|
+
type: 'urlinput',
|
|
1053
|
+
filetype: 'media',
|
|
1054
|
+
label: 'Alternative source URL'
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
if (hasPoster(editor)) {
|
|
1058
|
+
advancedFormItems.push({
|
|
1059
|
+
name: 'poster',
|
|
1060
|
+
type: 'urlinput',
|
|
1061
|
+
filetype: 'image',
|
|
1062
|
+
label: 'Media poster (Image URL)'
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
const advancedTab = {
|
|
1066
|
+
title: 'Advanced',
|
|
1067
|
+
name: 'advanced',
|
|
1068
|
+
items: advancedFormItems
|
|
1069
|
+
};
|
|
1070
|
+
const tabs = [
|
|
1071
|
+
generalTab,
|
|
1072
|
+
embedTab
|
|
1073
|
+
];
|
|
1074
|
+
if (advancedFormItems.length > 0) {
|
|
1075
|
+
tabs.push(advancedTab);
|
|
1076
|
+
}
|
|
1077
|
+
const body = {
|
|
1078
|
+
type: 'tabpanel',
|
|
1079
|
+
tabs
|
|
1080
|
+
};
|
|
1081
|
+
const win = editor.windowManager.open({
|
|
1082
|
+
title: 'Insert/Edit Media',
|
|
1083
|
+
size: 'normal',
|
|
1084
|
+
body,
|
|
1085
|
+
buttons: [
|
|
1086
|
+
{
|
|
1087
|
+
type: 'cancel',
|
|
1088
|
+
name: 'cancel',
|
|
1089
|
+
text: 'Cancel'
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
type: 'submit',
|
|
1093
|
+
name: 'save',
|
|
1094
|
+
text: 'Save',
|
|
1095
|
+
primary: true
|
|
1096
|
+
}
|
|
1097
|
+
],
|
|
1098
|
+
onSubmit: (api) => {
|
|
1099
|
+
const serviceData = unwrap(api.getData());
|
|
1100
|
+
submitForm(currentData.get(), serviceData, editor);
|
|
1101
|
+
api.close();
|
|
1102
|
+
},
|
|
1103
|
+
onChange: (api, detail) => {
|
|
1104
|
+
switch (detail.name) {
|
|
1105
|
+
case 'source':
|
|
1106
|
+
handleSource(currentData.get(), api);
|
|
1107
|
+
break;
|
|
1108
|
+
case 'embed':
|
|
1109
|
+
handleEmbed(api);
|
|
1110
|
+
break;
|
|
1111
|
+
case 'dimensions':
|
|
1112
|
+
case 'altsource':
|
|
1113
|
+
case 'poster':
|
|
1114
|
+
handleUpdate(api, detail.name, currentData.get());
|
|
1115
|
+
break;
|
|
1116
|
+
}
|
|
1117
|
+
currentData.set(unwrap(api.getData()));
|
|
1118
|
+
},
|
|
1119
|
+
initialData
|
|
1120
|
+
});
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
const get = (editor) => {
|
|
1124
|
+
const showDialog$1 = () => {
|
|
1125
|
+
showDialog(editor);
|
|
1126
|
+
};
|
|
1127
|
+
return {
|
|
1128
|
+
showDialog: showDialog$1
|
|
1129
|
+
};
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
const register$1 = (editor) => {
|
|
1133
|
+
const showDialog$1 = () => {
|
|
1134
|
+
showDialog(editor);
|
|
1135
|
+
};
|
|
1136
|
+
editor.addCommand('mceMedia', showDialog$1);
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
var global = tinymce.util.Tools.resolve('tinymce.Env');
|
|
1140
|
+
|
|
1141
|
+
const isLiveEmbedNode = (node) => {
|
|
1142
|
+
const name = node.name;
|
|
1143
|
+
return name === 'iframe' || name === 'video' || name === 'audio';
|
|
1144
|
+
};
|
|
1145
|
+
const getDimension = (node, styles, dimension, defaultValue = null) => {
|
|
1146
|
+
const value = node.attr(dimension);
|
|
1147
|
+
if (isNonNullable(value)) {
|
|
1148
|
+
return value;
|
|
1149
|
+
}
|
|
1150
|
+
else if (!has(styles, dimension)) {
|
|
1151
|
+
return defaultValue;
|
|
1152
|
+
}
|
|
1153
|
+
else {
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
const setDimensions = (node, previewNode, styles) => {
|
|
1158
|
+
// Apply dimensions for video elements to maintain legacy behaviour
|
|
1159
|
+
const useDefaults = previewNode.name === 'img' || node.name === 'video';
|
|
1160
|
+
// Determine the defaults
|
|
1161
|
+
const defaultWidth = useDefaults ? '300' : null;
|
|
1162
|
+
const fallbackHeight = node.name === 'audio' ? '30' : '150';
|
|
1163
|
+
const defaultHeight = useDefaults ? fallbackHeight : null;
|
|
1164
|
+
previewNode.attr({
|
|
1165
|
+
width: getDimension(node, styles, 'width', defaultWidth),
|
|
1166
|
+
height: getDimension(node, styles, 'height', defaultHeight)
|
|
1167
|
+
});
|
|
1168
|
+
};
|
|
1169
|
+
const appendNodeContent = (editor, nodeName, previewNode, html) => {
|
|
1170
|
+
const newNode = Parser(editor.schema).parse(html, { context: nodeName });
|
|
1171
|
+
while (newNode.firstChild) {
|
|
1172
|
+
previewNode.append(newNode.firstChild);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
const createPlaceholderNode = (editor, node) => {
|
|
1176
|
+
const name = node.name;
|
|
1177
|
+
const placeHolder = new global$2('img', 1);
|
|
1178
|
+
retainAttributesAndInnerHtml(editor, node, placeHolder);
|
|
1179
|
+
setDimensions(node, placeHolder, {});
|
|
1180
|
+
placeHolder.attr({
|
|
1181
|
+
'style': node.attr('style'),
|
|
1182
|
+
'src': global.transparentSrc,
|
|
1183
|
+
'data-mce-object': name,
|
|
1184
|
+
'class': 'mce-object mce-object-' + name
|
|
1185
|
+
});
|
|
1186
|
+
return placeHolder;
|
|
1187
|
+
};
|
|
1188
|
+
const createPreviewNode = (editor, node) => {
|
|
1189
|
+
var _a;
|
|
1190
|
+
const name = node.name;
|
|
1191
|
+
const previewWrapper = new global$2('span', 1);
|
|
1192
|
+
previewWrapper.attr({
|
|
1193
|
+
'contentEditable': 'false',
|
|
1194
|
+
'style': node.attr('style'),
|
|
1195
|
+
'data-mce-object': name,
|
|
1196
|
+
'class': 'mce-preview-object mce-object-' + name
|
|
1197
|
+
});
|
|
1198
|
+
retainAttributesAndInnerHtml(editor, node, previewWrapper);
|
|
1199
|
+
const styles = editor.dom.parseStyle((_a = node.attr('style')) !== null && _a !== void 0 ? _a : '');
|
|
1200
|
+
const previewNode = new global$2(name, 1);
|
|
1201
|
+
setDimensions(node, previewNode, styles);
|
|
1202
|
+
previewNode.attr({
|
|
1203
|
+
src: node.attr('src'),
|
|
1204
|
+
style: node.attr('style'),
|
|
1205
|
+
class: node.attr('class')
|
|
1206
|
+
});
|
|
1207
|
+
if (name === 'iframe') {
|
|
1208
|
+
previewNode.attr({
|
|
1209
|
+
allowfullscreen: node.attr('allowfullscreen'),
|
|
1210
|
+
frameborder: '0',
|
|
1211
|
+
sandbox: node.attr('sandbox'),
|
|
1212
|
+
referrerpolicy: node.attr('referrerpolicy')
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
else {
|
|
1216
|
+
// Exclude autoplay as we don't want video/audio to play by default
|
|
1217
|
+
const attrs = ['controls', 'crossorigin', 'currentTime', 'loop', 'muted', 'poster', 'preload'];
|
|
1218
|
+
each$1(attrs, (attrName) => {
|
|
1219
|
+
previewNode.attr(attrName, node.attr(attrName));
|
|
1220
|
+
});
|
|
1221
|
+
// Recreate the child nodes using the sanitized inner HTML
|
|
1222
|
+
const sanitizedHtml = previewWrapper.attr('data-mce-html');
|
|
1223
|
+
if (isNonNullable(sanitizedHtml)) {
|
|
1224
|
+
appendNodeContent(editor, name, previewNode, unescape(sanitizedHtml));
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
const shimNode = new global$2('span', 1);
|
|
1228
|
+
shimNode.attr('class', 'mce-shim');
|
|
1229
|
+
previewWrapper.append(previewNode);
|
|
1230
|
+
previewWrapper.append(shimNode);
|
|
1231
|
+
return previewWrapper;
|
|
1232
|
+
};
|
|
1233
|
+
const retainAttributesAndInnerHtml = (editor, sourceNode, targetNode) => {
|
|
1234
|
+
var _a;
|
|
1235
|
+
// Prefix all attributes except internal (data-mce-*), width, height and style since we
|
|
1236
|
+
// will add these to the placeholder
|
|
1237
|
+
const attribs = (_a = sourceNode.attributes) !== null && _a !== void 0 ? _a : [];
|
|
1238
|
+
let ai = attribs.length;
|
|
1239
|
+
while (ai--) {
|
|
1240
|
+
const attrName = attribs[ai].name;
|
|
1241
|
+
let attrValue = attribs[ai].value;
|
|
1242
|
+
if (attrName !== 'width' && attrName !== 'height' && attrName !== 'style' && !startsWith(attrName, 'data-mce-')) {
|
|
1243
|
+
if (attrName === 'data' || attrName === 'src') {
|
|
1244
|
+
attrValue = editor.convertURL(attrValue, attrName);
|
|
1245
|
+
}
|
|
1246
|
+
targetNode.attr('data-mce-p-' + attrName, attrValue);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
// Place the inner HTML contents inside an escaped attribute
|
|
1250
|
+
// This enables us to copy/paste the fake object
|
|
1251
|
+
const serializer = global$1({ inner: true }, editor.schema);
|
|
1252
|
+
const tempNode = new global$2('div', 1);
|
|
1253
|
+
each$1(sourceNode.children(), (child) => tempNode.append(child));
|
|
1254
|
+
const innerHtml = serializer.serialize(tempNode);
|
|
1255
|
+
if (innerHtml) {
|
|
1256
|
+
targetNode.attr('data-mce-html', escape(innerHtml));
|
|
1257
|
+
targetNode.empty();
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
const isPageEmbedWrapper = (node) => {
|
|
1261
|
+
const nodeClass = node.attr('class');
|
|
1262
|
+
return isString(nodeClass) && /\btiny-pageembed\b/.test(nodeClass);
|
|
1263
|
+
};
|
|
1264
|
+
const isWithinEmbedWrapper = (node) => {
|
|
1265
|
+
let tempNode = node;
|
|
1266
|
+
while ((tempNode = tempNode.parent)) {
|
|
1267
|
+
if (tempNode.attr('data-ephox-embed-iri') || isPageEmbedWrapper(tempNode)) {
|
|
1268
|
+
return true;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return false;
|
|
1272
|
+
};
|
|
1273
|
+
const placeHolderConverter = (editor) => (nodes) => {
|
|
1274
|
+
let i = nodes.length;
|
|
1275
|
+
let node;
|
|
1276
|
+
while (i--) {
|
|
1277
|
+
node = nodes[i];
|
|
1278
|
+
if (!node.parent) {
|
|
1279
|
+
continue;
|
|
1280
|
+
}
|
|
1281
|
+
if (node.parent.attr('data-mce-object')) {
|
|
1282
|
+
continue;
|
|
1283
|
+
}
|
|
1284
|
+
if (isLiveEmbedNode(node) && hasLiveEmbeds(editor)) {
|
|
1285
|
+
if (!isWithinEmbedWrapper(node)) {
|
|
1286
|
+
node.replace(createPreviewNode(editor, node));
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
else {
|
|
1290
|
+
if (!isWithinEmbedWrapper(node)) {
|
|
1291
|
+
node.replace(createPlaceholderNode(editor, node));
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
const parseAndSanitize = (editor, context, html) => {
|
|
1298
|
+
const getEditorOption = editor.options.get;
|
|
1299
|
+
const sanitize = getEditorOption('xss_sanitization');
|
|
1300
|
+
const validate = shouldFilterHtml(editor);
|
|
1301
|
+
return Parser(editor.schema, { sanitize, validate }).parse(html, { context });
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
const setup$1 = (editor) => {
|
|
1305
|
+
editor.on('PreInit', () => {
|
|
1306
|
+
const { schema, serializer, parser } = editor;
|
|
1307
|
+
// Set browser specific allowFullscreen attribs as boolean
|
|
1308
|
+
const boolAttrs = schema.getBoolAttrs();
|
|
1309
|
+
each$1('webkitallowfullscreen mozallowfullscreen'.split(' '), (name) => {
|
|
1310
|
+
boolAttrs[name] = {};
|
|
1311
|
+
});
|
|
1312
|
+
// Add some non-standard attributes to the schema
|
|
1313
|
+
each({
|
|
1314
|
+
embed: ['wmode']
|
|
1315
|
+
}, (attrs, name) => {
|
|
1316
|
+
const rule = schema.getElementRule(name);
|
|
1317
|
+
if (rule) {
|
|
1318
|
+
each$1(attrs, (attr) => {
|
|
1319
|
+
rule.attributes[attr] = {};
|
|
1320
|
+
rule.attributesOrder.push(attr);
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
// Converts iframe, video etc into placeholder images
|
|
1325
|
+
parser.addNodeFilter('iframe,video,audio,object,embed', placeHolderConverter(editor));
|
|
1326
|
+
// Replaces placeholder images with real elements for video, object, iframe etc
|
|
1327
|
+
serializer.addAttributeFilter('data-mce-object', (nodes, name) => {
|
|
1328
|
+
var _a;
|
|
1329
|
+
let i = nodes.length;
|
|
1330
|
+
while (i--) {
|
|
1331
|
+
const node = nodes[i];
|
|
1332
|
+
if (!node.parent) {
|
|
1333
|
+
continue;
|
|
1334
|
+
}
|
|
1335
|
+
const realElmName = node.attr(name);
|
|
1336
|
+
const realElm = new global$2(realElmName, 1);
|
|
1337
|
+
// Add width/height to everything but audio
|
|
1338
|
+
if (realElmName !== 'audio') {
|
|
1339
|
+
const className = node.attr('class');
|
|
1340
|
+
if (className && className.indexOf('mce-preview-object') !== -1 && node.firstChild) {
|
|
1341
|
+
realElm.attr({
|
|
1342
|
+
width: node.firstChild.attr('width'),
|
|
1343
|
+
height: node.firstChild.attr('height')
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
realElm.attr({
|
|
1348
|
+
width: node.attr('width'),
|
|
1349
|
+
height: node.attr('height')
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
realElm.attr({
|
|
1354
|
+
style: node.attr('style')
|
|
1355
|
+
});
|
|
1356
|
+
// Unprefix all placeholder attributes
|
|
1357
|
+
const attribs = (_a = node.attributes) !== null && _a !== void 0 ? _a : [];
|
|
1358
|
+
let ai = attribs.length;
|
|
1359
|
+
while (ai--) {
|
|
1360
|
+
const attrName = attribs[ai].name;
|
|
1361
|
+
if (attrName.indexOf('data-mce-p-') === 0) {
|
|
1362
|
+
realElm.attr(attrName.substr(11), attribs[ai].value);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
// Inject innerhtml
|
|
1366
|
+
const innerHtml = node.attr('data-mce-html');
|
|
1367
|
+
if (innerHtml) {
|
|
1368
|
+
const fragment = parseAndSanitize(editor, realElmName, unescape(innerHtml));
|
|
1369
|
+
each$1(fragment.children(), (child) => realElm.append(child));
|
|
1370
|
+
}
|
|
1371
|
+
node.replace(realElm);
|
|
1372
|
+
}
|
|
1373
|
+
});
|
|
1374
|
+
});
|
|
1375
|
+
editor.on('SetContent', () => {
|
|
1376
|
+
// TODO: This shouldn't be needed there should be a way to mark bogus
|
|
1377
|
+
// elements so they are never removed except external save
|
|
1378
|
+
const dom = editor.dom;
|
|
1379
|
+
each$1(dom.select('span.mce-preview-object'), (elm) => {
|
|
1380
|
+
if (dom.select('span.mce-shim', elm).length === 0) {
|
|
1381
|
+
dom.add(elm, 'span', { class: 'mce-shim' });
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1387
|
+
const setup = (editor) => {
|
|
1388
|
+
editor.on('ResolveName', (e) => {
|
|
1389
|
+
let name;
|
|
1390
|
+
if (e.target.nodeType === 1 && (name = e.target.getAttribute('data-mce-object'))) {
|
|
1391
|
+
e.name = name;
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
const onSetupEditable = (editor) => (api) => {
|
|
1397
|
+
const nodeChanged = () => {
|
|
1398
|
+
api.setEnabled(editor.selection.isEditable());
|
|
1399
|
+
};
|
|
1400
|
+
editor.on('NodeChange', nodeChanged);
|
|
1401
|
+
nodeChanged();
|
|
1402
|
+
return () => {
|
|
1403
|
+
editor.off('NodeChange', nodeChanged);
|
|
1404
|
+
};
|
|
1405
|
+
};
|
|
1406
|
+
const register = (editor) => {
|
|
1407
|
+
const onAction = () => editor.execCommand('mceMedia');
|
|
1408
|
+
editor.ui.registry.addToggleButton('media', {
|
|
1409
|
+
tooltip: 'Insert/edit media',
|
|
1410
|
+
icon: 'embed',
|
|
1411
|
+
onAction,
|
|
1412
|
+
onSetup: (buttonApi) => {
|
|
1413
|
+
const selection = editor.selection;
|
|
1414
|
+
buttonApi.setActive(isMediaElement(selection.getNode()));
|
|
1415
|
+
const unbindSelectorChanged = selection.selectorChangedWithUnbind('img[data-mce-object],span[data-mce-object],div[data-ephox-embed-iri]', buttonApi.setActive).unbind;
|
|
1416
|
+
const unbindEditable = onSetupEditable(editor)(buttonApi);
|
|
1417
|
+
return () => {
|
|
1418
|
+
unbindSelectorChanged();
|
|
1419
|
+
unbindEditable();
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
editor.ui.registry.addMenuItem('media', {
|
|
1424
|
+
icon: 'embed',
|
|
1425
|
+
text: 'Media...',
|
|
1426
|
+
onAction,
|
|
1427
|
+
onSetup: onSetupEditable(editor)
|
|
1428
|
+
});
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
var Plugin = () => {
|
|
1432
|
+
global$6.add('media', (editor) => {
|
|
1433
|
+
register$2(editor);
|
|
1434
|
+
register$1(editor);
|
|
1435
|
+
register(editor);
|
|
1436
|
+
setup(editor);
|
|
1437
|
+
setup$1(editor);
|
|
1438
|
+
setup$2(editor);
|
|
1439
|
+
return get(editor);
|
|
1440
|
+
});
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1443
|
+
Plugin();
|
|
1444
|
+
/** *****
|
|
1445
|
+
* DO NOT EXPORT ANYTHING
|
|
1446
|
+
*
|
|
1447
|
+
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
|
|
1448
|
+
*******/
|
|
1449
|
+
|
|
1450
|
+
})();
|