This is an automated email from the ASF dual-hosted git repository. dklco pushed a commit to branch SLING-7900 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git
commit 9dc63c13132996de55c74ec948e656a3700e547a Merge: 7415cce fff2bcb Author: JE Bailey <[email protected]> AuthorDate: Mon Oct 1 13:10:32 2018 -0400 Merge remote-tracking branch 'origin/master' into SLING-7900 Conflicts: ui/src/main/frontend/src/js/cms.js ui/src/main/resources/jcr_root/libs/sling-cms/content/start.json .../usergenerated/impl/ApproveUGCOperation.java | 3 + ui/src/main/frontend/src/js/cms.js | 1043 +++++++++++--------- .../components/cms/suffixswitch/suffixswitch.jsp | 45 + .../components/editor/fields/path/path.jsp | 2 +- .../components/editor/fields/select/field.jsp | 74 +- .../editor/fields/siblingselect/siblingselect.jsp | 2 +- .../libs/sling-cms/content/admin/bulkreplace.json | 145 +-- .../libs/sling-cms/content/admin/loadcontent.json | 198 +++- .../jcr_root/libs/sling-cms/content/start.json | 14 +- .../sling-cms/content/usergenerated/review.json | 2 + 10 files changed, 880 insertions(+), 648 deletions(-) diff --cc ui/src/main/frontend/src/js/cms.js index 72b9474,3d56576..41cb831 --- a/ui/src/main/frontend/src/js/cms.js +++ b/ui/src/main/frontend/src/js/cms.js @@@ -15,497 -15,508 +15,558 @@@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. -- */ ++ */ var Sling = {}; Sling.CMS = { - ext: {}, - decorate: function($ctx){ - for (var key in Sling.CMS.ext) { - if(typeof Sling.CMS.ext[key].decorate == 'function'){ - console.log('Invoking decorate for '+key); - Sling.CMS.ext[key].decorate($ctx); - } - } - }, - init: function(){ - for (var key in Sling.CMS.ext) { - if(typeof Sling.CMS.ext[key].init == 'function'){ - console.log('Invoking init for '+key); - Sling.CMS.ext[key].init(); - } - } - Sling.CMS.decorate($(document)); - }, - ui: { - confirmMessage: function(title, message, complete){ - var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">'+title+'</p></header><section class="modal-card-body">'+message+'</section><footer class="modal-card-foot"><button type="button" class="close-modal button is-primary">OK</button></footer></div>'); - $('body').append($modal); - Sling.CMS.decorate($modal); - $modal.addClass('is-active'); - $modal.find('.delete,.close-modal').click(function(){ - $modal.css('display','none').remove(); - complete(); - }); - return $modal; - }, - fetchModal: function(title, link, path, complete){ - var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">'+title+'</p></header><section class="modal-card-body"></section><footer class="modal-card-foot"><a class="close-modal is-danger button" aria-label="close">Cancel</a></footer></div>'); - $('body').append($modal); - $modal.find('.modal-card-body').load(link,function(){ - var submitButton = $modal.find('button:submit'); - var closeButton = $modal.find('.close-modal'); - submitButton.insertBefore(closeButton); - submitButton.on("click",function(){ - $modal.find('form').submit(); - }) - $modal.addClass('is-active'); - closeButton.click(function(){ - $modal.css('display','none').remove(); - return false; - }); - Sling.CMS.decorate($modal); - complete(); - }); - return $modal; - } - }, - utils: { - form2Obj: function ($form){ - var data = {}; - $.map($form.serializeArray(), function(n, i){ - data[n['name']] = n['value']; - }); - return data; - } - } - }; - - Sling.CMS.ext['ajaxform'] = { - decorate: function($ctx){ - $ctx.find('.Form-Ajax').submit(function(){ - - var $form = $(this); - var jcrcontent = false; - $form.find('input,select,textarea').each(function(idx,inp){ - if(inp.name.indexOf('jcr:content') != -1){ - jcrcontent = true; - } - }); - if($form.data('addDate') && $form.find('input[name="jcr:content/jcr:lastModified"]').length == 0){ - if(jcrcontent){ - $form.append('<input type="hidden" name="jcr:content/jcr:lastModified" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:lastModifiedBy" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:created" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:createdBy" />'); - } else { - $form.append('<input type="hidden" name="jcr:lastModified" />'); - $form.append('<input type="hidden" name="jcr:lastModifiedBy" />'); - $form.append('<input type="hidden" name="jcr:created" />'); - $form.append('<input type="hidden" name="jcr:createdBy" />'); - } - } - var callback = $form.data('callback'); - var data = new FormData(this); - $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); - $.ajax({ - url: $form.attr('action'), - type: 'POST', - data: data, - processData: false, - contentType: false, - dataType: 'json', - success: function(res,msg){ - if (callback && Sling.CMS.ext[callback]){ - Sling.CMS.ext[callback](res, msg); - } else { - Sling.CMS.ext.reload(res, msg); - } - }, - error: function(xhr, msg, err){ - if(window.self !== window.top){ - window.top.Sling.CMS.ui.confirmMessage(msg, err,function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - }); - } else { - Sling.CMS.ui.confirmMessage(msg, err,function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - }); - } - } - }); - return false; - }); - } - }; - - Sling.CMS.ext['draggable'] = { - decorate: function($ctx) { - var draggable = function(){ - var element = this; - var mouseX; - var mouseY; - var mouseDown = false; - var elementX = 0; - var elementY = 0; - - // mouse button down over the element - element.addEventListener('mousedown', function(evt){ - if(document.querySelector('.modal-card-body').contains(evt.target)){ - return; - } - mouseX = evt.clientX; - mouseY = evt.clientY; - mouseDown = true; - }); - - var moveComplete = function(){ - mouseDown = false; - elementX = parseInt(element.style.left) || 0; - elementY = parseInt(element.style.top) || 0; - return false; - } - - element.addEventListener('mouseup', moveComplete); - document.addEventListener('mouseout', moveComplete); - - document.addEventListener('mousemove', function(event) { - if (!mouseDown) { - return; - } - var deltaX = event.clientX - mouseX; - var deltaY = event.clientY - mouseY; - element.style.left = elementX + deltaX + 'px'; - element.style.top = elementY + deltaY + 'px'; - return false; - }); - - }; - if($ctx.is('.is-draggable')){ - $ctx.each(draggable) - } - $ctx.find('.is-draggable').each(draggable); - } - }; - - Sling.CMS.ext['load-versions'] = { - loaded: false, - decorate: function($ctx) { - if(!Sling.CMS.ext['load-versions'].loaded){ - $ctx.find('.load-versions').each(function(){ - var $ctr = $(this); - var $table = $ctr.closest('.table'); - $.getJSON($ctr.data('url'),function(res){ - $table.dataTable().api().destroy(); - var source = $('#'+$ctr.data('template')).html(); - var template = Handlebars.compile(source); - $ctr.append(template(res)); - Sling.CMS.ext['load-versions'].loaded = true; - Sling.CMS.decorate($ctr.closest('.version-container')); - }); - }); - } - } - }; - - //support links which fetch HTML and display a modal - Sling.CMS.ext['fetch-modal'] = { - decorate : function($ctx){ - $ctx.find('a.Fetch-Modal').click(function(){ - var $link = $(this); - $link.attr('disabled', 'disabled'); - Sling.CMS.ui.fetchModal($link.attr('data-title'), encodeURI($link.attr('href')), $link.attr('data-path'), function(){ - $link.removeAttr('disabled'); - }); - return false; - }); - } - }; - - Sling.CMS.ext['getform'] = { - decorate: function($ctx){ - $ctx.find('.Get-Form').submit(function(){ - var $form = $(this); - var params = $form.serialize(); - $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); - - $($form.data('target')).load($form.attr('action') + '?' + params +' ' + $form.data('load'), function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - Sling.CMS.decorate($($form.data('target'))); - }); - return false; - }); - } - }; - - Sling.CMS.ext['includeconfig'] = { - decorate: function($ctx){ - $ctx.find('.sling-cms-include-config').each(function(){ - var $ctr = $(this); - var load = function(){ - var config = $($ctr.data('source')).find('option:selected').data('config'); - - if(config){ - $ctr.load(config + $ctr.parents('form').attr('action'), function(){ - Sling.CMS.decorate($ctr.children()); - }); - } - }; - $($ctr.data('source')).change(load); - load(); - }); - } - }; - - Sling.CMS.ext['handledelete'] = function(res, msg){ - if(window.location.pathname.indexOf(res.path) !== -1){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.location = '/cms'; - }); - } else { - Sling.CMS.ext.reload(res, msg); - } - } - - Sling.CMS.ext['handlemove'] = function(res, msg){ - var changes = res.changes[0]; - if(changes.type === 'moved' && window.location.pathname.indexOf(changes.argument[0]) !== -1){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.location = window.location.href.replace(changes.argument[0], changes.argument[1]); - }); - } else { - Sling.CMS.ext.reload(res, msg); - } - } - - Sling.CMS.ext['namehint'] = { - decorate: function($ctx){ - $ctx.find('.namehint').each(function(){ - var $nh = $(this); - $nh.parents('.Form-Ajax').find('select[name="sling:resourceType"]').change(function(){ - var resourceType = $(this).val().split("\/"); - $nh.val(resourceType[resourceType.length - 1]); - }); - }); - } - }; - - Sling.CMS.ext['pageproperties'] = { - decorate: function($ctx){ - $ctx.find('.Sling-CMS__page-properties').each(function(){ - var $ctr = $(this); - var $wrapper = $ctr.closest('.Form-Ajax__wrapper'); - $($ctr.data('source')).change(function(){ - var config = $(this).val(); - $ctr.load($ctr.data('path')+config, function(){ - var source = $('#content-template').html(); - var template = Handlebars.compile(source); - var updateContent = function(){ - if(!$wrapper.is(':disabled')){ - var data = Sling.CMS.utils.form2Obj($ctr.parents('form')); - $('input[name=":content"]').val(template(data)); - } - } - $ctr.find('input,textarea,select').change(updateContent); - $ctr.parents('form').submit(updateContent); - Sling.CMS.decorate($ctr.children()); - }); - }); - }); - } - }; - - Sling.CMS.ext['pathfield'] = { - suggest: function(field, type, base) { - var xhr; - new autoComplete({ - minChars: 1, - selector: field, - source: function(term, response){ - try { - xhr.abort(); - } catch(e){} - if(term === '/'){ - term = base; - } - xhr = $.getJSON('/bin/cms/paths', { path: term, type: type }, function(data){ - response(data); - }); - } - }); - }, - decorate: function($ctx){ - $ctx.find('input.pathfield').each(function(){ - var type = $(this).data('type'); - var base = $(this).data('base'); - Sling.CMS.ext.pathfield.suggest(this, type, base); - }); - } - }; - - Sling.CMS.ext['reload'] = function(res, msg) { - if(window.self !== window.top){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.top.location.reload(); - }); - } else { - Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - location.reload(); - }); - } - } - - Sling.CMS.ext['repeating'] = { - decorate: function($ctx){ - $ctx.find('.repeating').each(function(){ - var $rep = $(this); - $rep.find('.repeating__add').click(function(){ - var $div = $('<div/>').html($rep.find('.repeating__template').html()); - Sling.CMS.decorate($div); - $rep.find('.repeating__container').append($div); - return false; - }); - }); - $ctx.find('.repeating__remove').click(function(){ - var $rem = $(this); - $rem.parents('.repeating__item').remove(); - return false; - }); - } - }; - - Sling.CMS.ext['richtext'] = { - decorate: function($ctx){ - $ctx.find('.richtext').summernote({ - toolbar: [ - ['style', ['bold', 'italic', 'clear','strikethrough', 'superscript', 'subscript']], - ['insert', ['picture', 'link', 'table', 'hr']], - ['para', ['style','ul', 'ol', 'paragraph']], - ['misc', ['codeview', 'undo','redo','help']] - ], - followingToolbar: false, - dialogsInBody: true, - height: 200, - onCreateLink: function (url) { - return url; - }, - callbacks: { - onDialogShown: function(){ - Sling.CMS.ext.pathfield.suggest($('.note-link-url')[0], 'content', '/content'); - Sling.CMS.ext.pathfield.suggest($('.note-image-url')[0], 'content', '/content'); - } - } - }); - } - }; - - Sling.CMS.ext['searchselect'] = { - decorate: function($ctx) { - $ctx.find('.Search-Select-Button').click(function(evt){ - var $btn = $(evt.target); - var $active = Sling.CMS.ext['searchbutton'].active; - $active.val($btn.data('path')); - $btn.closest('.Modal').remove(); - }); - } - } - - Sling.CMS.ext['searchbutton'] = { - active: null, - decorate: function($ctx) { - $ctx.find('.Search-Button').click(function(evt){ - Sling.CMS.ext['searchbutton'].active = $(evt.target).closest('.Field-Input').find('.Field-Path'); - }); - } - } - - Sling.CMS.ext['table'] = { - decorate: function($ctx) { - $ctx.find('table tbody tr').click(function(el){ - $('.actions-target > *').appendTo('tr.is-selected .cell-actions') - $('tr').removeClass('is-selected'); - $(this).addClass('is-selected'); - $(this).find('.cell-actions > *').appendTo('.actions-target') - }); - - $ctx.find('table').each(function(){ - var sort = $(this).data('sort') !== 'false'; - var paginate = $(this).data('paginate') !== 'false'; - $(this).DataTable({ - sort: sort, - paginate: paginate - }); - }); - } - }; - - Sling.CMS.ext['taxonomy'] = { - decorate: function($ctx){ - $ctx.find('.taxonomy').each(function(){ - var $rep = $(this); - $rep.find('.taxonomy__add').click(function(){ - var $span = $('<span/>').html($rep.find('.taxonomy__template').html()); - var val = $ctx.find('.taxonomy__field input').val(); - var found = false; - $rep.find('.taxonomy__item input').each(function(idx, el){ - if($(el).val() === val){ - found = true; - } - }); - if(found){ - return false; - } - $span.find('input').val(val); - var title = $ctx.find('option[value="'+val+'"]').text(); - - if(title !== ''){ - $span.find('.taxonomy__title').text(title); - Sling.CMS.decorate($span); - $('.taxonomy__container').append($span); - $ctx.find('.taxonomy__field input').val(''); - } - return false; - }); - }); - $ctx.find('.taxonomy__item').click(function(){ - $(this).remove(); - return false; - }); - } - }; - - Sling.CMS.ext['toggle-hidden'] = { - decorate: function($ctx){ - $ctx.find('.toggle-hidden').click(function(){ - $($(this).data('target')).toggleClass('is-hidden'); - }); - } - }; - - Sling.CMS.ext['toggle-value'] = { - decorate: function($ctx) { - $ctx.find('.toggle-value').each(function(){ - var $tog = $(this); - $('input[name="'+$tog.data('toggle-source')+'"], select[name="'+$tog.data('toggle-source')+'"]').change(function(){ - if($(this).val() !== $tog.data('toggle-value')){ - $tog.addClass('is-hidden'); - } else { - $tog.removeClass('is-hidden'); - } - }); - }) - } - }; - - Sling.CMS.ext['file-upload'] = { - decorate: function($ctx) { - $ctx.find('.file').on('change', "input", function(){ - var node = $(this); - node.parent().find('.file-name').text(this.files[0].name); - }); - } - }; - - $(document).ready(function() { - Sling.CMS.init(); - }); - ext: {}, - decorate: function($ctx){ - for (var key in Sling.CMS.ext) { - if(typeof Sling.CMS.ext[key].decorate == 'function'){ - console.log('Invoking decorate for '+key); - Sling.CMS.ext[key].decorate($ctx); ++ ext : {}, ++ decorate : function($ctx) { ++ for ( var key in Sling.CMS.ext) { ++ if (typeof Sling.CMS.ext[key].decorate == 'function') { ++ console.log('Invoking decorate for ' + key); ++ Sling.CMS.ext[key].decorate($ctx); ++ } ++ } ++ }, ++ init : function() { ++ for ( var key in Sling.CMS.ext) { ++ if (typeof Sling.CMS.ext[key].init == 'function') { ++ console.log('Invoking init for ' + key); ++ Sling.CMS.ext[key].init(); ++ } ++ } ++ Sling.CMS.decorate($(document)); ++ }, ++ ui : { ++ confirmMessage : function(title, message, complete) { ++ var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">' ++ + title ++ + '</p></header><section class="modal-card-body">' ++ + message ++ + '</section><footer class="modal-card-foot"><button type="button" class="close-modal button is-primary">OK</button></footer></div>'); ++ $('body').append($modal); ++ Sling.CMS.decorate($modal); ++ $modal.addClass('is-active'); ++ $modal.find('.delete,.close-modal').click(function() { ++ $modal.css('display', 'none').remove(); ++ complete(); ++ }); ++ return $modal; ++ }, ++ fetchModal : function(title, link, path, complete) { ++ var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">' ++ + title ++ + '</p></header><section class="modal-card-body"></section><footer class="modal-card-foot"><a class="close-modal is-danger button" aria-label="close">Cancel</a></footer></div>'); ++ $('body').append($modal); ++ $modal.find('.modal-card-body').load(link, function() { ++ var submitButton = $modal.find('button:submit'); ++ var closeButton = $modal.find('.close-modal'); ++ submitButton.insertBefore(closeButton); ++ submitButton.on("click", function() { ++ $modal.find('form').submit(); ++ }) ++ $modal.addClass('is-active'); ++ closeButton.click(function() { ++ $modal.css('display', 'none').remove(); ++ return false; ++ }); ++ Sling.CMS.decorate($modal); ++ complete(); ++ }); ++ return $modal; ++ } ++ }, ++ utils : { ++ form2Obj : function($form) { ++ var data = {}; ++ $.map($form.serializeArray(), function(n, i) { ++ data[n['name']] = n['value']; ++ }); ++ return data; ++ } ++ } ++}; ++ ++Sling.CMS.ext['ajaxform'] = { ++ decorate : function($ctx) { ++ $ctx ++ .find('.Form-Ajax') ++ .submit( ++ function() { ++ ++ var $form = $(this); ++ var jcrcontent = false; ++ $form.find('input,select,textarea').each(function(idx, inp) { ++ if (inp.name.indexOf('jcr:content') != -1) { ++ jcrcontent = true; + } - } - }, - init: function(){ - for (var key in Sling.CMS.ext) { - if(typeof Sling.CMS.ext[key].init == 'function'){ - console.log('Invoking init for '+key); - Sling.CMS.ext[key].init(); ++ }); ++ if ($form.data('addDate') ++ && $form.find('input[name="jcr:content/jcr:lastModified"]').length == 0) { ++ if (jcrcontent) { ++ $form ++ .append('<input type="hidden" name="jcr:content/jcr:lastModified" />'); ++ $form ++ .append('<input type="hidden" name="jcr:content/jcr:lastModifiedBy" />'); ++ $form ++ .append('<input type="hidden" name="jcr:content/jcr:created" />'); ++ $form ++ .append('<input type="hidden" name="jcr:content/jcr:createdBy" />'); ++ } else { ++ $form ++ .append('<input type="hidden" name="jcr:lastModified" />'); ++ $form ++ .append('<input type="hidden" name="jcr:lastModifiedBy" />'); ++ $form.append('<input type="hidden" name="jcr:created" />'); ++ $form.append('<input type="hidden" name="jcr:createdBy" />'); + } - } - Sling.CMS.decorate($(document)); - }, - ui: { - confirmMessage: function(title, message, complete){ - var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">'+title+'</p><button class="delete" aria-label="close"></button></header><section class="modal-card-body">'+message+'</section><footer class="modal-card-foot"><button type="button" class="close-modal button is-primary">OK</button></footer></div>'); - $('body').append($modal); - Sling.CMS.decorate($modal); - $modal.addClass('is-active'); - $modal.find('.delete,.close-modal').click(function(){ - $modal.css('display','none').remove(); - complete(); - }); - return $modal; - }, - fetchModal: function(title, link, path, complete){ - var $modal = $('<div class="modal"><div class="modal-background"></div><div class="modal-card is-draggable"><header class="modal-card-head"><p class="modal-card-title">'+title+'</p><button class="delete" aria-label="close"></button></header><section class="modal-card-body"></section><footer class="modal-card-foot"></footer></div>'); - $('body').append($modal); - $modal.find('.modal-card-body').load(link + " " +path,function(){ - $modal.addClass('is-active'); - $modal.find('.delete,.close-modal').click(function(){ - $modal.css('display','none').remove(); - return false; ++ } ++ var callback = $form.data('callback'); ++ var data = new FormData(this); ++ $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); ++ $.ajax({ ++ url : $form.attr('action'), ++ type : 'POST', ++ data : data, ++ processData : false, ++ contentType : false, ++ dataType : 'json', ++ success : function(res, msg) { ++ if (callback && Sling.CMS.ext[callback]) { ++ Sling.CMS.ext[callback](res, msg); ++ } else { ++ Sling.CMS.ext.reload(res, msg); ++ } ++ }, ++ error : function(xhr, msg, err) { ++ if (window.self !== window.top) { ++ window.top.Sling.CMS.ui.confirmMessage(msg, err, ++ function() { ++ $form.find('.Form-Ajax__wrapper').removeAttr( ++ 'disabled'); ++ }); ++ } else { ++ Sling.CMS.ui.confirmMessage(msg, err, function() { ++ $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); + }); - Sling.CMS.decorate($modal); - complete(); - }); - return $modal; - } - }, - utils: { - form2Obj: function ($form){ - var data = {}; - $.map($form.serializeArray(), function(n, i){ - data[n['name']] = n['value']; - }); - return data; - } - } - }; - - Sling.CMS.ext['ajaxform'] = { - decorate: function($ctx){ - $ctx.find('.Form-Ajax').submit(function(){ - - var $form = $(this); - var jcrcontent = false; - $form.find('input,select,textarea').each(function(idx,inp){ - if(inp.name.indexOf('jcr:content') != -1){ - jcrcontent = true; - } - }); - if($form.data('addDate') && $form.find('input[name="jcr:content/jcr:lastModified"]').length == 0){ - if(jcrcontent){ - $form.append('<input type="hidden" name="jcr:content/jcr:lastModified" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:lastModifiedBy" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:created" />'); - $form.append('<input type="hidden" name="jcr:content/jcr:createdBy" />'); - } else { - $form.append('<input type="hidden" name="jcr:lastModified" />'); - $form.append('<input type="hidden" name="jcr:lastModifiedBy" />'); - $form.append('<input type="hidden" name="jcr:created" />'); - $form.append('<input type="hidden" name="jcr:createdBy" />'); - } ++ } + } - var callback = $form.data('callback'); - var data = new FormData(this); - $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); - $.ajax({ - url: $form.attr('action'), - type: 'POST', - data: data, - processData: false, - contentType: false, - dataType: 'json', - success: function(res,msg){ - if (callback && Sling.CMS.ext[callback]){ - Sling.CMS.ext[callback](res, msg); - } else { - Sling.CMS.ext.reload(res, msg); - } - }, - error: function(xhr, msg, err){ - if(window.self !== window.top){ - window.top.Sling.CMS.ui.confirmMessage(msg, err,function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - }); - } else { - Sling.CMS.ui.confirmMessage(msg, err,function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - }); - } - } - }); - return false; ++ }); ++ return false; + }); - } - }; ++ } ++}; + - Sling.CMS.ext['draggable'] = { - decorate: function($ctx) { - var draggable = function(){ - var element = this; - var mouseX; - var mouseY; - var mouseDown = false; - var elementX = 0; - var elementY = 0; - - // mouse button down over the element - element.addEventListener('mousedown', function(evt){ - if(document.querySelector('.modal-card-body').contains(evt.target)){ - return; - } - mouseX = evt.clientX; - mouseY = evt.clientY; - mouseDown = true; - }); - - var moveComplete = function(){ - mouseDown = false; - elementX = parseInt(element.style.left) || 0; - elementY = parseInt(element.style.top) || 0; - return false; - } - - element.addEventListener('mouseup', moveComplete); - document.addEventListener('mouseout', moveComplete); - - document.addEventListener('mousemove', function(event) { - if (!mouseDown) { - return; - } - var deltaX = event.clientX - mouseX; - var deltaY = event.clientY - mouseY; - element.style.left = elementX + deltaX + 'px'; - element.style.top = elementY + deltaY + 'px'; - return false; - }); - - }; - if($ctx.is('.is-draggable')){ - $ctx.each(draggable) - } - $ctx.find('.is-draggable').each(draggable); - } - }; - - Sling.CMS.ext['load-versions'] = { - loaded: false, - decorate: function($ctx) { - if(!Sling.CMS.ext['load-versions'].loaded){ - $ctx.find('.load-versions').each(function(){ - var $ctr = $(this); - var $table = $ctr.closest('.table'); - $.getJSON($ctr.data('url'),function(res){ - $table.dataTable().api().destroy(); - var source = $('#'+$ctr.data('template')).html(); - var template = Handlebars.compile(source); - $ctr.append(template(res)); - Sling.CMS.ext['load-versions'].loaded = true; - Sling.CMS.decorate($ctr.closest('.version-container')); - }); - }); - } - } - }; ++Sling.CMS.ext['draggable'] = { ++ decorate : function($ctx) { ++ var draggable = function() { ++ var element = this; ++ var mouseX; ++ var mouseY; ++ var mouseDown = false; ++ var elementX = 0; ++ var elementY = 0; + - //support links which fetch HTML and display a modal - Sling.CMS.ext['fetch-modal'] = { - decorate : function($ctx){ - $ctx.find('a.Fetch-Modal').click(function(){ - var $link = $(this); - $link.attr('disabled', 'disabled'); - Sling.CMS.ui.fetchModal($link.attr('data-title'), encodeURI($link.attr('href')), $link.attr('data-path'), function(){ - $link.removeAttr('disabled'); - }); - return false; - }); - } - }; - - Sling.CMS.ext['getform'] = { - decorate: function($ctx){ - $ctx.find('.Get-Form').submit(function(){ - var $form = $(this); - var params = $form.serialize(); - $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); - - $($form.data('target')).load($form.attr('action') + '?' + params +' ' + $form.data('load'), function(){ - $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); - Sling.CMS.decorate($($form.data('target'))); - }); - return false; - }); ++ // mouse button down over the element ++ element.addEventListener('mousedown', function(evt) { ++ if (document.querySelector('.modal-card-body').contains(evt.target)) { ++ return; + } - }; ++ mouseX = evt.clientX; ++ mouseY = evt.clientY; ++ mouseDown = true; ++ }); + - Sling.CMS.ext['includeconfig'] = { - decorate: function($ctx){ - $ctx.find('.sling-cms-include-config').each(function(){ - var $ctr = $(this); - var load = function(){ - var config = $($ctr.data('source')).find('option:selected').data('config'); - - if(config){ - $ctr.load(config + $ctr.parents('form').attr('action'), function(){ - Sling.CMS.decorate($ctr.children()); - }); - } - }; - $($ctr.data('source')).change(load); - load(); - }); - } - }; ++ var moveComplete = function() { ++ mouseDown = false; ++ elementX = parseInt(element.style.left) || 0; ++ elementY = parseInt(element.style.top) || 0; ++ return false; ++ } + - Sling.CMS.ext['handledelete'] = function(res, msg){ - if(window.location.pathname.indexOf(res.path) !== -1){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.location = '/cms'; - }); - } else { - Sling.CMS.ext.reload(res, msg); - } - } ++ element.addEventListener('mouseup', moveComplete); ++ document.addEventListener('mouseout', moveComplete); + - Sling.CMS.ext['handlemove'] = function(res, msg){ - var changes = res.changes[0]; - if(changes.type === 'moved' && window.location.pathname.indexOf(changes.argument[0]) !== -1){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.location = window.location.href.replace(changes.argument[0], changes.argument[1]); - }); - } else { - Sling.CMS.ext.reload(res, msg); ++ document.addEventListener('mousemove', function(event) { ++ if (!mouseDown) { ++ return; + } ++ var deltaX = event.clientX - mouseX; ++ var deltaY = event.clientY - mouseY; ++ element.style.left = elementX + deltaX + 'px'; ++ element.style.top = elementY + deltaY + 'px'; ++ return false; ++ }); ++ ++ }; ++ if ($ctx.is('.is-draggable')) { ++ $ctx.each(draggable) + } ++ $ctx.find('.is-draggable').each(draggable); ++ } ++}; + - Sling.CMS.ext['handleugc'] = function(res, msg){ - Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.location = '/cms/usergenerated/content.html'+res.parentLocation; - }); ++Sling.CMS.ext['load-versions'] = { ++ loaded : false, ++ decorate : function($ctx) { ++ if (!Sling.CMS.ext['load-versions'].loaded) { ++ $ctx.find('.load-versions').each(function() { ++ var $ctr = $(this); ++ var $table = $ctr.closest('.table'); ++ $.getJSON($ctr.data('url'), function(res) { ++ $table.dataTable().api().destroy(); ++ var source = $('#' + $ctr.data('template')).html(); ++ var template = Handlebars.compile(source); ++ $ctr.append(template(res)); ++ Sling.CMS.ext['load-versions'].loaded = true; ++ Sling.CMS.decorate($ctr.closest('.version-container')); ++ }); ++ }); + } ++ } ++}; + - Sling.CMS.ext['namehint'] = { - decorate: function($ctx){ - $ctx.find('.namehint').each(function(){ - var $nh = $(this); - $nh.parents('.Form-Ajax').find('select[name="sling:resourceType"]').change(function(){ - var resourceType = $(this).val().split("\/"); - $nh.val(resourceType[resourceType.length - 1]); - }); - }); - } - }; - - Sling.CMS.ext['pageproperties'] = { - decorate: function($ctx){ - $ctx.find('.Sling-CMS__page-properties').each(function(){ - var $ctr = $(this); - var $wrapper = $ctr.closest('.Form-Ajax__wrapper'); - $($ctr.data('source')).change(function(){ - var config = $(this).val(); - $ctr.load($ctr.data('path')+config, function(){ - var source = $('#content-template').html(); - var template = Handlebars.compile(source); - var updateContent = function(){ - if(!$wrapper.is(':disabled')){ - var data = Sling.CMS.utils.form2Obj($ctr.parents('form')); - $('input[name=":content"]').val(template(data)); - } - } - $ctr.find('input,textarea,select').change(updateContent); - $ctr.parents('form').submit(updateContent); - Sling.CMS.decorate($ctr.children()); - }); - }); - }); - } - }; ++// support links which fetch HTML and display a modal ++Sling.CMS.ext['fetch-modal'] = { ++ decorate : function($ctx) { ++ $ctx.find('a.Fetch-Modal').click( ++ function() { ++ var $link = $(this); ++ $link.attr('disabled', 'disabled'); ++ Sling.CMS.ui.fetchModal($link.attr('data-title'), encodeURI($link ++ .attr('href')), $link.attr('data-path'), function() { ++ $link.removeAttr('disabled'); ++ }); ++ return false; ++ }); ++ } ++}; + - Sling.CMS.ext['pathfield'] = { - suggest: function(field, type, base) { - var xhr; - new autoComplete({ - minChars: 1, - selector: field, - source: function(term, response){ - try { - xhr.abort(); - } catch(e){} - if(term === '/'){ - term = base; - } - xhr = $.getJSON('/bin/cms/paths', { path: term, type: type }, function(data){ - response(data); - }); - } - }); - }, - decorate: function($ctx){ - $ctx.find('input.pathfield').each(function(){ - var type = $(this).data('type'); - var base = $(this).data('base'); - Sling.CMS.ext.pathfield.suggest(this, type, base); - }); - } - }; ++Sling.CMS.ext['getform'] = { ++ decorate : function($ctx) { ++ $ctx.find('.Get-Form').submit( ++ function() { ++ var $form = $(this); ++ var params = $form.serialize(); ++ $form.find('.Form-Ajax__wrapper').attr('disabled', 'disabled'); + - Sling.CMS.ext['reload'] = function(res, msg) { - if(window.self !== window.top){ - window.top.Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - window.top.location.reload(); - }); - } else { - Sling.CMS.ui.confirmMessage(msg, res.title,function(){ - location.reload(); - }); - } - } - - Sling.CMS.ext['repeating'] = { - decorate: function($ctx){ - $ctx.find('.repeating').each(function(){ - var $rep = $(this); - $rep.find('.repeating__add').click(function(){ - var $div = $('<div/>').html($rep.find('.repeating__template').html()); - Sling.CMS.decorate($div); - $rep.find('.repeating__container').append($div); - return false; - }); - }); - $ctx.find('.repeating__remove').click(function(){ - var $rem = $(this); - $rem.parents('.repeating__item').remove(); - return false; - }); - } - }; - - Sling.CMS.ext['richtext'] = { - decorate: function($ctx){ - $ctx.find('.richtext').summernote({ - toolbar: [ - ['style', ['bold', 'italic', 'clear','strikethrough', 'superscript', 'subscript']], - ['insert', ['picture', 'link', 'table', 'hr']], - ['para', ['style','ul', 'ol', 'paragraph']], - ['misc', ['codeview', 'undo','redo','help']] - ], - followingToolbar: false, - dialogsInBody: true, - height: 200, - onCreateLink: function (url) { - return url; - }, - callbacks: { - onDialogShown: function(){ - Sling.CMS.ext.pathfield.suggest($('.note-link-url')[0], 'content', '/content'); - Sling.CMS.ext.pathfield.suggest($('.note-image-url')[0], 'content', '/content'); - } - } - }); - } - }; - - Sling.CMS.ext['searchselect'] = { - decorate: function($ctx) { - $ctx.find('.Search-Select-Button').click(function(evt){ - var $btn = $(evt.target); - var $active = Sling.CMS.ext['searchbutton'].active; - $active.val($btn.data('path')); - $btn.closest('.Modal').remove(); - }); - } - } - - Sling.CMS.ext['searchbutton'] = { - active: null, - decorate: function($ctx) { - $ctx.find('.Search-Button').click(function(evt){ - Sling.CMS.ext['searchbutton'].active = $(evt.target).closest('.Field-Input').find('.Field-Path'); - }); - } - } ++ $($form.data('target')).load( ++ $form.attr('action') + '?' + params + ' ' + $form.data('load'), ++ function() { ++ $form.find('.Form-Ajax__wrapper').removeAttr('disabled'); ++ Sling.CMS.decorate($($form.data('target'))); ++ }); ++ return false; ++ }); ++ } ++}; + - Sling.CMS.ext['suffix-form'] = { - init: function() { - $('.suffix-form').submit(function(){ - var suffix = $(this).find('input[name=suffix]').val(); - var path = $(this).attr('action'); - window.location = path + suffix; - return false; - }); - } - } - - Sling.CMS.ext['table'] = { - decorate: function($ctx) { - $ctx.find('table tbody tr').click(function(el){ - $('.actions-target > *').appendTo('tr.is-selected .cell-actions') - $('tr').removeClass('is-selected'); - $(this).addClass('is-selected'); - $(this).find('.cell-actions > *').appendTo('.actions-target') - }); ++Sling.CMS.ext['includeconfig'] = { ++ decorate : function($ctx) { ++ $ctx.find('.sling-cms-include-config').each( ++ function() { ++ var $ctr = $(this); ++ var load = function() { ++ var config = $($ctr.data('source')).find('option:selected').data( ++ 'config'); + - $ctx.find('table').each(function(){ - var sort = $(this).data('sort') !== 'false'; - var paginate = $(this).data('paginate') !== 'false'; - $(this).DataTable({ - sort: sort, - paginate: paginate - }); - }); - } - }; ++ if (config) { ++ $ctr.load(config + $ctr.parents('form').attr('action'), ++ function() { ++ Sling.CMS.decorate($ctr.children()); ++ }); ++ } ++ }; ++ $($ctr.data('source')).change(load); ++ load(); ++ }); ++ } ++}; + - Sling.CMS.ext['taxonomy'] = { - decorate: function($ctx){ - $ctx.find('.taxonomy').each(function(){ - var $rep = $(this); - $rep.find('.taxonomy__add').click(function(){ - var $span = $('<span/>').html($rep.find('.taxonomy__template').html()); - var val = $ctx.find('.taxonomy__field input').val(); - var found = false; - $rep.find('.taxonomy__item input').each(function(idx, el){ - if($(el).val() === val){ - found = true; - } - }); - if(found){ - return false; - } - $span.find('input').val(val); - var title = $ctx.find('option[value="'+val+'"]').text(); - - if(title !== ''){ - $span.find('.taxonomy__title').text(title); - Sling.CMS.decorate($span); - $('.taxonomy__container').append($span); - $ctx.find('.taxonomy__field input').val(''); - } - return false; - }); - }); - $ctx.find('.taxonomy__item').click(function(){ - $(this).remove(); - return false; - }); ++Sling.CMS.ext['handledelete'] = function(res, msg) { ++ if (window.location.pathname.indexOf(res.path) !== -1) { ++ window.top.Sling.CMS.ui.confirmMessage(msg, res.title, function() { ++ window.location = '/cms'; ++ }); ++ } else { ++ Sling.CMS.ext.reload(res, msg); ++ } ++} ++ ++Sling.CMS.ext['handlemove'] = function(res, msg) { ++ var changes = res.changes[0]; ++ if (changes.type === 'moved' ++ && window.location.pathname.indexOf(changes.argument[0]) !== -1) { ++ window.top.Sling.CMS.ui.confirmMessage(msg, res.title, function() { ++ window.location = window.location.href.replace(changes.argument[0], ++ changes.argument[1]); ++ }); ++ } else { ++ Sling.CMS.ext.reload(res, msg); ++ } ++} ++ ++Sling.CMS.ext['handleugc'] = function(res, msg) { ++ Sling.CMS.ui.confirmMessage(msg, res.title, function() { ++ window.location = '/cms/usergenerated/content.html' + res.parentLocation; ++ }); ++} ++ ++Sling.CMS.ext['namehint'] = { ++ decorate : function($ctx) { ++ $ctx.find('.namehint').each( ++ function() { ++ var $nh = $(this); ++ $nh.parents('.Form-Ajax').find('select[name="sling:resourceType"]') ++ .change(function() { ++ var resourceType = $(this).val().split("\/"); ++ $nh.val(resourceType[resourceType.length - 1]); ++ }); ++ }); ++ } ++}; ++ ++Sling.CMS.ext['pageproperties'] = { ++ decorate : function($ctx) { ++ $ctx.find('.Sling-CMS__page-properties').each(function() { ++ var $ctr = $(this); ++ var $wrapper = $ctr.closest('.Form-Ajax__wrapper'); ++ $($ctr.data('source')).change(function() { ++ var config = $(this).val(); ++ $ctr.load($ctr.data('path') + config, function() { ++ var source = $('#content-template').html(); ++ var template = Handlebars.compile(source); ++ var updateContent = function() { ++ if (!$wrapper.is(':disabled')) { ++ var data = Sling.CMS.utils.form2Obj($ctr.parents('form')); ++ $('input[name=":content"]').val(template(data)); ++ } ++ } ++ $ctr.find('input,textarea,select').change(updateContent); ++ $ctr.parents('form').submit(updateContent); ++ Sling.CMS.decorate($ctr.children()); ++ }); ++ }); ++ }); ++ } ++}; ++ ++Sling.CMS.ext['pathfield'] = { ++ suggest : function(field, type, base) { ++ var xhr; ++ new autoComplete({ ++ minChars : 1, ++ selector : field, ++ source : function(term, response) { ++ try { ++ xhr.abort(); ++ } catch (e) { + } - }; - - Sling.CMS.ext['toggle-hidden'] = { - decorate: function($ctx){ - $ctx.find('.toggle-hidden').click(function(){ - $($(this).data('target')).toggleClass('is-hidden'); - }); ++ if (term === '/') { ++ term = base; + } - }; - - Sling.CMS.ext['toggle-value'] = { - decorate: function($ctx) { - $ctx.find('.toggle-value').each(function(){ - var $tog = $(this); - $('input[name="'+$tog.data('toggle-source')+'"], select[name="'+$tog.data('toggle-source')+'"]').change(function(){ - if($(this).val() !== $tog.data('toggle-value')){ - $tog.addClass('is-hidden'); - } else { - $tog.removeClass('is-hidden'); - } - }); - }) ++ xhr = $.getJSON('/bin/cms/paths', { ++ path : term, ++ type : type ++ }, function(data) { ++ response(data); ++ }); ++ } ++ }); ++ }, ++ decorate : function($ctx) { ++ $ctx.find('input.pathfield').each(function() { ++ var type = $(this).data('type'); ++ var base = $(this).data('base'); ++ Sling.CMS.ext.pathfield.suggest(this, type, base); ++ }); ++ } ++}; ++ ++Sling.CMS.ext['reload'] = function(res, msg) { ++ if (window.self !== window.top) { ++ window.top.Sling.CMS.ui.confirmMessage(msg, res.title, function() { ++ window.top.location.reload(); ++ }); ++ } else { ++ Sling.CMS.ui.confirmMessage(msg, res.title, function() { ++ location.reload(); ++ }); ++ } ++} ++ ++Sling.CMS.ext['repeating'] = { ++ decorate : function($ctx) { ++ $ctx.find('.repeating').each(function() { ++ var $rep = $(this); ++ $rep.find('.repeating__add').click(function() { ++ var $div = $('<div/>').html($rep.find('.repeating__template').html()); ++ Sling.CMS.decorate($div); ++ $rep.find('.repeating__container').append($div); ++ return false; ++ }); ++ }); ++ $ctx.find('.repeating__remove').click(function() { ++ var $rem = $(this); ++ $rem.parents('.repeating__item').remove(); ++ return false; ++ }); ++ } ++}; ++ ++Sling.CMS.ext['richtext'] = { ++ decorate : function($ctx) { ++ $ctx.find('.richtext').summernote( ++ { ++ toolbar : [ ++ [ ++ 'style', ++ [ 'bold', 'italic', 'clear', 'strikethrough', 'superscript', ++ 'subscript' ] ], ++ [ 'insert', [ 'picture', 'link', 'table', 'hr' ] ], ++ [ 'para', [ 'style', 'ul', 'ol', 'paragraph' ] ], ++ [ 'misc', [ 'codeview', 'undo', 'redo', 'help' ] ] ], ++ followingToolbar : false, ++ dialogsInBody : true, ++ height : 200, ++ onCreateLink : function(url) { ++ return url; ++ }, ++ callbacks : { ++ onDialogShown : function() { ++ Sling.CMS.ext.pathfield.suggest($('.note-link-url')[0], ++ 'content', '/content'); ++ Sling.CMS.ext.pathfield.suggest($('.note-image-url')[0], ++ 'content', '/content'); ++ } ++ } ++ }); ++ } ++}; ++ ++Sling.CMS.ext['searchselect'] = { ++ decorate : function($ctx) { ++ $ctx.find('.Search-Select-Button').click(function(evt) { ++ var $btn = $(evt.target); ++ var $active = Sling.CMS.ext['searchbutton'].active; ++ $active.val($btn.data('path')); ++ $btn.closest('.Modal').remove(); ++ }); ++ } ++} ++ ++Sling.CMS.ext['searchbutton'] = { ++ active : null, ++ decorate : function($ctx) { ++ $ctx.find('.Search-Button').click( ++ function(evt) { ++ Sling.CMS.ext['searchbutton'].active = $(evt.target).closest( ++ '.Field-Input').find('.Field-Path'); ++ }); ++ } ++} ++ ++Sling.CMS.ext['suffix-form'] = { ++ init : function() { ++ $('.suffix-form').submit(function() { ++ var suffix = $(this).find('input[name=suffix]').val(); ++ var path = $(this).attr('action'); ++ window.location = path + suffix; ++ return false; ++ }); ++ } ++} ++ ++Sling.CMS.ext['table'] = { ++ decorate : function($ctx) { ++ $ctx.find('table tbody tr').click(function(el) { ++ $('.actions-target > *').appendTo('tr.is-selected .cell-actions') ++ $('tr').removeClass('is-selected'); ++ $(this).addClass('is-selected'); ++ $(this).find('.cell-actions > *').appendTo('.actions-target') ++ }); ++ ++ $ctx.find('table').each(function() { ++ var sort = $(this).data('sort') !== 'false'; ++ var paginate = $(this).data('paginate') !== 'false'; ++ $(this).DataTable({ ++ sort : sort, ++ paginate : paginate ++ }); ++ }); ++ } ++}; ++ ++Sling.CMS.ext['taxonomy'] = { ++ decorate : function($ctx) { ++ $ctx.find('.taxonomy').each(function() { ++ var $rep = $(this); ++ $rep.find('.taxonomy__add').click(function() { ++ var $span = $('<span/>').html($rep.find('.taxonomy__template').html()); ++ var val = $ctx.find('.taxonomy__field input').val(); ++ var found = false; ++ $rep.find('.taxonomy__item input').each(function(idx, el) { ++ if ($(el).val() === val) { ++ found = true; ++ } ++ }); ++ if (found) { ++ return false; + } - }; - - Sling.CMS.ext['file-upload'] = { - decorate: function($ctx) { - $ctx.find('.file').on('change', "input", function(){ - var node = $(this); - node.parent().find('.file-name').text(this.files[0].name); - }); ++ $span.find('input').val(val); ++ var title = $ctx.find('option[value="' + val + '"]').text(); ++ ++ if (title !== '') { ++ $span.find('.taxonomy__title').text(title); ++ Sling.CMS.decorate($span); ++ $('.taxonomy__container').append($span); ++ $ctx.find('.taxonomy__field input').val(''); + } - }; ++ return false; ++ }); ++ }); ++ $ctx.find('.taxonomy__item').click(function() { ++ $(this).remove(); ++ return false; ++ }); ++ } ++}; + - $(document).ready(function() { - Sling.CMS.init(); ++Sling.CMS.ext['toggle-hidden'] = { ++ decorate : function($ctx) { ++ $ctx.find('.toggle-hidden').click(function() { ++ $($(this).data('target')).toggleClass('is-hidden'); + }); ++ } ++}; ++ ++Sling.CMS.ext['toggle-value'] = { ++ decorate : function($ctx) { ++ $ctx.find('.toggle-value').each( ++ function() { ++ var $tog = $(this); ++ $( ++ 'input[name="' + $tog.data('toggle-source') + '"], select[name="' ++ + $tog.data('toggle-source') + '"]').change(function() { ++ if ($(this).val() !== $tog.data('toggle-value')) { ++ $tog.addClass('is-hidden'); ++ } else { ++ $tog.removeClass('is-hidden'); ++ } ++ }); ++ }) ++ } ++}; ++ ++Sling.CMS.ext['file-upload'] = { ++ decorate : function($ctx) { ++ $ctx.find('.file').on('change', "input", function() { ++ var node = $(this); ++ node.parent().find('.file-name').text(this.files[0].name); ++ }); ++ } ++}; ++ ++$(document).ready(function() { ++ Sling.CMS.init(); ++}); diff --cc ui/src/main/resources/jcr_root/libs/sling-cms/content/start.json index fa03c4a,d8bce41..2e9aa72 --- a/ui/src/main/resources/jcr_root/libs/sling-cms/content/start.json +++ b/ui/src/main/resources/jcr_root/libs/sling-cms/content/start.json @@@ -58,6 -73,11 +58,13 @@@ "title": "Tools", "links": { "jcr:primaryType": "nt:unstructured", ++ "links": { ++ "jcr:primaryType": "nt:unstructured", + "bulkreplace": { + "jcr:primaryType": "nt:unstructured", + "link": "/cms/admin/bulkreplace.html", + "text": "Bulk Replace" + }, "contentpackages": { "jcr:primaryType": "nt:unstructured", "link": "/bin/packages.html",
