From 42debba142bfe09de6e2fa93d130657101710861 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 1 Jun 2021 08:28:00 +0200 Subject: [PATCH] Use scripts and styles from canvas --- src/canvas/config/config.js | 2 +- src/canvas/index.js | 3 +- src/canvas/model/Canvas.js | 25 ++++++----- src/canvas/view/CanvasView.js | 3 +- src/canvas/view/FrameView.js | 78 ++++++++++++++++++++--------------- 5 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/canvas/config/config.js b/src/canvas/config/config.js index c680f1768..b1e6f8b46 100644 --- a/src/canvas/config/config.js +++ b/src/canvas/config/config.js @@ -17,7 +17,7 @@ export default { * @example * styles: [ 'https://...1.css', 'https://...2.css' ] * // or passing objects as attributes - * scripts: [ { href: '/style.css', someattr: 'value' }, ... ] + * styles: [ { href: '/style.css', someattr: 'value' }, ... ] */ styles: [], diff --git a/src/canvas/index.js b/src/canvas/index.js index 31fea99fa..a114efbd0 100644 --- a/src/canvas/index.js +++ b/src/canvas/index.js @@ -68,9 +68,10 @@ export default () => { }; this.em = c.em; + const { scripts, styles } = c; const ppfx = c.pStylePrefix; if (ppfx) c.stylePrefix = ppfx + c.stylePrefix; - canvas = new Canvas(config); + canvas = new Canvas({ scripts, styles }, config); this.model = canvas; this.startAutoscroll = this.startAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this); diff --git a/src/canvas/model/Canvas.js b/src/canvas/model/Canvas.js index 8520c8ce8..eda0a6245 100644 --- a/src/canvas/model/Canvas.js +++ b/src/canvas/model/Canvas.js @@ -9,11 +9,15 @@ export default class Canvas extends Model { rulers: false, zoom: 100, x: 0, - y: 0 + y: 0, + // Scripts to apply on all frames + scripts: [], + // Styles to apply on all frames + styles: [] }; } - initialize(config = {}) { + initialize(props, config = {}) { const { em } = config; this.config = config; this.em = em; @@ -23,15 +27,14 @@ export default class Canvas extends Model { } init() { - const { em, config } = this; - const { styles = [], scripts = [] } = config; - const mainPage = em.get('PageManager').getMain(); - const frames = mainPage.getFrames(); - const frame = mainPage.getMainFrame(); - styles.forEach(style => frame.addLink(style)); - scripts.forEach(script => frame.addScript(script)); - this.set('frame', frame); - this.set('frames', frames); + const { em } = this; + this.set( + 'frames', + em + .get('PageManager') + .getMain() + .getFrames() + ); } _pageUpdated(page, prev) { diff --git a/src/canvas/view/CanvasView.js b/src/canvas/view/CanvasView.js index 2b946f704..9c514bcf2 100644 --- a/src/canvas/view/CanvasView.js +++ b/src/canvas/view/CanvasView.js @@ -58,8 +58,7 @@ export default Backbone.View.extend({ collection, config: { ...config, - canvasView: this, - renderContent: 1 + canvasView: this } }); }, diff --git a/src/canvas/view/FrameView.js b/src/canvas/view/FrameView.js index eb048140d..e3a7be5d7 100644 --- a/src/canvas/view/FrameView.js +++ b/src/canvas/view/FrameView.js @@ -36,7 +36,9 @@ export default Backbone.View.extend({ }; this.ppfx = this.config.pStylePrefix || ''; this.em = this.config.em; + const cvModel = this.getCanvasModel(); this.listenTo(model, 'change:head', this.updateHead); + this.listenTo(cvModel, 'change:styles', this.renderStyles); model.view = this; setViewEl(el, this); }, @@ -54,6 +56,10 @@ export default Backbone.View.extend({ return this.el; }, + getCanvasModel() { + return this.em.get('Canvas').getModel(); + }, + getWindow() { return this.getEl().contentWindow; }, @@ -219,20 +225,15 @@ export default Backbone.View.extend({ }, render() { - const { el, $el, ppfx, config } = this; - $el.attr({ class: ppfx + 'frame' }); - - if (config.scripts.length) { - this.renderScripts(); - } else if (config.renderContent) { - el.onload = this.renderBody.bind(this); - } - + const { $el, ppfx } = this; + $el.attr({ class: `${ppfx}frame` }); + this.renderScripts(); return this; }, renderScripts() { - const { el, config } = this; + const { el } = this; + const canvas = this.getCanvasModel(); const appendScript = scripts => { if (scripts.length > 0) { const src = scripts.shift(); @@ -247,38 +248,49 @@ export default Backbone.View.extend({ } }; - el.onload = () => appendScript([...config.scripts]); + el.onload = () => appendScript([...canvas.get('scripts')]); + }, + + renderStyles(opts = {}) { + const head = this.getHead(); + const canvas = this.getCanvasModel(); + const normalize = stls => + stls.map(href => ({ + tag: 'link', + attributes: { + rel: 'stylesheet', + ...(isString(href) ? { href } : href) + } + })); + const prevStyles = normalize(opts.prev || canvas.previous('styles')); + const styles = normalize(canvas.get('styles')); + const toRemove = []; + const toAdd = []; + const find = (items, stack, res) => { + items.forEach(item => { + const { href } = item.attributes; + const has = stack.some(s => s.attributes.href === href); + !has && res.push(item); + }); + }; + find(styles, prevStyles, toAdd); + find(prevStyles, styles, toRemove); + toRemove.forEach(stl => { + const el = head.querySelector(`link[href="${stl.attributes.href}"]`); + el && el.parentNode.removeChild(el); + }); + appendVNodes(head, toAdd); }, renderBody() { const { config, model, ppfx } = this; - const styles = model.getStyles(); const { em } = config; const doc = this.getDoc(); - const head = this.getHead(); const body = this.getBody(); const win = this.getWindow(); const conf = em.get('Config'); - const extStyles = []; win._isEditor = true; - - config.styles.forEach(href => - extStyles.push( - isString(href) - ? { - tag: 'link', - attributes: { href, rel: 'stylesheet' } - } - : { - tag: 'link', - attributes: { - rel: 'stylesheet', - ...href - } - } - ) - ); - extStyles.length && appendVNodes(head, extStyles); + this.renderStyles({ prev: [] }); const colorWarn = '#ffca6f'; @@ -365,7 +377,7 @@ export default Backbone.View.extend({ append( body, new CssRulesView({ - collection: styles, + collection: model.getStyles(), config: { ...em.get('CssComposer').getConfig(), frameView: this