WRMCB=function(e){var c=console;if(c&&c.log&&c.error){c.log('Error running batched script.');c.error(e);}}
;
try {
/* module-key = 'com.atlassian.confluence.plugins.confluence-highlight-actions:highlighting-experiment-resources', location = '/js/doctheme-utils.js' */
/**
* Utility functions for working with the Documentation Theme
* TO DO: This needs to live somewhere else, maybe the Confluence Core JS library
*/
define('confluence-highlight-actions/js/doctheme-utils', ['jquery'], function($) {
'use strict';
function appendAbsolutePositionedElement(node) {
var $node = $(node);
$(node).appendTo($('body'));
return $node;
}
function getMainContentScrollTop() {
return $(document).scrollTop();
}
function getMainContentScrollLeft() {
return $(document).scrollLeft();
}
return {
appendAbsolutePositionedElement: appendAbsolutePositionedElement,
getMainContentScrollTop: getMainContentScrollTop,
getMainContentScrollLeft: getMainContentScrollLeft
};
});
require('confluence/module-exporter').exportModuleAsGlobal('confluence-highlight-actions/js/doctheme-utils', 'Confluence.DocThemeUtils');
}catch(e){WRMCB(e)};
;
try {
/* module-key = 'com.atlassian.confluence.plugins.confluence-highlight-actions:highlighting-experiment-resources', location = '/js/scrolling-inline-dialog.js' */
/**
* An improved version of the inline dialog that scrolls correctly when using documentation theme
* Because documentation theme uses a scrollable, fixed-height container, inline dialogs in documentation theme
* would not scroll with the content. This fixes that issue
*
* Call this exactly as you would call AJS.InlineDialog()
* https://developer.atlassian.com/display/AUI/Inline+Dialog
*
* @param items The elements that will trigger the inline-dialog, use a jQuery Selector to select items
* @param identifier A unique identifier for the inline-dialog
* @param url can be a url with dialog contents or a function to generate the dialog contents dynamically
* @param options A number of different options may be passed in as an associative array
* @returns the inline dialog
*/
define('confluence-highlight-actions/js/scrolling-inline-dialog', [
'ajs',
'jquery'
], function(
AJS,
$
) {
'use strict';
return function(items, identifier, url, options) {
options = options || {};
/**
* This method is copied from Inline Dialog and MODIFIED to work with documentation theme
*
* Modifications:
* Use position() instead of offset(), this returns the targetPosition coordinates relative to containing element
* and not the viewport
* Adjust top values for scroll in docTheme
* Use either window for the container or the docThemeContainer
* has an extra isActionPanelDialog parameter to help position that dialog accordingly
*/
var calculatePositions = function(popup, targetPosition, mousePosition, opts) {
var popupLeft; //position of the left edge of popup box from the left of the screen
var popupRight = "auto"; //position of the right edge of the popup box fron the right edge of the screen
var popupTop; //position of the top edge of popup box
var arrowOffsetY = -7; //the offsets of the arrow from the top edge of the popup, default is the height of the arrow above the popup
var arrowOffsetX;
var displayAbove; //determines if popup should be displayed above the the trigger or not
var containerWidth = $(window).width();
var targetOffset = targetPosition.target.position();
var triggerWidth = targetPosition.target.outerWidth(); //The total width of the trigger (including padding)
var middleOfTrigger = targetOffset.left + triggerWidth / 2; //The absolute x position of the middle of the Trigger
var bottomOfViewablePage = (window.pageYOffset || document.documentElement.scrollTop) + $(window).height();
//CONSTANTS
var SCREEN_PADDING = 10; //determines how close to the edge the dialog needs to be before it is considered offscreen
var SCREEN_TOP_PADDING = 20; //keep the bottom of inline-dialog enough far from the bottom of browser.
popupTop = targetOffset.top + targetPosition.target.outerHeight() + opts.offsetY;
var arrowWidth = popup.find(".arrow").outerWidth();
var popupOuterWidth = popup.outerWidth();
var targetOuterWidth = targetPosition.target.outerWidth();
if (opts.centerOnHighlight) {
// if action panel is wider that the selection, center the arrow and the dialog above the selection
if (popupOuterWidth > targetOuterWidth) {
popupLeft = targetOffset.left - (popupOuterWidth - targetOuterWidth) / 2;
arrowOffsetX = middleOfTrigger - popupLeft - arrowWidth / 2;
} else {
// align left to selection and place arrow in the center of dialog
popupLeft = targetOffset.left + opts.offsetX;
arrowOffsetX = (popupOuterWidth - arrowWidth) / 2;
}
} else {
// if not action panel, always align left the dialog to the selection
popupLeft = targetOffset.left + opts.offsetX;
// if the create issue popup is wider than the selection, center the arrow on the selection
if (popupOuterWidth > targetOuterWidth) {
arrowOffsetX = middleOfTrigger - popupLeft - arrowWidth / 2;
} else {
// if create issue popup is narrow then selection, place the arrow in the enter of the dialog
arrowOffsetX = (popupOuterWidth - arrowWidth) / 2;
}
}
// arrow always needs to have a positive offset
arrowOffsetX = (arrowOffsetX < 0) ? 0 : arrowOffsetX;
// Fix default behavior of original inline-dialog code.
var distanceToTopOfViewablePage = (targetOffset.top - (window.pageYOffset || document.documentElement.scrollTop));
var popupMaxHeight = opts.maxHeight || 0;
var popupHeight = popup.height();
var enoughRoomAbove = distanceToTopOfViewablePage > Math.max(popupHeight, popupMaxHeight);
var enoughRoomBelow = (popupTop + popup.height()) < bottomOfViewablePage;
//Check if the popup should be displayed above the trigger or not (if the user has set opts.onTop to true and if theres enough room)
displayAbove = (!enoughRoomBelow && enoughRoomAbove) || opts.onTop;
// opts is a reference to the original options that we used at init config
// Assign displayAbove value into onTop property to prevent dialog is flipped after call refresh()
opts.onTop = displayAbove;
//calculate if the popup will be offscreen
var diff = containerWidth - (popupLeft + popupOuterWidth + SCREEN_PADDING);
//check if the popup should be displayed above or below the trigger
if (displayAbove) {
popupTop = targetOffset.top - popupHeight - 8; //calculate the flipped position of the popup (the 8 allows for room for the arrow
arrowOffsetY = popupHeight;
}
// We have to make sure inline-dialog never clipped by the viewport
if (displayAbove === false && enoughRoomBelow === false) {
var clippedHeight = (popupTop + popupHeight) - bottomOfViewablePage;
var optimalScrollTop = (window.pageYOffset || document.documentElement.scrollTop) + clippedHeight + SCREEN_TOP_PADDING;
var $container = $('html, body');
$container.stop().animate({
scrollTop: optimalScrollTop
}, 500);
}
//check if the popup should show up relative to the mouse
if (opts.isRelativeToMouse) {
if (diff < 0) {
popupRight = SCREEN_PADDING;
popupLeft = "auto";
arrowOffsetX = mousePosition.x - ($(window).width() - opts.width);
} else {
popupLeft = mousePosition.x - 20;
arrowOffsetX = mousePosition.x - popupLeft;
}
} else {
if (diff < 0) {
popupRight = SCREEN_PADDING;
popupLeft = "auto";
var popupRightEdge = containerWidth - popupRight;
var popupLeftEdge = popupRightEdge - popupOuterWidth;
//arrow's position must be relative to the popup's position and not of the screen.
arrowOffsetX = middleOfTrigger - popupLeftEdge - arrowWidth / 2;
}
}
return {
displayAbove: displayAbove,
popupCss: {
left: popupLeft,
right: popupRight,
top: popupTop
},
arrowCss: {
position: "absolute",
left: arrowOffsetX,
right: "auto",
top: arrowOffsetY
}
};
};
// still allow the user to override our custom calculatePositions if needed
if (!options.calculatePositions) {
options.calculatePositions = calculatePositions;
}
return AJS.InlineDialog.call(this, items, identifier, url, options);
};
});
require('confluence/module-exporter').exportModuleAsGlobal('confluence-highlight-actions/js/scrolling-inline-dialog', 'Confluence.ScrollingInlineDialog');
}catch(e){WRMCB(e)};
;
try {
/* module-key = 'com.atlassian.confluence.plugins.confluence-highlight-actions:highlighting-experiment-resources', location = 'js/highlight-ranger-helper.js' */
/**
* Provide a useful method to interact with Range
*/
define('confluence-highlight-actions/js/highlight-ranger-helper', [
'ajs',
'jquery',
'confluence/legacy',
'confluence-highlight-actions/js/doctheme-utils'
], function(
AJS,
$,
Confluence,
docThemeUtils
) {
'use strict';
/**
* Convert all non-break spaces u00a0 to normal spaces u0020
* @param {string} str string to be converted
* @returns {string} result string
*/
function convertSpaces(str) {
return str.replace(/\u00a0/g,'\u0020');
}
/*
* Given a selectionRange object and clientRects representing the highlighted text, return the first and last
* clientRect containing text accounting for browser incompatibilities
*
* @param selectionRange selected text range object
* @param clientRects browser clientRects representing the highlighted text
* @return an object containing the first and last clientRect of the highlighted text
*/
function getFirstAndLastSelectionRect(selectionRange, clientRects) {
// In Chrome triple clicking text will cause all the text in an element to be selected. When calling
// getClientRects after a triple click, the array will contain rects for each line of highlighted text
// in the highlighted element and also a clientRects for the adjacent sibling element even though no text
// is highlighted inside it. If the endOffset is zero, we ignore this final clientRect because no text
// is highlighted inside of it.
//
// Also, in Chrome, Safari and Firefox, get client rects return a clientRects representing each inline element
// including rectangles for all nested elements. IE8 return many less rects, maybe just one for the ancestor
// element containing the highlight or a clientRects for each line of highlight without individual rects for each
// inline element
var rects = {};
rects.first = clientRects[0];
rects.last = clientRects[clientRects.length - 1];
if (selectionRange.endOffset !== 'undefined') {
//In IE, if we highlight on resolved inline comment, we will length of clientRects is 1
if (selectionRange.endOffset === 0 && clientRects.length > 1) {
rects.last = clientRects[clientRects.length - 2];
}
}
return rects;
}
/*
* Returns an object representing a rectangle. the rectangle coordinates are as follows
* left: start of the text highlight
* right: either the end of the highlight of the first line or the end of the highlight of the last line, whichever is greater
* top: top of highlighted text
* bottom: bottom of highlighted text
*
* @param selectionRange range object representing the selected text
* @return rect object or false if error occurs
*/
function getSelectionRects(selectionRange) {
// if using documentation theme, get scrolltop of documentation theme content which is fixed size
// certain browsers give the scrollTop on html element, some give it on the body element. this works in both.
var scrollTop = docThemeUtils.getMainContentScrollTop();
var scrollLeft = docThemeUtils.getMainContentScrollLeft();
var clientRects = selectionRange.getClientRects();
// IE fails to provide client rects when highlighting a paragraph containing only an image or triple clicking to
// highlight any paragraph containing content other than plain text. In this case, it is safe to assume parent
// element dimensions will represent the highlighted area
if (!clientRects.length && selectionRange.parentElement()) {
var $parentElement = $(selectionRange.parentElement());
var parentOffset = $parentElement.offset();
clientRects = [{
top: parentOffset.top - scrollTop,
left: parentOffset.left - scrollLeft,
bottom: parentOffset.top + $parentElement.height(),
right: parentOffset.left + $parentElement.width()
}];
}
var rects = getFirstAndLastSelectionRect(selectionRange, clientRects);
/*
* Calculates Create Issue dialog target area
*/
var getOverlap = function(firstRect, lastRect) {
var overlap = {};
overlap.top = firstRect.top;
overlap.left = firstRect.left + scrollLeft;
overlap.bottom = lastRect.bottom;
if (firstRect.left >= lastRect.right) {
overlap.right = firstRect.right;
} else {
overlap.right = lastRect.right;
}
overlap.right = overlap.right + scrollLeft;
// adjust top for doc theme
overlap.top = overlap.top + scrollTop;
overlap.bottom = overlap.bottom + scrollTop;
// set width and height
overlap.width = overlap.right - overlap.left;
overlap.height = overlap.bottom - overlap.top;
return overlap;
};
/*
* Calculates the action panel target area
*/
var getHighlightStart = function(rect) {
var highlight = {};
highlight.width = rect.right - rect.left;
highlight.height = rect.bottom - rect.top;
highlight.left = rect.left + scrollLeft;
highlight.right = rect.right + scrollLeft;
highlight.top = rect.top + scrollTop;
highlight.bottom = rect.bottom + scrollTop;
return highlight;
};
var averageRect = getOverlap(rects.first, rects.last);
var firstRect = getHighlightStart(rects.first);
// Some Debugging output. Turn on by typing Confluence.HighlightAction.debug = true in console after page loads
if (Confluence.HighlightAction.debug) {
var $highlight_debug = $('
" + paragraphContent; editor.execCommand('mceInsertContent', false, insertContent); editorEmpty = false; } function actionCallback(selectionObject) { highlightActions.clearTextSelection(); // Need to place this in a timeout so that the panel actions have a chance to fade out before the // window scrolls, otherwise scrolling will break the fadeout behavior setTimeout(function() { var commentEditor = AJS && AJS.Rte && AJS.Rte.getEditor && AJS.Rte.getEditor(); if (commentEditor) { // If comment editor is already loaded, need to scroll the window to the comment editor when user quotes scrollWindowToEditor(); pasteQuote(commentEditor, selectionObject); } else { editorEmpty = true; // Need to trigger quick edit and paste the text when // the quick edit form visible and "quickedit.visible" event fires var handler = function() { pasteQuote(AJS.Rte.getEditor(), selectionObject); AJS.unbind('quickedit.visible', handler); }; AJS.bind('quickedit.visible', handler); activeEditor(quoteInsideComment(selectionObject.containingElement)); } }, 0); } /** * Return the comment element which contains the text is quoting * @param selectionObject * @returns {*|jQuery} */ function quoteInsideComment(containingElement) { var $commentEl = $(containingElement).closest('div.comment'); return $commentEl; } /** * Active the correct editor if commentEl is passed. If not, active editor as new comment * @param commentEl */ function activeEditor($commentEl) { if (!$commentEl.length > 0) { // Active new Editor as new comment $('.quick-comment-prompt').click(); } else { // Active editor as reply according to commentEl $commentEl.find('.comment-actions .action-reply-comment').click(); } } return { actionCallback: actionCallback }; }); require('confluence/module-exporter').safeRequire('confluence-highlight-actions/js/quote-in-comment', function(quoteInComment) { var PLUGIN_KEY = "com.atlassian.confluence.plugins.confluence-highlight-actions:quote-comment"; var ConfluenceHighlightActions = require('confluence-highlight-actions/js/highlight-actions'); ConfluenceHighlightActions.registerButtonHandler(PLUGIN_KEY, { onClick: quoteInComment.actionCallback, shouldDisplay: ConfluenceHighlightActions.WORKING_AREA.MAINCONTENT_AND_COMMENT }); }); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-highlight-actions:highlighting-experiment-resources', location = '/js/highlight-test-helper.js' */ define('confluence-highlight-actions/js/highlight-test-helper', [ 'ajs', 'window', 'confluence-highlight-actions/js/highlight-actions' ], function( AJS, window, HighlightAction ) { 'use strict'; function init() { HighlightAction.registerButtonHandler("com.atlassian.confluence.plugins.confluence-highlight-actions-test:create-JIRA-issue", { onClick: function(sel) { var dialog = new AJS.Dialog({ id : "hilightext-action-dialog", closeOnOutsideClick : true }); dialog.addHeader(sel.text); dialog.show(); }, shouldDisplay: function() { return true; } }); HighlightAction.registerButtonHandler("com.atlassian.confluence.plugins.confluence-highlight-actions-test:append-xxx", { onClick: function(sel) { var insertionBean = HighlightAction.createXMLModificationBean('XXX', sel.searchText); HighlightAction.insertContentAtSelectionEnd(insertionBean) .done(function(data) { if (data) { window.location.reload(); } else { var dialog = new AJS.Dialog({ id : "hilightext-append-xxx-dialog", closeOnOutsideClick : true }); dialog.addHeader("Cannot insert"); dialog.show(); } }); }, shouldDisplay: function() { return true; } }); HighlightAction.registerButtonHandler("com.atlassian.confluence.plugins.confluence-highlight-actions-test:insert-table-content", { onClick: function(sel) { // create insert data var cellXmlInsertions = []; for ( var i = 0; i < 3; i++) { var cellXmlInsertion = {}; cellXmlInsertion.rowIndex = i; cellXmlInsertion.xmlInsertion = "Insert content"; cellXmlInsertions.push(cellXmlInsertion); } var tableColumnIndex = 0; var tableInsertionBean = HighlightAction.createTableInsertionBean(cellXmlInsertions, tableColumnIndex, sel.searchText); HighlightAction.insertContentsInTableColumnCells(tableInsertionBean).done(function(data) { if (data) { window.location.reload(); } else { var dialog = new AJS.Dialog({ id : "hilightext-insert-table-content-dialog", closeOnOutsideClick : true }); dialog.addHeader("Cannot insert"); dialog.show(); } }); }, shouldDisplay: function() { return true; } }); } return init; }); require('confluence/module-exporter').safeRequire('confluence-highlight-actions/js/highlight-test-helper', function(highlightTestHelper) { highlightTestHelper(); }); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-highlight-actions:highlighting-experiment-resources', location = '/soy/templates.soy' */ // This file was automatically generated from templates.soy. // Please don't edit this file by hand. /** * @fileoverview Templates in namespace Confluence.HighlightPanel.Templates. */ if (typeof Confluence == 'undefined') { var Confluence = {}; } if (typeof Confluence.HighlightPanel == 'undefined') { Confluence.HighlightPanel = {}; } if (typeof Confluence.HighlightPanel.Templates == 'undefined') { Confluence.HighlightPanel.Templates = {}; } Confluence.HighlightPanel.Templates.panelContent = function(opt_data, opt_ignored) { var output = ''; var webItemList3 = opt_data.webItems; var webItemListLen3 = webItemList3.length; for (var webItemIndex3 = 0; webItemIndex3 < webItemListLen3; webItemIndex3++) { var webItemData3 = webItemList3[webItemIndex3]; output += (webItemData3['key'] == 'com.atlassian.confluence.plugins.confluence-inline-comments:create-inline-comment') ? '' : (webItemData3['key'] == 'com.atlassian.confluence.plugins.confluence-jira-content:create-JIRA-issue-summary') ? '' : ''; } return output; }; if (goog.DEBUG) { Confluence.HighlightPanel.Templates.panelContent.soyTemplateName = 'Confluence.HighlightPanel.Templates.panelContent'; } }catch(e){WRMCB(e)};" + selectionObject.html + "