diff --git a/ajax/getBrickInfo.php b/ajax/getBrickInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..bb344c4e10dfe168eeac65683231b39f08329d59 --- /dev/null +++ b/ajax/getBrickInfo.php @@ -0,0 +1,19 @@ +<?php + +/** + * Gets information about a brick + */ + +QUI::$Ajax->registerFunction( + 'package_quiqqer_ckeditor4_ajax_getBrickInfo', + function ($brickId) { + try { + $Brick = QUI\Bricks\Manager::init()->getBrickById($brickId); + } catch (QUI\Exception $Exception) { + return ''; + } + + return '#'.$Brick->getAttribute('id').' - '.$Brick->getAttribute('title'); + }, + ['brickId'] +); diff --git a/bin/Editor.js b/bin/Editor.js index c5fb9d3f1d3d4ed799b69914a0da0fa7267e9c55..f4d6990d7d4a517f4de21a01e74c92c4c58e000c 100644 --- a/bin/Editor.js +++ b/bin/Editor.js @@ -247,23 +247,23 @@ define('package/quiqqer/ckeditor4/bin/Editor', [ } window.CKEDITOR.replace(instance, { - skinName : 'moono-lisa', - customConfig : '', - language : Locale.getCurrent(), - baseHref : URL_DIR, - basePath : URL_DIR, - height : height, - width : width, - toolbar : toolbar, - allowedContent : true, - extraAllowedContent : 'iframe(*)[*]{*}; img(*)[*]{*}; script(*)[*]{*}; ins(*)[*]{*}', - protectedSource : [/<ins[\s|\S]+?<\/ins>/g], - stylesSet : styles, - contentsCss : data.cssFiles || [], - bodyClass : data.bodyClass, + skinName : 'moono-lisa', + customConfig : '', + language : Locale.getCurrent(), + baseHref : URL_DIR, + basePath : URL_DIR, + height : height, + width : width, + toolbar : toolbar, + allowedContent : true, + extraAllowedContent: 'iframe(*)[*]{*}; img(*)[*]{*}; script(*)[*]{*}; ins(*)[*]{*}', + protectedSource : [/<ins[\s|\S]+?<\/ins>/g], + stylesSet : styles, + contentsCss : data.cssFiles || [], + bodyClass : data.bodyClass, // templates_files : [URL_OPT_DIR +'base/bin/pcsgEditorPlugins/templates.php'], - baseFloatZIndex : zIndex, - extraPlugins : extraPlugins, + baseFloatZIndex: zIndex, + extraPlugins : extraPlugins, //removePlugins : 'scayt', disableNativeSpellChecker: config.disableNativeSpellChecker, autoGrow_onStartup : false, @@ -484,7 +484,7 @@ define('package/quiqqer/ckeditor4/bin/Editor', [ var extra = [], buttonList = []; - if (typeOf(toolbar) == 'array') { + if (typeOf(toolbar) === 'array') { buttonList = toolbar.flatten(); } diff --git a/plugins/quiqqer/quiqqerBricks/images/icon.jpg b/plugins/quiqqer/quiqqerBricks/images/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..514edafb04edd14b7926738c66ebef4a2a5d6bc0 Binary files /dev/null and b/plugins/quiqqer/quiqqerBricks/images/icon.jpg differ diff --git a/plugins/quiqqer/quiqqerBricks/lang/de.js b/plugins/quiqqer/quiqqerBricks/lang/de.js new file mode 100644 index 0000000000000000000000000000000000000000..8f879f944a86c790e1240d1a8c69cc8eb2544332 --- /dev/null +++ b/plugins/quiqqer/quiqqerBricks/lang/de.js @@ -0,0 +1,3 @@ +CKEDITOR.plugins.setLang('quiqqerBricks', 'de', { + button: 'QUIQQER Bausteine' +}); diff --git a/plugins/quiqqer/quiqqerBricks/lang/en.js b/plugins/quiqqer/quiqqerBricks/lang/en.js new file mode 100644 index 0000000000000000000000000000000000000000..10dcdb959662a340b81a52d5a198c57468c43721 --- /dev/null +++ b/plugins/quiqqer/quiqqerBricks/lang/en.js @@ -0,0 +1,3 @@ +CKEDITOR.plugins.setLang('quiqqerBricks', 'en', { + button: 'QUIQQER Bricks' +}); diff --git a/plugins/quiqqer/quiqqerBricks/plugin.js b/plugins/quiqqer/quiqqerBricks/plugin.js new file mode 100644 index 0000000000000000000000000000000000000000..527ba73a53a3726bbadcb5f9581f50955c1413e1 --- /dev/null +++ b/plugins/quiqqer/quiqqerBricks/plugin.js @@ -0,0 +1,363 @@ +(function () { + "use strict"; + + // finds out which project are active + var getProjectData = function (Node, editor) { + var Panel, Site; + var project = ''; + var lang = ''; + + if (Node.closest('.qui-panel')) { + Panel = window.QUI.Controls.getById( + Node.closest('.qui-panel').get('data-quiid') + ); + + if (Panel && Panel.getType() === 'controls/projects/project/site/Panel') { + Site = Panel.getSite(); + + project = Site.getProject().getName(); + lang = Site.getProject().getLang(); + } + } else { + Node = editor.ui.contentsElement.$; + + if (Node.closest('.qui-panel')) { + Panel = window.QUI.Controls.getById( + Node.closest('.qui-panel').get('data-quiid') + ); + + if (Panel && Panel.getType() === 'controls/projects/project/site/Panel') { + Site = Panel.getSite(); + + project = Site.getProject().getName(); + lang = Site.getProject().getLang(); + } + } + } + + return { + project: project, + lang : lang + }; + }; + + var editNode = function (Node, editor) { + if (!Node.classList.contains('quiqqer_bricks_placeholder')) { + return; + } + + var brickId = Node.getAttribute('data-brickid'); + var projectData = getProjectData(Node, editor); + + require(['qui/controls/windows/Confirm'], function (QUIConfirm) { + new QUIConfirm({ + icon : 'fa fa-cubes', + title : 'Editor Baustein ändern', + maxHeight: 300, + maxWidth : 500, + events : { + onOpen: function (Win) { + Win.getContent().set( + 'html', + + '<label style="display: flex; width: 300px; margin: 2rem auto 0;">' + + ' <span style="padding: 0 10px 0 0; line-height: 30px;">Brick ID:</span>' + + ' <input style="flex-grow: 1" type="text" name="brickId" />' + + ' <button class="qui-button">' + + ' <span class="fa fa-cubes"></span>' + + ' </button>' + + '</label>' + ); + + Win.getContent().getElement('input').set('value', brickId); + + Win.getContent().getElement('button').addEvent('click', function () { + require([ + 'package/quiqqer/bricks/bin/Controls/backend/BrickSelectWindow' + ], function (BrickSelectWindow) { + new BrickSelectWindow({ + project : projectData.project, + lang : projectData.lang, + multiple: false, + events : { + onSubmit: function (Instance, ids) { + if (ids.length) { + Win.getContent() + .getElement('input') + .set('value', parseInt(ids[0].id)); + } + } + } + }).open(); + }); + }); + }, + + onSubmit: function (Win) { + var brickId = Win.getContent().getElement('input').value; + + if (brickId !== '') { + Node.setAttribute('data-brickid', brickId); + refreshPlaceholderDisplay(Node, editor); + } + } + } + }).open(); + }); + }; + + // set custom div events + var setPlaceHolderEvents = function (element, editor) { + if (element.getAttribute('data-placeholder-event')) { + return; + } + + // edit + element.addEventListener('click', function (e) { + var Target = e.target; + + // delete brick + if (Target.name === 'delete') { + e.preventDefault(); + + var Brick = e.target.closest('.quiqqer_bricks_placeholder'); + Brick.parentNode.removeChild(Brick) + } + }); + + element.addEventListener('focus', function () { + console.log('focus'); + }); + + element.addEventListener('dblclick', function (e) { + editNode(e.target, editor); + }); + + element.setAttribute('data-placeholder-event', 1); + element.setAttribute('tabindex', -1); + + refreshPlaceholderDisplay(element, editor); + }; + + // refresh placeholder display data + var refreshPlaceholderDisplay = function (element, editor) { + var doc = editor.document.$; + var Info = element.querySelector('.quiqqer_bricks_placeholder_info'); + var Settings = element.querySelector('.quiqqer_bricks_placeholder_settings'); + + if (!Info) { + Info = doc.createElement('div'); + Info.classList.add('quiqqer_bricks_placeholder_info'); + + element.appendChild(Info); + } + + if (!Settings) { + Settings = doc.createElement('div'); + Settings.innerHTML = '<button name="delete">x</button>'; + Settings.classList.add('quiqqer_bricks_placeholder_settings'); + + element.appendChild(Settings); + } + + require(['Ajax'], function (QUIAjax) { + QUIAjax.get('package_quiqqer_ckeditor4_ajax_getBrickInfo', function (result) { + Info.innerHTML = result; + }, { + 'package': 'quiqqer/ckeditor4', + brickId : element.getAttribute('data-brickid') + }); + }); + }; + + var setCustomEvents = function (evt) { + var editor = evt.editor; + var doc = editor.document.$; + var elements = doc.querySelectorAll('.quiqqer_bricks_placeholder'); + + for (var i = 0, len = elements.length; i < len; i++) { + setPlaceHolderEvents(elements[i], editor); + } + }; + + // add ckeditor + CKEDITOR.plugins.add('quiqqerBricks', { + icons: "icon", + lang : ['en', 'de'], + + onLoad: function () { + // Register styles for placeholder widget frame. + CKEDITOR.addCss( + '.quiqqer_bricks_placeholder {' + + ' cursor: pointer;' + + ' display: inline-block;' + + ' background-color:#dedede;' + + ' height: 200px;' + + ' margin-bottom: 10px;' + + ' position: relative;' + + ' width: 100%;' + + '}' + + '.quiqqer_bricks_placeholder:hover {' + + ' outline: 2px solid #2F8FC6' + + '}' + + '.quiqqer_bricks_placeholder_info {' + + ' left: 10px;' + + ' position: absolute;' + + ' pointer-events: none;' + + ' top: 10px;' + + '}' + + '' + + '.quiqqer_bricks_placeholder_settings {' + + ' display: none;' + + //' pointer-events: none;' + + ' position: absolute;' + + ' top: 10px;' + + ' right: 10px;' + + '}' + + '' + + '.quiqqer_bricks_placeholder:hover .quiqqer_bricks_placeholder_settings {' + + ' display: inline;' + + '}' + ); + }, + + init: function (editor) { + var self = this; + + this.$Editor = editor; + + editor.ui.addButton('QuiqqerBricks', { + label : editor.lang.quiqqerBricks.button, + toolbar: 'insert', + command: 'insert-quiqqer-brick', + icon : this.path + 'images/icon.jpg' + }); + + // save + editor.on('getData', function (evt) { + var Ghost = new Element('div', { + html: evt.data.dataValue + }); + + var placeholders = Ghost.getElements('.quiqqer_bricks_placeholder'); + var brickId, textNode, PH; + + for (var i = 0, len = placeholders.length; i < len; i++) { + PH = placeholders[i]; + brickId = PH.get('data-brickid'); + + if (!brickId) { + continue; + } + + textNode = document.createTextNode("{{brick id=" + brickId + "}}"); + + PH.parentNode.insertBefore(textNode, PH); + PH.parentNode.removeChild(PH); + } + + evt.data.dataValue = Ghost.get('html'); + }); + + // load + editor.on('setData', function (evt) { + var result; + var data = evt.data.dataValue; + + if (data.indexOf('{{brick ') === -1) { + return; + } + + result = data.replace( + /{{brick ([^}}]*)}}/g, + function (match) { + match = match.replace('{{brick ', '') + match = match.replace('}}', ''); + match = match.trim(); + match = match.split(' '); + + var parts; + var attributes = []; + + for (var m = 0, len = match.length; m < len; m++) { + parts = match[m].trim().split('='); + + attributes[parts[0]] = parts[1]; + } + + if ("id" in attributes) { + return '<cke:object class="quiqqer_bricks_placeholder" ' + + 'data-brickid="' + attributes.id + '"' + + '></cke:object>'; + } + + return ""; + } + ); + + evt.data.dataValue = result; + + setTimeout(function () { + setCustomEvents(evt); + }, 500); + }); + + editor.on('afterInsertHtml', setCustomEvents); + + + // editor inser command + editor.addCommand('insert-quiqqer-brick', { + exec: function (editor) { + require([ + 'package/quiqqer/bricks/bin/Controls/backend/BrickSelectWindow' + ], function (BrickSelectWindow) { + // get project, if editor is in panel + var Node = editor.ui.contentsElement.$; + var projectData = getProjectData(Node, editor); + + new BrickSelectWindow({ + project : projectData.project, + lang : projectData.lang, + area : 'content', + multiple: false, + events : { + onSubmit: function (Instance, bricks) { + self.insertBrick( + editor, + bricks[0].id, + bricks[0].project, + bricks[0].lang + ); + } + } + }).open(); + }); + } + }); + }, + + insertBrick: function (editor, brickId) { + editor.insertHtml( + '<div class="quiqqer_bricks_placeholder" ' + + ' data-brickid="' + brickId + '"' + + '> </div>' + ); + + var i, len, o; + var doc = editor.document.$; + var nodes = doc.body.querySelectorAll('div.quiqqer_bricks_placeholder'); + + for (i = 0, len = nodes.length; i < len; i++) { + o = doc.createElement('cke:object'); + o.setAttribute('data-brickid', nodes[i].getAttribute('data-brickid')); + o.classList.add('quiqqer_bricks_placeholder'); + + nodes[i].parentNode.replaceChild(o, nodes[i]); + } + + setCustomEvents({ + editor: editor + }); + } + }); +})();