...
Code Block |
---|
## @noparams #set ( $Integer$containerManagerClass = 0$content.class.forName('com.atlassian.spring.container.ContainerManager') ) #set ( $requestedSearch$getInstanceMethod = ""$containerManagerClass.getDeclaredMethod('getInstance',null) ) #set ( $requestedSearch$containerManager = $req$getInstanceMethod.getParameter('requestedSearch'invoke(null,null) ) #set ( $requestedSpaces$containerContext = ""$containerManager.containerContext ) #set ( $requestedSpaces$webResourceManager = $req$containerContext.getParametergetComponent('requestedSpaceswebResourceManager') ) $webResourceManager.requireResource('com.atlassian.auiplugin:aui-select2') #set ( $replace$Integer = 0 ) #set ( $requestedSearch = "" ) #set ( $requestedSearch = $req.getParameter('requestedSearch') ) #set ( $requestedSpaces = "" ) #set ( $replace$requestedSpaces = $req.getParameter('replacerequestedSpaces') ) #set ( $requestedReplace$replace = "" ) #set ( $requestedReplace$replace = $req.getParameter('requestedReplacereplace') ) #set ( $continue$requestedReplace = "" ) #set ( $continue$requestedReplace = $req.getParameter('continuerequestedReplace') ) #set ( $escapedRequestedSearch = $generalUtil.escapeXml($requestedSearch) ) #set ( $escapedRequestedReplace = $generalUtil.escapeXml($requestedReplace) ) #set ( $requestCharacter = "?" ) #if ( $content.getUrlPath().contains("?") ) #set ( $requestCharacter = "&" ) #end <script> var qs = (function(a) { if (a == "") return {}; var b = {}; for (var i = 0; i < a.length; ++i) { var p=a[i].split('=', 2); if (p.length == 1) b[p[0]] = ""; else b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " ")); } return b; })(window.location.search.substr(1).split('&')); function htmlEncode ( html ) { return document.createElement( 'a' ).appendChild( document.createTextNode( html ) ).parentNode.innerHTML; }; </script> #if ( $requestedSearch == "" function htmlDecode (text) { <form class="aui top-label" onsubmit="return false;">jQuery('<textarea/>').html(text).text(); } <div class="field-group top-label"> <label for="requested-search">Enter Search Terms:</label> <input id="requested-search" class="text long-field" type="text" name="requestedSearch"> </div> <div class="field-group"> <input id="replace" type="checkbox" onclick="jQuery('#requested-replace').val('');jQuery('#replace-fields').toggle();"> <span>Do Search/Replace</span> </div> <div class="field-group" id="replace-fields" style="display:none;"> <label for="requested-replace">Text to replace:</label> <input id="requested-replace" class="text long-field" type="text" name="requestedReplace"> </div> <script> jQuery(function() { if (document.getElementById('replace').checked) { jQuery('#replace-fields').show(); } }); </script> ## show replace field if user hits back button <div class="field-group"> <label for="requestedSpaces">Spaces to search:</label> <select class="select" id="requestedSpaces" name="requestedSpaces" multiple> #set ( $allSpaces = $spaceManager.getAllSpaces() ) #foreach ( $space in $allSpaces ) #if ( $space.isGlobal() ) <option value="$space.key">$space.name - $space.key</option> #end #end </div> <button class="button submit" onclick="window.location = '$content.getUrlPath()' + '${requestCharacter}requestedSearch=' + encodeURIComponent(document.getElementById('requested-search').value) + '&requestedSpaces=' + jQuery('#requestedSpaces').select2('val').join() + '&replace=' + jQuery('#replace').is(':checked') + '&requestedReplace=' + encodeURIComponent(document.getElementById('requested-replace').value);">Search</button> </form> <script> jQuery("#requestedSpaces").auiSelect2(); </script> #elseif ( $requestedSearch != "" && $replace == "false" ) #set ( $searchTerm = $requestedSearch ) #foreach ( $spaceKey in $requestedSpaces.split(",") ) #set ( $space = $spaceManager.getSpace($spaceKey) ) <p> Pages containing "${escapedRequestedSearch}" in $space.name </p> #set ( $spacePages = $pageManager.getPages($space, true) ) <table> <thead> <tr> <th> <p>Page</p> </th> <th> var formatXml = this.formatXml = function (xml) { var reg = /(>)\s*(<)(\/*)/g; var wsexp = / *(.*) +\n/g; var contexp = /(<.+>)(.+\n)/g; xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); var pad = 0; var formatted = ''; var lines = xml.split('\n'); var indent = 0; var lastType = 'other'; var transitions = { 'single->single': 0, 'single->closing': -1, 'single->opening': 0, 'single->other': 0, 'closing->single': 0, 'closing->closing': -1, 'closing->opening': 0, 'closing->other': 0, 'opening->single': 1, 'opening->closing': 0, 'opening->opening': 1, 'opening->other': 1, 'other->single': 0, 'other->closing': -1, 'other->opening': 0, 'other->other': 0 }; for (var i = 0; i < lines.length; i++) { var ln = lines[i]; var single = Boolean(ln.match(/<.+\/>/)); var closing = Boolean(ln.match(/<\/.+>/)); var opening = Boolean(ln.match(/<[^!].*>/)); var type = single ? 'single' : closing ? 'closing' : opening ? 'opening' : 'other'; var fromTo = lastType + '->' + type; lastType = type; var padding = ''; indent += transitions[fromTo]; for (var j = 0; j < indent; j++) { padding += ' '; } if (fromTo == 'opening->closing') formatted </th> </tr>= formatted.substr(0, formatted.length - 1) + ln + '\n'; else </thead> <tbody> formatted += padding + ln + #foreach ($page in $spacePages) '\n'; } return formatted; #set ( $pageId = $page.id }; </script> #if ( $requestedSearch == "" ) <form class="aui top-label" onsubmit="return false;"> #set ( $pageMarkup<div class= $page.getBodyAsString() )"field-group top-label"> <label for="requested-search">Enter Search Terms:</label> #if ( $permissionHelper.canView($action.remoteUser, $page) && $pageMarkup.contains($searchTerm) ) #set ( $quoteEscapedPageMarkup = $pageMarkup.replaceAll($generalUtil.urlDecode("%22"), """) ) <input id="requested-search" class="text long-field" type="text" name="requestedSearch"> </div> <tr><div class="field-group"> <input <td> <p><a href="$action.getGlobalSettings().getBaseUrl()$page.getUrlPath()" target="_blank">$page.title</a></p>id="replace" type="checkbox" onclick="jQuery('#requested-replace').val('');jQuery('#replace-fields').toggle();"> <span>Do Search/Replace</span> </div> <input style="display:none;" <div class="page-checkbox" type="checkbox"field-group" id="pagereplace-$pageIdfields" originalstyle="$quoteEscapedPageMarkupdisplay:none;"> <label for="requested-replace">Text to replace:</td>label> <input id="requested-replace" class="text long-field" type="text" name="requestedReplace"> <td> </div> <script> jQuery(function() { if <button id="preview${pageId}" class="aui-button">Preview</button> (document.getElementById('replace').checked) { jQuery('#replace-fields').show(); } }); </script> ## show replace field if user hits back button <button<div class="auifield-buttongroup" onclick="window.open(contextPath + '/pages/editpage.action?pageId=$pageId', '_blank');">Edit</button>> <label for="requestedSpaces">Spaces to search:</label> <select <script> class="select" id="requestedSpaces" name="requestedSpaces" multiple> #set ( $allSpaces = $spaceManager.getAllSpaces() ) var dialog${pageId} = new#foreach AJS.Dialog({ $space in $allSpaces ) #if ( $space.isGlobal() ) width: 840, <option value="$space.key">$space.name - $space.key</option> #end height: 640, #end </div> <button class="button submit" onclick="window.location = '$content.getUrlPath()' id: "dialog${pageId}", closeOnOutsideClick: true }); dialog${pageId}.addHeader("Preview"); var originalMarkup = jQuery("#page-${pageId}").attr("original"); var originalMarkupArray = originalMarkup.split(jQuery('<textarea/>').html(qs["requestedSearch"]).text()); + '${requestCharacter}requestedSearch=' + encodeURIComponent(document.getElementById('requested-search').value) + '&requestedSpaces=' + jQuery('#requestedSpaces').select2('val').join() + '&replace=' + jQuery('#replace').is(':checked') + '&requestedReplace=' + encodeURIComponent(document.getElementById('requested-replace').value);">Search</button> </form> <script> jQuery("#requestedSpaces").auiSelect2(); </script> #elseif ( $requestedSearch != "" && $replace == "false" ) #set ( $searchTerm = $requestedSearch ) #foreach ( $spaceKey in $requestedSpaces.split(",") ) #set ( $space = $spaceManager.getSpace($spaceKey) ) <p> Pages containing "${escapedRequestedSearch}" in $space.name </p> #set ( $spacePages = $pageManager.getPages($space, true) ) <table> <thead> var<tr> previewMarkup = jQuery('<pre style="white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word;"></pre>'); <th> <p>Page</p> var replaceElement = '<span style="background-color: #ddfade;">' + htmlEncode(qs["requestedSearch"]) + '</span>';th> <th> jQuery.each( originalMarkupArray, function(i, val) {</th> </tr> </thead> jQuery(previewMarkup).append(jQuery('<span>' + htmlEncode(val) + '</span>' + replaceElement)); <tbody> #foreach ($page in $spacePages) #set ( $pageId = $page.id ) }); #set ( $pageMarkup = $page.getBodyAsString() ) #if jQuery('span', previewMarkup).last().remove(); $permissionHelper.canView($action.remoteUser, $page) && $pageMarkup.contains($searchTerm) ) #set ( $quoteEscapedPageMarkup = dialog${pageId}.addPanel("SinglePanel", previewMarkup, "singlePanel"); $pageMarkup.replaceAll('"', '@@quot@@').replaceAll('"', '@@quot@@') ) <tr> dialog${pageId}.addButton("Close", function (dialog${pageId}) {<td style="vertical-align:middle"> dialog${pageId}.hide(); <p><a href="$action.getGlobalSettings().getBaseUrl()$page.getUrlPath()" target="_blank">$page.title</a></p> }); <input style="display:none;" class="page-checkbox" type="checkbox" id="page-$pageId" pageid="$pageId" original="$quoteEscapedPageMarkup"> jQuery("#preview${pageId}").click(function() {</td> <td> dialog${pageId}.gotoPage(0); dialog$<button id="preview${pageId}.gotoPanel(0); " class="aui-button">Preview</button> <button class="aui-button" onclick="window.open(contextPath dialog${pageId}.show(); }); </script>+ '/pages/editpage.action?pageId=$pageId', '_blank');">Edit</button> </td> </tr> #end #end </tbody> </table> #end <p> </p> <button class="aui-button" onclick="window.location = '$content.getUrlPath()'">New Search</button> #elseif ( $requestedSearch != "" && $replace == "true" && $continue == "" ) <button class="aui-button" onclick="jQuery('.page-checkbox').prop('checked', true);">Select All</button> <button class="aui-button" onclick="jQuery('.page-checkbox').prop('checked', false);">Select None</button> #set ( $searchResultCount = 0 ) #set ( $searchTerm = $requestedSearch ) #foreach ( $spaceKey in $requestedSpaces.split(",") ) #set ( $space = $spaceManager.getSpace($spaceKey) ) <p> Pages containing "${escapedRequestedSearch}" in $space.name </p> #set ( $spacePages = $pageManager.getPages($space, true) ) <table> <thead> <colgroup> ## To prevent table from being sortable </colgroup> <tr> <th> <p>Page</p> </th> <th> <button class="aui-button" onclick="jQuery('.page-checkbox[space=\'$space.key\']').click();">X</button> </th> <th> </th> </tr> </thead> <tbody> #foreach ($page in $spacePages) #set ( $pageId = $page.id ) #set ( $pageMarkup = $page.getBodyAsString() ) #if ( $permissionHelper.canView($action.remoteUser, $page) && $pageMarkup.contains($searchTerm) ) #set ( $searchResultCount = $searchResultCount + 1 ) <tr> <td> <td style="vertical-align:middle"> <p><a href="$action.getGlobalSettings().getBaseUrl()$page.getUrlPath()" target="_blank">$page.title</a></p> </td> <td> <td style="vertical-align:middle"> #if ( $permissionHelper.canEdit($action.remoteUser, $page) ) #set ( $replacedPageMarkup = $pageMarkup.replaceAll($requestedSearch, $requestedReplace) ) #set ( $newPageMarkup = $replacedPageMarkup.replaceAll($generalUtil.urlDecode("%22"), """'"', '@@quot@@').replaceAll('"', '@@quot@@') ) ## %22 = " #set ( $newPageMarkup = $newPageMarkup.replaceAll(" ", " ") ) ## because of some sort of bug where is replaced with  #set ( $quoteEscapedPageMarkup = $pageMarkup.replaceAll($generalUtil.urlDecode("%22"), """'"', '@@quot@@').replaceAll('"', '@@quot@@') ) <input class="page-checkbox unchanged" type="checkbox" id="page-$pageId" pageid="$pageId" version="$page.version" title="$page.title" parent="$page.parent.id" space="$space.key" content="$newPageMarkup" original="$quoteEscapedPageMarkup" checked="checked"> <span class="aui-lozenge">unchanged</span> #else <span class="aui-lozenge aui-lozenge-current">cannot edit</span> #end </td> <td> <button id="preview${pageId}" class="aui-button">Preview</button> <button class="aui-button" onclick="window.open(contextPath + '/pages/editpage.action?pageId=$pageId', '_blank');">Edit</button> <button style="display:none;" id="undo-${pageId}" class="aui-button" onclick="window.open(contextPath + '/pages/revertpagebacktoversion.action?pageId=${pageId}&version=$page.version', '_blank');">Undo</button> </td> <script> </tr> var dialog${pageId}#end = new AJS.Dialog({ #end </tbody> </table> #end width: 840,<p> Found $searchResultCount results. You are about to replace "${escapedRequestedSearch}" with "${escapedRequestedReplace}" on all selected pages. Continue? </p> height: 640,<p> </p> <button class="aui-button" onclick="replaceText()">Continue</button> <button class="aui-button" onclick="window.location = '$content.getUrlPath()'">New Search</button> <script> function id: "dialog${pageId}",replaceText() { searchReplace(jQuery(".page-checkbox.unchanged:checked").first()) } function searchReplace(nextCheckbox) { closeOnOutsideClick: true var pageId = jQuery(nextCheckbox).attr("pageid"); var pageObj = { }); "id": pageId, dialog${pageId}.addHeader("Preview"); "type": "page", "title": jQuery(nextCheckbox).attr("title"), "space": { var originalMarkup ="key": jQuery("#page-${pageId}").attr("original");nextCheckbox).attr("space") }, var originalMarkupArray = originalMarkup.split(jQuery('<textarea/>').html(qs["requestedSearch"]).text());"body": { "storage": { var previewMarkup = jQuery('<pre style="white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word;"></pre>'); "value": jQuery(nextCheckbox).attr("content").split('@@quot@@').join('"'), "representation": "storage" var replaceElement = '<span style="background-color: #ddfade;">' + htmlEncode(qs["requestedReplace"]) + '</span>'; } }, "version": { if (qs["requestedReplace"] === "") { replaceElement = '<span style="background-color: #ddfade;">[blank]</span>' } ## so there is something to show if replacement field is blank "number": parseInt(jQuery(nextCheckbox).attr("version")) + 1 } } jQuery.ajax({ dataType: "json", jQuery.each( originalMarkupArray, function(i, val) { contentType: "application/json", type: "PUT", url: contextPath jQuery(previewMarkup).append(jQuery('<span>' + htmlEncode(val) + '</span>' + replaceElement));+ "/rest/api/content/" + pageId, data: JSON.stringify(pageObj), success: function (response) { }); jQuery(nextCheckbox) jQuery('span', previewMarkup).last().remove();removeClass("unchanged") dialog${pageId}.addPanel.addClass("SinglePanel", previewMarkup, "singlePanel"changed"); jQuery(nextCheckbox) .next() dialog${pageId}.addButton("Close", function (dialog${pageId}) { .removeClass("aui-lozenge-current") dialog${pageId}.hide();removeClass("aui-lozenge-error") });.addClass("aui-lozenge-complete") jQuery.html("#preview${pageId}updated").click(function() {; jQuery("#undo-" + pageObj.id).show(); dialog${pageId}.gotoPage(0); nextCheckbox = jQuery(".page-checkbox.unchanged:checked").first(); if (nextCheckbox.length) { dialog${pageId}.gotoPanel(0 searchReplace(nextCheckbox); } dialog${pageId}.show();}, error: function() { }); jQuery(nextCheckbox).removeClass("unchanged").addClass("error"); </script> jQuery(nextCheckbox) </td> .next() </tr> #end.removeClass("aui-lozenge-complete") #end </tbody>.removeClass("aui-lozenge-current") </table> #end <p> Found $searchResultCount results..addClass("aui-lozenge-error") You are about to replace "${escapedRequestedSearch}" with "${escapedRequestedReplace}" on all selected pages.html("error") Continue? </p> <p> </p> <button class="aui-button" onclick="replaceText()">Continue</button> console.log(response); <button class="aui-button" onclick="window.location = '$content.getUrlPath()'">New Search</button> <script> function replaceText(){searchReplace(nextCheckbox = jQuery(".page-checkbox.unchanged:checked").first())} function searchReplace(a){var c=[],b={};b.id=jQuery(a).attr("pageid");b.version=jQuery(a).attr("version");b.title=jQuery(a).attr("title");b.space=jQuery(a).attr("space");b.content=jQuery(a).attr("content");b.parentId=jQuery(a).attr("parent");c.push(b);jQuery.ajax({dataType:"json",contentType:"application/json",type:"POST",url:contextPath+"/rpc/json-rpc/confluenceservice-v2/storePage",data:JSON.stringify(c),success:function(c){c.hasOwnProperty("id")?(jQuery(a).removeClass("unchanged").addClass("changed"), jQuery(a).next().removeClass("aui-lozenge-current").removeClass("aui-lozenge-error").addClass("aui-lozenge-complete").html("updated"),jQuery("#undo-"+b.id).show(),a=jQuery("input[type='checkbox'].page-checkbox.unchanged:checked").first()):(jQuery(a).removeClass("unchanged").addClass("error"),jQuery(a).next().removeClass("aui-lozenge-complete").removeClass("aui-lozenge-current").addClass("aui-lozenge-error").html("error"),console.log(c),a=jQuery(".page-checkbox.unchanged:checked").first());0<a.length&& searchReplace(a)}})}; </script> #end; if (nextCheckbox.length) { searchReplace(nextCheckbox); } } }); } </script> #end <script> var nextMatch; var dialogs = {}; var requestedSearch = qs["requestedSearch"]; var requestedReplace = qs["requestedReplace"]; var replace = qs["replace"]; if (replace !== 'true') { requestedReplace = requestedSearch; } if (requestedReplace === "") { requestedReplace = '[Blank]'; } if (requestedSearch) { jQuery(".page-checkbox").each(function() { var pageId = jQuery(this).attr("pageid"); dialogs[pageId] = new AJS.Dialog({ width: 840, height: 640, id: "dialog" + pageId, closeOnOutsideClick: true }); dialogs[pageId].addHeader("Preview"); var replacedMarkup = jQuery(this) .attr("original") .split('@@quot@@') .join('"') .split(htmlDecode(requestedSearch)) .join(' @@start@@ ' + htmlEncode(requestedReplace) + ' @@end@@ '); var formattedMarkup = formatXml(replacedMarkup); var previewMarkup = jQuery('<pre style="white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word;"><span>' + formattedMarkup .split('<') .join('<') .split('>') .join('>') .split(' @@start@@ ') .join('</span><span class="match" style="background-color: #ddfade;">') .split(' @@end@@ ') .join('</span><span>') + '</span></pre>'); dialogs[pageId].addPanel("SinglePanel", previewMarkup, "singlePanel"); dialogs[pageId].addButton("Next Match", function () { if (!nextMatch) { nextMatch = jQuery(".match:visible").first(); nextMatch.css("background-color", "yellow"); } else { nextMatch.css("background-color", "#ddfade"); nextMatch = nextMatch.next().next(".match").length ? nextMatch.next().next(".match") : jQuery(".match:visible").first(); nextMatch.css("background-color", "yellow"); } nextMatch.get(0).scrollIntoView(); }); dialogs[pageId].addButton("Close", function () { if (nextMatch) { nextMatch.css("background-color", "#ddfade"); nextMatch = undefined; } dialogs[pageId].hide(); }); jQuery("#preview" + pageId).click(function() { dialogs[pageId].gotoPage(0); dialogs[pageId].gotoPanel(0); dialogs[pageId].show(); }); }); } </script> |