diff --git a/app/packs/src/decidim/cfj/editor/extensions/iframe/index.js b/app/packs/src/decidim/cfj/editor/extensions/iframe/index.js new file mode 100644 index 000000000..43bdf2fd2 --- /dev/null +++ b/app/packs/src/decidim/cfj/editor/extensions/iframe/index.js @@ -0,0 +1,72 @@ +import { Node } from "@tiptap/core" + +const iframeAllowedDomains = ["youtube.com", "vimeo.com", "docs.google.com"]; + +const isAllowedDomain = (src) => { + if (!src) return false; + for (const domain of iframeAllowedDomains) { + const domainPattern = new RegExp(`^https://${domain}/`); + if (domainPattern.test(src)) { + return true; + } + } + return false; +}; + +export default Node.create({ + name: "iframe", + group: "block", + atom: true, + defaultOptions: { + allowFullscreen: true, + HTMLAttributes: { + class: "iframe-wrapper" + } + }, + addAttributes() { + return { + src: { + default: null, + parseHTML: (element) => element.getAttribute("src"), + renderHTML: (attributes) => { + if (!isAllowedDomain(attributes.src)) { + return {}; // 無効な場合は属性をレンダリングしない + } + return { src: attributes.src }; + }, + }, + title: { + default: null, + }, + frameborder: { + default: 0, + }, + allowfullscreen: { + default: this.options.allowFullscreen, + parseHTML: () => this.options.allowFullscreen, + }, + } + }, + parseHTML() { + return [{ + tag: "iframe", + }] + }, + renderHTML({ HTMLAttributes }) { + return ["div", this.options.HTMLAttributes, ["iframe", HTMLAttributes]] + }, + addCommands() { + return { + setIframe: (options) => ({ tr, dispatch }) => { + const { selection } = tr + const node = this.type.create(options) + + if (dispatch) { + tr.replaceRangeWith(selection.from, selection.to, node) + } + + return true + }, + } + }, +}) diff --git a/app/packs/src/decidim/editor/extensions/decidim_kit/index.js b/app/packs/src/decidim/editor/extensions/decidim_kit/index.js index 3d8ec1cb4..ae01a4b8a 100644 --- a/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +++ b/app/packs/src/decidim/editor/extensions/decidim_kit/index.js @@ -17,6 +17,7 @@ import Mention from "src/decidim/editor/extensions/mention"; import VideoEmbed from "src/decidim/editor/extensions/video_embed"; import Emoji from "src/decidim/editor/extensions/emoji"; import TagEdit from "src/decidim/cfj/editor/extensions/tag_edit"; +import Iframe from "src/decidim/cfj/editor/extensions/iframe"; export default Extension.create({ name: "decidimKit", @@ -54,6 +55,7 @@ export default Extension.create({ OrderedList, CodeBlock, TagEdit, + Iframe, Underline ];