]> BookStack Code Mirror - bookstack/commitdiff
Improved iframe embed interaction within editor
authorDan Brown <redacted>
Thu, 20 Jan 2022 13:55:44 +0000 (13:55 +0000)
committerDan Brown <redacted>
Thu, 20 Jan 2022 13:55:44 +0000 (13:55 +0000)
TODO
resources/js/editor/menu/item-iframe-button.js
resources/js/editor/node-views/IframeView.js [new file with mode: 0644]
resources/js/editor/node-views/index.js
resources/sass/_editor.scss

diff --git a/TODO b/TODO
index a882f23ef344df5c0b6e513d9b929a8cd718e717..1e5cef12d3cbb37b993074faa832cd11028c4e5f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -7,7 +7,6 @@
 ### In-Progress
 
 - Tables
-- Iframe/Media
 
 ### Features
 
@@ -33,8 +32,9 @@
 - Clear formatting, If no selection range, clear the formatting of parent block.
   - If no marks, clear the block type if text type?
 - Remove links button? (Action already in place if link href is empty).
-- Links - Limit target attribute options and validate URL.
+- Links - Validate URL.
 - Links - Integrate entity picker.
+- iFrame - Parse iframe HTML & auto-convert youtube/vimeo urls to embeds. 
 
 ### Notes
 
index da2596fca74b71413d59a106cedc3a8b035b25b0..23a6ad74e82f975b49306f0440506710f86a9a37 100644 (file)
@@ -107,6 +107,7 @@ function iframeButtonItem() {
         title: "Embed Content",
         run: onPress,
         enable: state => true,
+        active: state => (state.selection.node || {type: ''}).type === schema.nodes.iframe,
         icon: icons.iframe,
     });
 }
diff --git a/resources/js/editor/node-views/IframeView.js b/resources/js/editor/node-views/IframeView.js
new file mode 100644 (file)
index 0000000..06a9598
--- /dev/null
@@ -0,0 +1,26 @@
+class IframeView {
+    /**
+     * @param {PmNode} node
+     * @param {PmView} view
+     * @param {(function(): number)} getPos
+     */
+    constructor(node, view, getPos) {
+        this.dom = document.createElement('div');
+        this.dom.classList.add('ProseMirror-iframewrap');
+
+        this.iframe = document.createElement("iframe");
+        for (const [key, value] of Object.entries(node.attrs)) {
+            if (value) {
+                this.iframe.setAttribute(key, value);
+            }
+        }
+
+        this.dom.appendChild(this.iframe);
+    }
+
+    stopEvent() {
+        return false;
+    }
+}
+
+export default IframeView;
\ No newline at end of file
index 997ab0803a01b6443d55f6af6e2938b75c16130c..e675a1b2e6b5207cdb87cbbe28c0218c21aebb81 100644 (file)
@@ -1,7 +1,9 @@
 import ImageView from "./ImageView";
+import IframeView from "./IframeView";
 
 const views = {
     image: (node, view, getPos) => new ImageView(node, view, getPos),
+    iframe: (node, view, getPos) => new IframeView(node, view, getPos),
 };
 
 export default views;
\ No newline at end of file
index 9b6a5ea5ec9f333498fc257fe32bda0550793df3..5ef0b15e6dfb296e9b0c6ab1a2aa27cf7ed7f9ff 100644 (file)
@@ -517,7 +517,7 @@ img.ProseMirror-separator {
   }
 }
 
-.ProseMirror-imagewrap {
+.ProseMirror-imagewrap, .ProseMirror-iframewrap {
   display: inline-block;
   line-height: 0;
   font-size: 0;
@@ -532,6 +532,10 @@ img.ProseMirror-separator {
   outline: 4px solid #000;
 }
 
+.ProseMirror .ProseMirror-iframewrap iframe {
+  pointer-events: none !important;
+}
+
 .ProseMirror-dragdummy {
   position: absolute;
   z-index: 2;