diff --git a/src/dom_components/index.js b/src/dom_components/index.js index 43eebc39f..7c8a043f1 100644 --- a/src/dom_components/index.js +++ b/src/dom_components/index.js @@ -68,6 +68,8 @@ import ComponentTextNodeView from './view/ComponentTextNodeView'; import ComponentText from './model/ComponentText'; import ComponentTextView from './view/ComponentTextView'; import ComponentWrapper from './model/ComponentWrapper'; +import ComponentFrame from './model/ComponentFrame'; +import ComponentFrameView from './view/ComponentFrameView'; export default () => { var c = {}; @@ -146,6 +148,11 @@ export default () => { model: ComponentSvg, view: ComponentSvgView }, + { + id: 'iframe', + model: ComponentFrame, + view: ComponentFrameView + }, { id: 'comment', model: ComponentComment, diff --git a/src/dom_components/model/Component.js b/src/dom_components/model/Component.js index 63878cf51..039a636d0 100644 --- a/src/dom_components/model/Component.js +++ b/src/dom_components/model/Component.js @@ -185,7 +185,7 @@ const Component = Backbone.Model.extend(Styleable).extend( this.frame = opt.frame; this.config = opt.config || {}; this.set('attributes', { - ...(this.defaults.attributes || {}), + ...(result(this, 'defaults').attributes || {}), ...(this.get('attributes') || {}) }); this.ccid = Component.createId(this, opt); diff --git a/src/dom_components/model/ComponentFrame.js b/src/dom_components/model/ComponentFrame.js new file mode 100644 index 000000000..da06b0259 --- /dev/null +++ b/src/dom_components/model/ComponentFrame.js @@ -0,0 +1,22 @@ +import Component from './Component'; + +const type = 'iframe'; + +export default Component.extend( + { + defaults() { + return { + ...Component.prototype.defaults, + type, + tagName: type, + droppable: false, + resizable: true, + traits: ['id', 'title', 'src'], + attributes: { frameborder: '0' } + }; + } + }, + { + isComponent: el => el.tagName === 'IFRAME' + } +); diff --git a/src/dom_components/view/ComponentFrameView.js b/src/dom_components/view/ComponentFrameView.js new file mode 100644 index 000000000..27b1d028e --- /dev/null +++ b/src/dom_components/view/ComponentFrameView.js @@ -0,0 +1,31 @@ +import ComponentView from './ComponentView'; +import { createEl, find, attrUp } from 'utils/dom'; + +export default ComponentView.extend({ + tagName: 'div', + + initialize(...args) { + ComponentView.prototype.initialize.apply(this, args); + this.listenTo(this.model, 'change:attributes:src', this.updateSrc); + }, + + updateSrc() { + const frame = find(this.el, 'iframe')[0]; + frame && attrUp(frame, { src: this.__getSrc() }); + }, + + render(...args) { + ComponentView.prototype.render.apply(this, args); + const frame = createEl('iframe', { + class: `${this.ppfx}no-pointer`, + style: 'width: 100%; height: 100%; border: none', + src: this.__getSrc() + }); + this.el.appendChild(frame); + return this; + }, + + __getSrc() { + return this.model.getAttributes().src || ''; + } +}); diff --git a/src/utils/dom.js b/src/utils/dom.js index 50bb43e60..9e10254c7 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -15,6 +15,13 @@ export const removeEl = el => { parent && parent.removeChild(el); }; +export const find = (el, query) => el.querySelectorAll(query); + +export const attrUp = (el, attrs = {}) => + el && + el.setAttribute && + each(attrs, (value, key) => el.setAttribute(key, value)); + export const isVisible = el => { return ( el && !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)