diff --git a/dist/grapes.js b/dist/grapes.js index 244dbc3a7..5383de3de 100644 --- a/dist/grapes.js +++ b/dist/grapes.js @@ -13108,7 +13108,7 @@ LineWidget.prototype.changed = function () { this.height = null; var diff = widgetHeight(this) - oldH; if (!diff) { return } - updateLineHeight(line, line.height + diff); + if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); } if (cm) { runInOp(cm, function () { cm.curOp.forceUpdate = true; @@ -14035,7 +14035,7 @@ keyMap.pcDefault = { "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" + "fallthrough": "basic" }; // Very basic readline/emacs-style bindings, which are standard on Mac. keyMap.emacsy = { @@ -14053,7 +14053,7 @@ keyMap.macDefault = { "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - fallthrough: ["basic", "emacsy"] + "fallthrough": ["basic", "emacsy"] }; keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; @@ -15186,6 +15186,7 @@ function CodeMirror$1(place, options) { var doc = options.value; if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); } + else if (options.mode) { doc.modeOption = options.mode; } this.doc = doc; var input = new CodeMirror$1.inputStyles[options.inputStyle](this); @@ -17089,7 +17090,7 @@ CodeMirror$1.fromTextArea = fromTextArea; addLegacyProps(CodeMirror$1); -CodeMirror$1.version = "5.39.0"; +CodeMirror$1.version = "5.39.2"; return CodeMirror$1; @@ -19719,10 +19720,10 @@ if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) /***/ }), -/***/ "./node_modules/process/browser.js": -/*!*****************************************!*\ - !*** ./node_modules/process/browser.js ***! - \*****************************************/ +/***/ "./node_modules/node-libs-browser/node_modules/process/browser.js": +/*!************************************************************************!*\ + !*** ./node_modules/node-libs-browser/node_modules/process/browser.js ***! + \************************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { @@ -20373,7 +20374,7 @@ exports.default = Promise; attachTo.clearImmediate = clearImmediate; }(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self)); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js"))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../node-libs-browser/node_modules/process/browser.js */ "./node_modules/node-libs-browser/node_modules/process/browser.js"))) /***/ }), @@ -24391,33 +24392,27 @@ module.exports = _backbone2.default.View.extend({ module.exports = { stylePrefix: 'cv-', - // Coming soon - rulers: false, - /* - * Append external scripts in head of the iframe before renderBody content - * In this case, you have to add them manually later in the final HTML page + * Append external scripts to the `
` of the iframe. + * Be aware that these scripts will not be printed in the export code * @example - * scripts: [ - * 'https://...', - * ] + * scripts: [ 'https://...1.js', 'https://...2.js' ] */ scripts: [], /* - * Append external styles. This styles won't be added to the final HTML/CSS + * Append external styles to the `` of the iframe + * Be aware that these styles will not be printed in the export code * @example - * styles: [ - * 'https://...', - * ] + * styles: [ 'https://...1.css', 'https://...2.css' ] */ styles: [], /** * Add custom badge naming strategy * @example - * customBadgeLabel: function(ComponentModel) { - * return ComponentModel.getName(); + * customBadgeLabel: function(component) { + * return component.getName(); * } */ customBadgeLabel: '' @@ -24443,6 +24438,36 @@ var _Droppable2 = _interopRequireDefault(_Droppable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/** + * 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) + * ```js + * const editor = grapesjs.init({ + * canvas: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance + * + * ```js + * const canvas = editor.Canvas; + * ``` + * + * * [getConfig](#getconfig) + * * [getElement](#getelement) + * * [getFrameEl](#getframeel) + * * [getWindow](#getwindow) + * * [getDocument](#getdocument) + * * [getBody](#getbody) + * * [getWrapperEl](#getwrapperel) + * * [setCustomBadgeLabel](#setcustombadgelabel) + * * [hasFocus](#hasfocus) + * * [scrollTo](#scrollto) + * + * @module Canvas + */ + module.exports = function () { var c = {}, defaults = __webpack_require__(/*! ./config/config */ "./src/canvas/config/config.js"), @@ -24471,6 +24496,7 @@ module.exports = function () { /** * Initialize module. Automatically called with a new instance of the editor * @param {Object} config Configurations + * @private */ init: function init(config) { c = config || {}; @@ -24498,7 +24524,7 @@ module.exports = function () { /** - * Return config object + * Get the configuration object * @return {Object} */ getConfig: function getConfig() { @@ -24509,7 +24535,7 @@ module.exports = function () { /** * Add wrapper * @param {Object} wrp Wrapper - * + * @private * */ setWrapper: function setWrapper(wrp) { canvas.set('wrapper', wrp); @@ -24517,7 +24543,7 @@ module.exports = function () { /** - * Returns canvas element + * Get the canvas element * @return {HTMLElement} */ getElement: function getElement() { @@ -24526,8 +24552,8 @@ module.exports = function () { /** - * Returns frame element of the canvas - * @return {HTMLElement} + * Get the iframe element of the canvas + * @return {HTMLIFrameElement} */ getFrameEl: function getFrameEl() { return CanvasView.frame.el; @@ -24535,34 +24561,34 @@ module.exports = function () { /** - * Returns the frame document - * @return {HTMLElement} + * Get the window instance of the iframe element + * @return {Window} */ - getDocument: function getDocument() { - return this.getFrameEl().contentDocument; + getWindow: function getWindow() { + return this.getFrameEl().contentWindow; }, /** - * Returns the frame's window - * @return {HTMLElement} + * Get the document of the iframe element + * @return {HTMLDocument} */ - getWindow: function getWindow() { - return this.getFrameEl().contentWindow; + getDocument: function getDocument() { + return this.getFrameEl().contentDocument; }, /** - * Returns body element of the frame - * @return {HTMLElement} + * Get the body of the iframe element + * @return {HTMLBodyElement} */ getBody: function getBody() { - return CanvasView.frame.el.contentDocument.body; + return this.getDocument().body; }, /** - * Returns body wrapper element of the frame + * Get the wrapper element containing all the components * @return {HTMLElement} */ getWrapperEl: function getWrapperEl() { @@ -24573,6 +24599,7 @@ module.exports = function () { /** * Returns element containing all canvas tools * @return {HTMLElement} + * @private */ getToolsEl: function getToolsEl() { return CanvasView.toolsEl; @@ -24582,6 +24609,7 @@ module.exports = function () { /** * Returns highlighter element * @return {HTMLElement} + * @private */ getHighlighter: function getHighlighter() { return CanvasView.hlEl; @@ -24591,6 +24619,7 @@ module.exports = function () { /** * Returns badge element * @return {HTMLElement} + * @private */ getBadgeEl: function getBadgeEl() { return CanvasView.badgeEl; @@ -24600,6 +24629,7 @@ module.exports = function () { /** * Returns placer element * @return {HTMLElement} + * @private */ getPlacerEl: function getPlacerEl() { return CanvasView.placerEl; @@ -24619,6 +24649,7 @@ module.exports = function () { /** * Returns toolbar element * @return {HTMLElement} + * @private */ getToolbarEl: function getToolbarEl() { return CanvasView.toolbarEl; @@ -24628,6 +24659,7 @@ module.exports = function () { /** * Returns resizer element * @return {HTMLElement} + * @private */ getResizerEl: function getResizerEl() { return CanvasView.resizerEl; @@ -24637,6 +24669,7 @@ module.exports = function () { /** * Returns offset viewer element * @return {HTMLElement} + * @private */ getOffsetViewerEl: function getOffsetViewerEl() { return CanvasView.offsetEl; @@ -24646,6 +24679,7 @@ module.exports = function () { /** * Returns fixed offset viewer element * @return {HTMLElement} + * @private */ getFixedOffsetViewerEl: function getFixedOffsetViewerEl() { return CanvasView.fixedOffsetEl; @@ -24654,6 +24688,7 @@ module.exports = function () { /** * Render canvas + * @private * */ render: function render() { return CanvasView.render().el; @@ -24676,7 +24711,7 @@ module.exports = function () { /** - * Get the offset of the element + * Get the offset of the passed component element * @param {HTMLElement} el * @return {Object} * @private @@ -24690,8 +24725,8 @@ module.exports = function () { * Set custom badge naming strategy * @param {Function} f * @example - * canvas.setCustomBadgeLabel(function(model){ - * return ComponentModel.getName(); + * canvas.setCustomBadgeLabel(function(component){ + * return component.getName(); * }); */ setCustomBadgeLabel: function setCustomBadgeLabel(f) { @@ -24703,6 +24738,7 @@ module.exports = function () { * Get element position relative to the canvas * @param {HTMLElement} el * @return {Object} + * @private */ getElementPos: function getElementPos(el, opts) { return CanvasView.getElementPos(el, opts); @@ -24723,6 +24759,7 @@ module.exports = function () { * @param {Object} options Custom options * @param {Boolean} options.toRight Set to true if you want the toolbar attached to the right * @return {Object} + * @private */ getTargetToElementDim: function getTargetToElementDim(target, element, options) { var opts = options || {}; @@ -24772,6 +24809,7 @@ module.exports = function () { * canvas area, which is in the iframe * @param {Event} e * @return {Object} + * @private */ getMouseRelativePos: function getMouseRelativePos(e, options) { var opts = options || {}; @@ -24801,6 +24839,7 @@ module.exports = function () { * X and Y mouse position relative to the canvas * @param {Event} e * @return {Object} + * @private */ getMouseRelativeCanvas: function getMouseRelativeCanvas(e, options) { var opts = options || {}; @@ -24829,27 +24868,29 @@ module.exports = function () { /** * Detects if some input is focused (input elements, text components, etc.) - * Used internally, for example, to avoid undo/redo in text editing mode * @return {Boolean} + * @private */ isInputFocused: function isInputFocused() { - return this.getFrameEl().contentDocument.activeElement.tagName !== 'BODY'; + var contentDocument = this.getFrameEl().contentDocument; + return contentDocument.activeElement && contentDocument.activeElement.tagName !== 'BODY'; }, /** * Scroll canvas to the element if it's not visible. The scrolling is * executed via `scrollIntoView` API and options of this method are - * passed to it. For instance, you can scroll smoothly with - * `{ behavior: 'smooth' }`. You can also force the scroll + * passed to it. For instance, you can scroll smoothly by using + * `{ behavior: 'smooth' }`. * @param {HTMLElement|Component} el * @param {Object} [opts={}] Options, same as options for `scrollIntoView` + * @param {Boolean} [opts.force=false] Force the scroll, even if the element is already visible * @example * const selected = editor.getSelected(); * // Scroll smoothly (this behavior can be polyfilled) - * cv.scrollTo(selected, { behavior: 'smooth' }); + * canvas.scrollTo(selected, { behavior: 'smooth' }); * // Force the scroll, even if the element is alredy visible - * cv.scrollTo(selected, { force: true }); + * canvas.scrollTo(selected, { force: true }); */ scrollTo: function scrollTo(el) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -24865,6 +24906,7 @@ module.exports = function () { /** * Start autoscroll + * @private */ startAutoscroll: function startAutoscroll() { var _this = this; @@ -24880,6 +24922,11 @@ module.exports = function () { (0, _mixins.on)(toListen, 'mouseup', _this.stopAutoscroll); }, 0); }, + + + /** + * @private + */ autoscroll: function autoscroll(e) { e.preventDefault(); if (this.dragging) { @@ -24906,6 +24953,7 @@ module.exports = function () { /** * Stop autoscroll + * @private */ stopAutoscroll: function stopAutoscroll() { this.dragging = 0; @@ -24925,6 +24973,7 @@ module.exports = function () { * Returns wrapper element * @return {HTMLElement} * ???? + * @private */ getFrameWrapperEl: function getFrameWrapperEl() { return CanvasView.frame.getWrapper(); @@ -26189,6 +26238,12 @@ module.exports = { var _underscore = __webpack_require__(/*! underscore */ "./node_modules/underscore/underscore.js"); +var _CommandAbstract = __webpack_require__(/*! ./view/CommandAbstract */ "./src/commands/view/CommandAbstract.js"); + +var _CommandAbstract2 = _interopRequireDefault(_CommandAbstract); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /** * 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/commands/config/config.js) * ```js @@ -26207,9 +26262,12 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr * * * [add](#add) * * [get](#get) + * * [getAll](#getall) * * [has](#has) * * [run](#run) * * [stop](#stop) + * * [isActive](#isactive) + * * [getActive](#getactive) * * @module Commands */ @@ -26219,23 +26277,21 @@ module.exports = function () { var c = {}, commands = {}, defaultCommands = {}, - defaults = __webpack_require__(/*! ./config/config */ "./src/commands/config/config.js"), - CommandAbstract = __webpack_require__(/*! ./view/CommandAbstract */ "./src/commands/view/CommandAbstract.js"); + defaults = __webpack_require__(/*! ./config/config */ "./src/commands/config/config.js"); + var active = {}; // Need it here as it would be used below var add = function add(id, obj) { - if ((0, _underscore.isFunction)(obj)) { - obj = { run: obj }; - } - + if ((0, _underscore.isFunction)(obj)) obj = { run: obj }; + if (!obj.stop) obj.noStop = 1; delete obj.initialize; obj.id = id; - commands[id] = CommandAbstract.extend(obj); + commands[id] = _CommandAbstract2.default.extend(obj); return this; }; return { - CommandAbstract: CommandAbstract, + CommandAbstract: _CommandAbstract2.default, /** * Name of the module @@ -26445,6 +26501,15 @@ module.exports = function () { }, + /** + * Get an object containing all the commands + * @return {Object} + */ + getAll: function getAll() { + return commands; + }, + + /** * Execute the command * @param {String} id Command ID @@ -26456,12 +26521,7 @@ module.exports = function () { run: function run(id) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var result = void 0; - var command = this.get(id); - var editor = em.get('Editor'); - if (command) result = command.callRun(editor, options); - - return result; + return this.runCommand(this.get(id), options); }, @@ -26476,12 +26536,39 @@ module.exports = function () { stop: function stop(id) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var result = void 0; - var command = this.get(id); - var editor = em.get('Editor'); - if (command) result = command.callStop(editor, options); + return this.stopCommand(this.get(id), options); + }, - return result; + + /** + * Check if the command is active. You activate commands with `run` + * and disable them with `stop`. If the command was created without `stop` + * method it can't be registered as active + * @param {String} id Command id + * @return {Boolean} + * @example + * const cId = 'some-command'; + * commands.run(cId); + * commands.isActive(cId); + * // -> true + * commands.stop(cId); + * commands.isActive(cId); + * // -> false + */ + isActive: function isActive(id) { + return this.getActive().hasOwnProperty(id); + }, + + + /** + * Get all active commands + * @return {Object} + * @example + * console.log(commands.getActive()); + * // -> { someCommand: itsLastReturn, anotherOne: ... }; + */ + getActive: function getActive() { + return active; }, @@ -26499,6 +26586,55 @@ module.exports = function () { }, + /** + * Run command via its object + * @param {Object} command + * @param {Object} options + * @return {*} Result of the command + * @private + */ + runCommand: function runCommand(command) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var result = void 0; + + if (command && command.run) { + var id = command.id; + var _editor = em.get('Editor'); + result = command.callRun(_editor, options); + + if (id && command.stop && !command.noStop) { + active[id] = result; + } + } + + return result; + }, + + + /** + * [runCommand description] + * @param {Object} command + * @param {Object} options + * @return {*} Result of the command + * @private + */ + stopCommand: function stopCommand(command) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var result = void 0; + + if (command && command.run) { + var id = command.id; + var _editor2 = em.get('Editor'); + result = command.callStop(_editor2, options); + if (id) delete active[id]; + } + + return result; + }, + + /** * Create anonymous Command instance * @param {Object} command Command object @@ -26506,7 +26642,7 @@ module.exports = function () { * @private * */ create: function create(command) { - var cmd = CommandAbstract.extend(command); + var cmd = _CommandAbstract2.default.extend(command); return new cmd(c); } }; @@ -26636,6 +26772,10 @@ module.exports = { "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); + var _backbone = __webpack_require__(/*! backbone */ "./node_modules/backbone/backbone.js"); var _backbone2 = _interopRequireDefault(_backbone); @@ -26644,7 +26784,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de var $ = _backbone2.default.$; -module.exports = _backbone2.default.View.extend({ +exports.default = _backbone2.default.View.extend({ /** * Initialize method that can't be removed * @param {Object} o Options @@ -27396,6 +27536,8 @@ var $ = _backbone2.default.$; module.exports = { run: function run(editor, sender) { + var _this = this; + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; sender && sender.set && sender.set('active', 0); @@ -27414,9 +27556,12 @@ module.exports = { this.$editors = $editors; } - modal.setTitle(config.textViewCode); - modal.setContent(this.$editors); - modal.open(); + modal.open({ + title: config.textViewCode, + content: this.$editors + }).getModel().once('change:open', function () { + return editor.stopCommand(_this.id); + }); this.htmlEditor.setContent(editor.getHtml()); this.cssEditor.setContent(editor.getCss()); }, @@ -27899,6 +28044,8 @@ module.exports = _underscore2.default.extend({}, SelectPosition, SelectComponent module.exports = { run: function run(editor, sender) { + var _this = this; + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var modal = editor.Modal; @@ -27932,9 +28079,17 @@ module.exports = { uploadEl && uploadEl.setAttribute('accept', accept); } - modal.setTitle(title); - modal.setContent(amContainer); - modal.open(); + modal.open({ + title: title, + content: amContainer + }).getModel().once('change:open', function () { + return editor.stopCommand(_this.id); + }); + return this; + }, + stop: function stop(editor) { + editor.Modal.close(); + return this; } }; @@ -31337,120 +31492,89 @@ var avoidInline = function avoidInline(em) { return em && em.getConfig('avoidInlineStyle'); }; +/** + * The Component object represents a single node of our template structure, so when you update its properties the changes are + * immediatly reflected on the canvas and in the code to export (indeed, when you ask to export the code we just go through all + * the tree of nodes). + * An example on how to update properties: + * ```js + * component.set({ + * tagName: 'span', + * attributes: { ... }, + * removable: false, + * }); + * component.get('tagName'); + * // -> 'span' + * ``` + * + * @typedef Component + * @property {String} [type=''] Component type, eg. `text`, `image`, `video`, etc. + * @property {String} [tagName='div'] HTML tag of the component, eg. `span`. Default: `div` + * @property {Object} [attributes={}] Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}` + * @property {String} [name=''] Name of the component. Will be used, for example, in Layers and badges + * @property {Boolean} [removable=true] When `true` the component is removable from the canvas, default: `true` + * @property {Boolean|String} [draggable=true] Indicates if it's possible to drag the component inside others. + * You can also specify a query string to indentify elements, + * eg. `'.some-class[title=Hello], [data-gjs-type=column]'` means you can drag the component only inside elements + * containing `some-class` class and `Hello` title, and `column` components. Default: `true` + * @property {Boolean|String} [droppable=true] Indicates if it's possible to drop other components inside. You can use + * a query string as with `draggable`. Default: `true` + * @property {Boolean} [badgable=true] Set to false if you don't want to see the badge (with the name) over the component. Default: `true` + * @property {Boolean|Array