diff --git a/dist/grapes.js b/dist/grapes.js index 39cf7c9da..4c576b8b8 100644 --- a/dist/grapes.js +++ b/dist/grapes.js @@ -21490,6 +21490,8 @@ __webpack_require__.r(__webpack_exports__); * Be aware that these scripts will not be printed in the export code * @example * scripts: [ 'https://...1.js', 'https://...2.js' ] + * * // or passing objects as attributes + * scripts: [ { src: '/file.js', someattr: 'value' }, ... ] */ scripts: [], @@ -21498,6 +21500,8 @@ __webpack_require__.r(__webpack_exports__); * Be aware that these styles will not be printed in the export code * @example * styles: [ 'https://...1.css', 'https://...2.css' ] + * // or passing objects as attributes + * scripts: [ { href: '/style.css', someattr: 'value' }, ... ] */ styles: [], @@ -21534,13 +21538,13 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/typeof */ "./node_modules/@babel/runtime/helpers/typeof.js"); -/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); -/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js"); -/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var utils_mixins__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! utils/mixins */ "./src/utils/mixins.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js"); +/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var utils_mixins__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! utils/mixins */ "./src/utils/mixins.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var utils_Droppable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! utils/Droppable */ "./src/utils/Droppable.js"); /* harmony import */ var _config_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./config/config */ "./src/canvas/config/config.js"); /* harmony import */ var _model_Canvas__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./model/Canvas */ "./src/canvas/model/Canvas.js"); @@ -21548,10 +21552,9 @@ __webpack_require__.r(__webpack_exports__); - function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_2___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/canvas/config/config.js) @@ -21589,6 +21592,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va + var _window = window, requestAnimationFrame = _window.requestAnimationFrame; /* harmony default export */ __webpack_exports__["default"] = (function () { @@ -21619,7 +21623,9 @@ var _window = window, */ init: function init() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - c = _objectSpread({}, _config_config__WEBPACK_IMPORTED_MODULE_5__["default"], {}, config); + c = _objectSpread({}, _config_config__WEBPACK_IMPORTED_MODULE_5__["default"], {}, config, { + module: this + }); this.em = c.em; var ppfx = c.pStylePrefix; if (ppfx) c.stylePrefix = ppfx + c.stylePrefix; @@ -21630,10 +21636,9 @@ var _window = window, }); var cm = c.em.get('DomComponents'); if (cm) this.setWrapper(cm); + this.model = canvas; this.startAutoscroll = this.startAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this); - this.autoscroll = this.autoscroll.bind(this); - this.updateClientY = this.updateClientY.bind(this); return this; }, @@ -21670,7 +21675,12 @@ var _window = window, * @return {HTMLIFrameElement} */ getFrameEl: function getFrameEl() { - return CanvasView.frame.el; + var _CanvasView = CanvasView, + frame = _CanvasView.frame; + return frame && frame.el; + }, + getFramesEl: function getFramesEl() { + return CanvasView.framesArea; }, /** @@ -21686,7 +21696,8 @@ var _window = window, * @return {HTMLDocument} */ getDocument: function getDocument() { - return this.getFrameEl().contentDocument; + var frame = this.getFrameEl(); + return frame && frame.contentDocument; }, /** @@ -21706,14 +21717,34 @@ var _window = window, var body = this.getBody(); return body && body.querySelector('#wrapper'); }, + _getCompFrame: function _getCompFrame(compView) { + return compView && compView._getFrame(); + }, + _getLocalEl: function _getLocalEl(globalEl, compView, method) { + var result = globalEl; + + var frameView = this._getCompFrame(compView); + + result = frameView ? frameView[method]() : result; + return result; + }, + + /** + * Returns element containing all global canvas tools + * @return {HTMLElement} + * @private + */ + getGlobalToolsEl: function getGlobalToolsEl() { + return CanvasView.toolsGlobEl; + }, /** * Returns element containing all canvas tools * @return {HTMLElement} * @private */ - getToolsEl: function getToolsEl() { - return CanvasView.toolsEl; + getToolsEl: function getToolsEl(compView) { + return this._getLocalEl(CanvasView.toolsEl, compView, 'getToolsEl'); }, /** @@ -21721,8 +21752,8 @@ var _window = window, * @return {HTMLElement} * @private */ - getHighlighter: function getHighlighter() { - return CanvasView.hlEl; + getHighlighter: function getHighlighter(compView) { + return this._getLocalEl(CanvasView.hlEl, compView, 'getHighlighter'); }, /** @@ -21730,8 +21761,8 @@ var _window = window, * @return {HTMLElement} * @private */ - getBadgeEl: function getBadgeEl() { - return CanvasView.badgeEl; + getBadgeEl: function getBadgeEl(compView) { + return this._getLocalEl(CanvasView.badgeEl, compView, 'getBadgeEl'); }, /** @@ -21775,8 +21806,8 @@ var _window = window, * @return {HTMLElement} * @private */ - getOffsetViewerEl: function getOffsetViewerEl() { - return CanvasView.offsetEl; + getOffsetViewerEl: function getOffsetViewerEl(compView) { + return this._getLocalEl(CanvasView.offsetEl, compView, 'getOffsetViewerEl'); }, /** @@ -21921,6 +21952,88 @@ var _window = window, return result; }, + canvasRectOffset: function canvasRectOffset(el, pos) { + var _this = this; + + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var getFrameElFromDoc = function getFrameElFromDoc(doc) { + var defaultView = doc.defaultView; + return defaultView && defaultView.frameElement; + }; + + var rectOff = function rectOff(el) { + var top = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + var pos = arguments.length > 2 ? arguments[2] : undefined; + + var zoom = _this.em.getZoomDecimal(); + + var side = top ? 'top' : 'left'; + var doc = el.ownerDocument; + + var _ref = opts.offset ? getFrameElFromDoc(doc) : {}, + _ref$offsetTop = _ref.offsetTop, + offsetTop = _ref$offsetTop === void 0 ? 0 : _ref$offsetTop, + _ref$offsetLeft = _ref.offsetLeft, + offsetLeft = _ref$offsetLeft === void 0 ? 0 : _ref$offsetLeft; + + var _ref2 = doc.body || {}, + _ref2$scrollTop = _ref2.scrollTop, + scrollTop = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop, + _ref2$scrollLeft = _ref2.scrollLeft, + scrollLeft = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft; + + var scroll = top ? scrollTop : scrollLeft; + var offset = top ? offsetTop : offsetLeft; // if (!top) { + // console.log('LEFT', { posLeft: pos[side], scroll, offset }, el); + // } + + return pos[side] - (scroll - offset) * zoom; + }; + + return { + top: rectOff(el, 1, pos), + left: rectOff(el, 0, pos) + }; + }, + getTargetToElementFixed: function getTargetToElementFixed(el, elToMove) { + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var pos = opts.pos || this.getElementPos(el); + var cvOff = opts.canvasOff || this.canvasRectOffset(el, pos); + var toolbarH = elToMove.offsetHeight || 0; + var toolbarW = elToMove.offsetWidth || 0; + var elRight = pos.left + pos.width; + var cv = this.getCanvasView(); + var frCvOff = cv.getPosition(); + var frameOffset = cv.getFrameOffset(el); + var event = opts.event; + var top = -toolbarH; + var left = pos.width - toolbarW; + left = pos.left < -left ? -pos.left : left; + left = elRight > frCvOff.width ? left - (elRight - frCvOff.width) : left; // Scroll with the window if the top edge is reached and the + // element is bigger than the canvas + + var fullHeight = pos.height + toolbarH; + var elIsShort = fullHeight < frameOffset.height; + + if (cvOff.top < toolbarH) { + if (elIsShort) { + top = top + fullHeight; + } else { + top = -cvOff.top < pos.height ? -cvOff.top : pos.height; + } + } + + var result = { + top: top, + left: left, + canvasOffsetTop: cvOff.top, + canvasOffsetLeft: cvOff.left + }; // In this way I can catch data and also change the position strategy + + event && this.em.trigger(event, result); + return result; + }, /** * Instead of simply returning e.clientX and e.clientY this function @@ -21960,10 +22073,10 @@ var _window = window, * @return {Object} * @private */ - getMouseRelativeCanvas: function getMouseRelativeCanvas(ev) { + getMouseRelativeCanvas: function getMouseRelativeCanvas(ev, opts) { var zoom = this.getZoomDecimal(); - var _CanvasView$getPositi2 = CanvasView.getPosition(), + var _CanvasView$getPositi2 = CanvasView.getPosition(opts), top = _CanvasView$getPositi2.top, left = _CanvasView$getPositi2.left; @@ -21988,7 +22101,7 @@ var _window = window, */ isInputFocused: function isInputFocused() { var doc = this.getDocument(); - var toIgnore = ['body'].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default()(this.getConfig().notTextable)); + var toIgnore = ['body'].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(this.getConfig().notTextable)); var focused = doc && doc.activeElement; return focused && !toIgnore.some(function (item) { return focused.matches(item); @@ -22012,82 +22125,30 @@ var _window = window, */ scrollTo: function scrollTo(el) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var elem = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getElement"])(el); - var cv = this.getCanvasView(); - if (!elem) return; - - if (!cv.isElInViewport(elem) || opts.force) { - var opt = _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_0___default()(opts) === 'object' ? opts : { - behavior: 'smooth', - block: 'nearest' - }; - elem.scrollIntoView(opt); - } + var elem = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getElement"])(el); + var view = elem && Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getViewEl"])(elem); + view && view.scrollIntoView(opts); }, /** * Start autoscroll * @private */ - startAutoscroll: function startAutoscroll() { - var _this = this; - - this.dragging = 1; - var toListen = this.getScrollListeners(); - frameRect = CanvasView.getFrameOffset(1); // By detaching those from the stack avoid browsers lags - // Noticeable with "fast" drag of blocks - - setTimeout(function () { - Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["on"])(toListen, 'mousemove dragover', _this.updateClientY); - Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["on"])(toListen, 'mouseup', _this.stopAutoscroll); - requestAnimationFrame(_this.autoscroll); - }, 0); - }, - updateClientY: function updateClientY(ev) { - ev.preventDefault(); - this.lastClientY = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getPointerEvent"])(ev).clientY * this.getZoomDecimal(); - }, - - /** - * @private - */ - autoscroll: function autoscroll() { - if (this.dragging) { - var frameWindow = this.getFrameEl().contentWindow; - var actualTop = frameWindow.document.body.scrollTop; - var nextTop = actualTop; - var clientY = this.lastClientY; - var limitTop = this.getConfig().autoscrollLimit; - var limitBottom = frameRect.height - limitTop; - - if (clientY < limitTop) { - nextTop -= limitTop - clientY; - } - - if (clientY > limitBottom) { - nextTop += clientY - limitBottom; - } - - frameWindow.scrollTo(0, nextTop); - requestAnimationFrame(this.autoscroll); - } + startAutoscroll: function startAutoscroll(frame) { + var fr = frame && frame.view || this.em.getCurrentFrame(); + fr && fr.startAutoscroll(); }, /** * Stop autoscroll * @private */ - stopAutoscroll: function stopAutoscroll() { - this.dragging = 0; - var toListen = this.getScrollListeners(); - Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["off"])(toListen, 'mousemove dragover', this.updateClientY); - Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["off"])(toListen, 'mouseup', this.stopAutoscroll); - }, - getScrollListeners: function getScrollListeners() { - return [this.getFrameEl().contentWindow]; + stopAutoscroll: function stopAutoscroll(frame) { + var fr = frame && frame.view || this.em.getCurrentFrame(); + fr && fr.stopAutoscroll(); }, postRender: function postRender() { - if (Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["hasDnd"])(c.em)) this.droppable = new utils_Droppable__WEBPACK_IMPORTED_MODULE_4__["default"](c.em); + if (Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["hasDnd"])(c.em)) this.droppable = new utils_Droppable__WEBPACK_IMPORTED_MODULE_4__["default"](c.em); }, /** @@ -22114,6 +22175,12 @@ var _window = window, var zoom = this.getZoomDecimal(); return zoom ? 1 / zoom : 1; }, + toggleFramesEvents: function toggleFramesEvents(on) { + var _this$getFramesEl = this.getFramesEl(), + style = _this$getFramesEl.style; + + style.pointerEvents = on ? '' : 'none'; + }, /** * Returns wrapper element @@ -22123,6 +22190,42 @@ var _window = window, */ getFrameWrapperEl: function getFrameWrapperEl() { return CanvasView.frame.getWrapper(); + }, + getFrames: function getFrames() { + return canvas.get('frames').map(function (item) { + return item; + }); + }, + + /** + * Add new frame to the canvas + * @param {Object} props Frame properties + * @returns {Frame} + * @example + * + editor.Canvas.addFrame({ + name: 'Mobile home page', + x: 100, // Position in canvas + y: 100, + width: 500, // Frame dimensions + height: 600, + // device: 'DEVICE-ID', + components: [ + '
Paragraph frame
', + ], + styles: ` + .testh { color: red; } + .testp { color: blue; } + `, + }); + */ + addFrame: function addFrame() { + var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return canvas.get('frames').add(_objectSpread({}, props), _objectSpread({}, opts, { + em: this.em + })); } }; }); @@ -22141,11 +22244,14 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); /* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _Frame__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Frame */ "./src/canvas/model/Frame.js"); +/* harmony import */ var _Frames__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Frames */ "./src/canvas/model/Frames.js"); + /* harmony default export */ __webpack_exports__["default"] = (backbone__WEBPACK_IMPORTED_MODULE_0___default.a.Model.extend({ defaults: { frame: '', + frames: '', wrapper: '', rulers: false, zoom: 100, @@ -22154,19 +22260,38 @@ __webpack_require__.r(__webpack_exports__); }, initialize: function initialize() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var em = config.em; var _config$styles = config.styles, styles = _config$styles === void 0 ? [] : _config$styles, _config$scripts = config.scripts, scripts = _config$scripts === void 0 ? [] : _config$scripts; - var frame = new _Frame__WEBPACK_IMPORTED_MODULE_1__["default"](); + var frame = new _Frame__WEBPACK_IMPORTED_MODULE_1__["default"]({}, config); styles.forEach(function (style) { return frame.addLink(style); }); scripts.forEach(function (script) { return frame.addScript(script); }); + this.em = em; this.set('frame', frame); + this.set('frames', new _Frames__WEBPACK_IMPORTED_MODULE_2__["default"]([frame], config)); this.listenTo(this, 'change:zoom', this.onZoomChange); + this.listenTo(em, 'change:device', this.updateDevice); + }, + updateDevice: function updateDevice() { + var em = this.em; + var device = em.getDeviceModel(); + var model = em.getCurrentFrameModel(); + + if (model && device) { + var _device$attributes = device.attributes, + width = _device$attributes.width, + height = _device$attributes.height; + model.set({ + width: width, + height: height + }); + } }, onZoomChange: function onZoomChange() { var zoom = this.get('zoom'); @@ -22189,18 +22314,50 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); /* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var dom_components_model_Component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! dom_components/model/Component */ "./src/dom_components/model/Component.js"); +/* harmony import */ var css_composer_model_CssRules__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! css_composer/model/CssRules */ "./src/css_composer/model/CssRules.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_4__); + + + /* harmony default export */ __webpack_exports__["default"] = (backbone__WEBPACK_IMPORTED_MODULE_1___default.a.Model.extend({ defaults: { wrapper: '', - width: '', - height: '', + width: null, + height: null, head: '', + x: 0, + y: 0, + root: 0, + components: 0, + styles: 0, attributes: {} }, - initialize: function initialize() { + initialize: function initialize(props) { + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _this$attributes = this.attributes, + root = _this$attributes.root, + styles = _this$attributes.styles, + components = _this$attributes.components; this.set('head', []); + var modOpts = { + em: opts.em, + config: opts.em.get('DomComponents').getConfig(), + frame: this + }; + !root && this.set('root', new dom_components_model_Component__WEBPACK_IMPORTED_MODULE_2__["default"]({ + type: 'wrapper', + components: components || [] + }, modOpts)); + (!styles || Object(underscore__WEBPACK_IMPORTED_MODULE_4__["isString"])(styles)) && this.set('styles', new css_composer_model_CssRules__WEBPACK_IMPORTED_MODULE_3__["default"](styles, modOpts)); + }, + remove: function remove() { + this.view = 0; + var coll = this.collection; + return coll && coll.remove(this); }, getHead: function getHead() { return _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(this.get('head')); @@ -22258,6 +22415,52 @@ __webpack_require__.r(__webpack_exports__); /***/ }), +/***/ "./src/canvas/model/Frames.js": +/*!************************************!*\ + !*** ./src/canvas/model/Frames.js ***! + \************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); +/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _Frame__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Frame */ "./src/canvas/model/Frame.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (backbone__WEBPACK_IMPORTED_MODULE_1___default.a.Collection.extend({ + model: _Frame__WEBPACK_IMPORTED_MODULE_2__["default"], + initialize: function initialize() { + Object(underscore__WEBPACK_IMPORTED_MODULE_0__["bindAll"])(this, 'itemLoaded'); + }, + itemLoaded: function itemLoaded() { + this.loadedItems++; + + if (this.loadedItems >= this.itemsToLoad) { + this.trigger('loaded:all'); + this.listenToLoadItems(0); + } + }, + listenToLoad: function listenToLoad() { + this.loadedItems = 0; + this.itemsToLoad = this.length; + this.listenToLoadItems(1); + }, + listenToLoadItems: function listenToLoadItems(on) { + var _this = this; + + this.forEach(function (item) { + return item[on ? 'on' : 'off']('loaded', _this.itemLoaded); + }); + } +})); + +/***/ }), + /***/ "./src/canvas/view/CanvasView.js": /*!***************************************!*\ !*** ./src/canvas/view/CanvasView.js ***! @@ -22267,19 +22470,27 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); -/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); -/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var utils_mixins__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! utils/mixins */ "./src/utils/mixins.js"); -/* harmony import */ var _FrameView__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./FrameView */ "./src/canvas/view/FrameView.js"); +/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js"); +/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); +/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); +/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var utils_mixins__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! utils/mixins */ "./src/utils/mixins.js"); +/* harmony import */ var _FramesView__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./FramesView */ "./src/canvas/view/FramesView.js"); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var $ = backbone__WEBPACK_IMPORTED_MODULE_0___default.a.$; + + + + +var $ = backbone__WEBPACK_IMPORTED_MODULE_1___default.a.$; var timerZoom; -/* harmony default export */ __webpack_exports__["default"] = (backbone__WEBPACK_IMPORTED_MODULE_0___default.a.View.extend({ +/* harmony default export */ __webpack_exports__["default"] = (backbone__WEBPACK_IMPORTED_MODULE_1___default.a.View.extend({ events: { wheel: 'onWheel' }, @@ -22288,24 +22499,42 @@ var timerZoom; return "\n \n \n "); }, initialize: function initialize(o) { - Object(underscore__WEBPACK_IMPORTED_MODULE_1__["bindAll"])(this, 'renderBody', 'onFrameScroll', 'clearOff', 'onKeyPress'); - Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["on"])(window, 'scroll resize', this.clearOff); + Object(underscore__WEBPACK_IMPORTED_MODULE_2__["bindAll"])(this, 'clearOff', 'onKeyPress'); + Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["on"])(window, 'scroll resize', this.clearOff); var model = this.model; + var frames = model.get('frames'); this.config = o.config || {}; this.em = this.config.em || {}; this.pfx = this.config.stylePrefix || ''; this.ppfx = this.config.pStylePrefix || ''; this.className = this.config.stylePrefix + 'canvas'; - this.listenTo(this.em, 'change:canvasOffset', this.clearOff); + var em = this.em, + config = this.config; + this.frames = new _FramesView__WEBPACK_IMPORTED_MODULE_4__["default"]({ + collection: frames, + config: _objectSpread({}, config, { + canvasView: this, + renderContent: 1 + }) + }); + this.listenTo(em, 'change:canvasOffset', this.clearOff); + this.listenTo(em, 'component:selected', this.checkSelected); this.listenTo(model, 'change:zoom change:x change:y', this.updateFrames); + this.listenTo(frames, 'loaded:all', function () { + return em.trigger('loaded'); + }); this.toggleListeners(1); - this.frame = new _FrameView__WEBPACK_IMPORTED_MODULE_3__["default"]({ - model: this.model.get('frame'), - config: this.config + }, + checkSelected: function checkSelected(component) { + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var scroll = opts.scroll; + var currFrame = this.em.get('currentFrame'); + scroll && component.views.forEach(function (view) { + view._getFrame() !== currFrame && view.scrollIntoView(scroll); }); }, remove: function remove() { - backbone__WEBPACK_IMPORTED_MODULE_0___default.a.View.prototype.remove.apply(this, arguments); + backbone__WEBPACK_IMPORTED_MODULE_1___default.a.View.prototype.remove.apply(this, arguments); this.toggleListeners(); }, preventDefault: function preventDefault(ev) { @@ -22317,14 +22546,14 @@ var timerZoom; toggleListeners: function toggleListeners(enable) { var method = enable ? 'on' : 'off'; var methods = { - on: utils_mixins__WEBPACK_IMPORTED_MODULE_2__["on"], - off: utils_mixins__WEBPACK_IMPORTED_MODULE_2__["off"] + on: utils_mixins__WEBPACK_IMPORTED_MODULE_3__["on"], + off: utils_mixins__WEBPACK_IMPORTED_MODULE_3__["off"] }; methods[method](document, 'keypress', this.onKeyPress); }, onKeyPress: function onKeyPress(ev) { var em = this.em; - var key = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getKeyChar"])(ev); + var key = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getKeyChar"])(ev); if (key === ' ' && em.getZoomDecimal() !== 1) { this.preventDefault(ev); @@ -22353,13 +22582,12 @@ var timerZoom; var mpl = zoom ? 1 / zoom : 1; this.framesArea.style.transform = "scale(".concat(zoom, ") translate(").concat(x * mpl, "px, ").concat(y * mpl, "px)"); this.clearOff(); - this.onFrameScroll(); em.stopDefault(defOpts); em.trigger('canvas:update', ev); timerZoom && clearTimeout(timerZoom); timerZoom = setTimeout(function () { return em.runDefault(defOpts); - }); + }, 300); }, getZoom: function getZoom() { return this.em.getZoomDecimal(); @@ -22371,164 +22599,27 @@ var timerZoom; * @return {Boolean} */ isElInViewport: function isElInViewport(el) { - var rect = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getElRect"])(Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getElement"])(el)); - var frameRect = this.getFrameOffset(); + var elem = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getElement"])(el); + var rect = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getElRect"])(elem); + var frameRect = this.getFrameOffset(elem); var rTop = rect.top; var rLeft = rect.left; return rTop >= 0 && rLeft >= 0 && rTop <= frameRect.height && rLeft <= frameRect.width; }, - /** - * Update tools position - * @private - */ - onFrameScroll: function onFrameScroll() { - var u = 'px'; - var body = this.frame.el.contentDocument.body; - var zoom = this.getZoom(); - this.toolsEl.style.top = '-' + body.scrollTop * zoom + u; - this.toolsEl.style.left = '-' + body.scrollLeft * zoom + u; - this.em.trigger('canvasScroll'); - }, - - /** - * Insert scripts into head, it will call renderBody after all scripts loaded or failed - * @private - */ - renderScripts: function renderScripts() { - var frame = this.frame; - var that = this; - - frame.el.onload = function () { - var scripts = that.config.scripts.slice(0), - // clone - counter = 0; - - function appendScript(scripts) { - if (scripts.length > 0) { - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = scripts.shift(); - script.onerror = script.onload = appendScript.bind(null, scripts); - frame.el.contentDocument.head.appendChild(script); - } else { - that.renderBody(); - } - } - - appendScript(scripts); - }; - }, - - /** - * Render inside frame's body - * @private - */ - renderBody: function renderBody() { - var _this = this; - - var config = this.config, - model = this.model; - var wrap = this.model.get('frame').get('wrapper'); - var em = config.em; - - if (wrap) { - var Canvas = em.get('Canvas'); - var ppfx = this.ppfx; - var body = $(Canvas.getBody()); - var head = $(Canvas.getDocument().head); - var cssc = em.get('CssComposer'); - var conf = em.get('Config'); - var externalStyles = ''; - config.styles.forEach(function (style) { - externalStyles += ""); - }); - var colorWarn = '#ffca6f'; // I need all this styles to make the editor work properly - // Remove `html { height: 100%;}` from the baseCss as it gives jumpings - // effects (on ENTER) with RTE like CKEditor (maybe some bug there?!?) - // With `body {height: auto;}` jumps in CKEditor are removed but in - // Firefox is impossible to drag stuff in empty canvas, so bring back - // `body {height: 100%;}`. - // For the moment I give the priority to Firefox as it might be - // CKEditor's issue - - var frameCss = "\n ".concat(em.config.baseCss || '', "\n\n .").concat(ppfx, "dashed *[data-highlightable] {\n outline: 1px dashed rgba(170,170,170,0.7);\n outline-offset: -2px;\n }\n\n .").concat(ppfx, "comp-selected {\n outline: 3px solid #3b97e3 !important;\n outline-offset: -3px;\n }\n\n .").concat(ppfx, "comp-selected-parent {\n outline: 2px solid ").concat(colorWarn, " !important\n }\n\n .").concat(ppfx, "no-select {\n user-select: none;\n -webkit-user-select:none;\n -moz-user-select: none;\n }\n\n .").concat(ppfx, "freezed {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .").concat(ppfx, "no-pointer {\n pointer-events: none;\n }\n\n .").concat(ppfx, "plh-image {\n background: #f5f5f5;\n border: none;\n height: 100px;\n width: 100px;\n display: block;\n outline: 3px solid #ffca6f;\n cursor: pointer;\n outline-offset: -2px\n }\n\n .").concat(ppfx, "grabbing {\n cursor: grabbing;\n cursor: -webkit-grabbing;\n }\n\n .").concat(ppfx, "is__grabbing {\n overflow-x: hidden;\n }\n\n .").concat(ppfx, "is__grabbing,\n .").concat(ppfx, "is__grabbing * {\n cursor: grabbing !important;\n }\n\n ").concat(conf.canvasCss || '', "\n ").concat(conf.protectedCss || '', "\n "); - - if (externalStyles) { - head.append(externalStyles); - } - - body.append(''); - body.append(wrap.render()).append(cssc.render()); - body.append(this.getJsContainer()); - em.trigger('loaded'); - this.frame.el.contentWindow.onscroll = this.onFrameScroll; - this.frame.updateOffset(); // Avoid the default link behaviour in the canvas - - body.on('click', function (ev) { - return ev && ev.target.tagName == 'A' && ev.preventDefault(); - }); // Avoid the default form behaviour - - body.on('submit', function (ev) { - return ev && ev.preventDefault(); - }); // When the iframe is focused the event dispatcher is not the same so - // I need to delegate all events to the parent document - - var doc = document; - var fdoc = this.frame.el.contentDocument; // Unfortunately just creating `KeyboardEvent(e.type, e)` is not enough, - // the keyCode/which will be always `0`. Even if it's an old/deprecated - // property keymaster (and many others) still use it... using `defineProperty` - // hack seems the only way - - var createCustomEvent = function createCustomEvent(e, cls) { - var oEvent; - - try { - oEvent = new window[cls](e.type, e); - } catch (e) { - oEvent = document.createEvent(cls); - oEvent.initEvent(e.type, true, true); - } - - oEvent.keyCodeVal = e.keyCode; - oEvent._parentEvent = e; - ['keyCode', 'which'].forEach(function (prop) { - Object.defineProperty(oEvent, prop, { - get: function get() { - return this.keyCodeVal; - } - }); - }); - return oEvent; - }; - - [{ - event: 'keydown keyup keypress', - class: 'KeyboardEvent' - }, { - event: 'wheel', - class: 'WheelEvent' - }].forEach(function (obj) { - return obj.event.split(' ').forEach(function (event) { - fdoc.addEventListener(event, function (e) { - return _this.el.dispatchEvent(createCustomEvent(e, obj.class)); - }); - }); - }); - } - }, - /** * Get the offset of the element * @param {HTMLElement} el * @return {Object} */ offset: function offset(el) { - var rect = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["getElRect"])(el); + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var rect = Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["getElRect"])(el); var docBody = el.ownerDocument.body; + var noScroll = opts.noScroll; return { - top: rect.top + docBody.scrollTop, - left: rect.left + docBody.scrollLeft, + top: rect.top + (noScroll ? 0 : docBody.scrollTop), + left: rect.left + (noScroll ? 0 : docBody.scrollLeft), width: rect.width, height: rect.height }; @@ -22548,9 +22639,12 @@ var timerZoom; * @return {Object} * @private */ - getFrameOffset: function getFrameOffset() { - var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - if (!this.frmOff || force) this.frmOff = this.offset(this.frame.el); + getFrameOffset: function getFrameOffset(el) { + if (!this.frmOff || el) { + var frEl = el ? el.ownerDocument.defaultView.frameElement : this.frame.el; + this.frmOff = this.offset(frEl); + } + return this.frmOff; }, @@ -22565,7 +22659,7 @@ var timerZoom; }, /** - * Returns element's data info + * Returns element's rect info * @param {HTMLElement} el * @return {Object} * @private @@ -22573,9 +22667,9 @@ var timerZoom; getElementPos: function getElementPos(el, opts) { var zoom = this.getZoom(); var opt = opts || {}; - var frmOff = this.getFrameOffset(); + var frmOff = this.getFrameOffset(el); var cvsOff = this.getCanvasOffset(); - var eo = this.offset(el); + var eo = this.offset(el, opts); var frmTop = opt.avoidFrameOffset ? 0 : frmOff.top; var frmLeft = opt.avoidFrameOffset ? 0 : frmOff.left; var top = eo.top * zoom + frmTop - cvsOff.top; @@ -22599,13 +22693,13 @@ var timerZoom; * @private */ getElementOffsets: function getElementOffsets(el) { - var _this2 = this; + var _this = this; - if (!el || Object(utils_mixins__WEBPACK_IMPORTED_MODULE_2__["isTextNode"])(el)) return {}; + if (!el || Object(utils_mixins__WEBPACK_IMPORTED_MODULE_3__["isTextNode"])(el)) return {}; var result = {}; var styles = window.getComputedStyle(el); ['marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'].forEach(function (offset) { - result[offset] = parseFloat(styles[offset]) * _this2.getZoom(); + result[offset] = parseFloat(styles[offset]) * _this.getZoom(); }); return result; }, @@ -22616,15 +22710,17 @@ var timerZoom; * @private */ getPosition: function getPosition() { + var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var doc = this.frame.el.contentDocument; if (!doc) return; var bEl = doc.body; var zoom = this.getZoom(); var fo = this.getFrameOffset(); var co = this.getCanvasOffset(); + var noScroll = opts.noScroll; return { - top: fo.top + bEl.scrollTop * zoom - co.top, - left: fo.left + bEl.scrollLeft * zoom - co.left, + top: fo.top + (noScroll ? 0 : bEl.scrollTop) * zoom - co.top, + left: fo.left + (noScroll ? 0 : bEl.scrollLeft) * zoom - co.left, width: co.width, height: co.height }; @@ -22672,25 +22768,27 @@ var timerZoom; var el = this.el, $el = this.$el, ppfx = this.ppfx, - model = this.model; - this.wrapper = model.get('wrapper'); + model = this.model, + em = this.em, + frames = this.frames; + var cssc = em.get('CssComposer'); + var wrapper = model.get('wrapper'); $el.html(this.template()); var $frames = $el.find('[data-frames]'); this.framesArea = $frames.get(0); + this.wrapper = wrapper; - if (this.wrapper && typeof this.wrapper.render == 'function') { - model.get('frame').set('wrapper', this.wrapper); - $frames.append(this.frame.render().el); - var frame = this.frame; - - if (this.config.scripts.length === 0) { - frame.el.onload = this.renderBody; - } else { - this.renderScripts(); // will call renderBody later - } + if (wrapper && typeof wrapper.render == 'function') { + model.get('frame').set({ + wrapper: wrapper, + root: wrapper.getWrapper(), + styles: cssc.getAll() + }); } - $el.find('[data-tools]').append("\n