blob: b9ca05d65d53c1a04f808662cba6e16d77f8f52d [file] [log] [blame]
AJS.log("LinkBrowser editor plugin src starting");
// Register TinyMCE plugin
(function() {
tinymce.create('tinymce.plugins.LinkBrowser', {
init : function(ed) {
ed.addCommand('mceConflink', AJS.Editor.LinkBrowser.open);
ed.addCommand('mceConfAttachments', function () {
return AJS.Editor.LinkBrowser.open({
panelId: AJS.Editor.LinkBrowser.ATTACHMENTS_PANEL_ID
});
}); // attachments item in insert menu
ed.addButton("linkbrowserButton", {title: "confluence.conflink_desc", cmd: "mceConflink", "class": "mce_conflink" });
ed.addShortcut("ctrl+k", ed.getLang("confluence.conflink_desc"), "mceConflink");
},
getInfo : function () {
return {
longname : "Confluence Link Browser",
author : "Atlassian",
authorurl : "http://www.atlassian.com/",
version : tinymce.majorVersion + "." + tinymce.minorVersion
};
}
});
tinymce.PluginManager.add('linkbrowser', tinymce.plugins.LinkBrowser);
})();
AJS.Editor.Adapter.addTinyMcePluginInit(function(settings) {
settings.plugins += ",linkbrowser";
var buttons = settings.theme_advanced_buttons1;
var index = buttons.indexOf("confimage");
settings.theme_advanced_buttons1 = buttons.substring(0, index) + "linkbrowserButton," + buttons.substring(index);
});
AJS.Editor.LinkBrowser = (function($) {
var loadI18nThen = function (open) {
if (window.LinkBrowserI18n) {
open();
}
else {
AJS.I18n.get("com.atlassian.confluence.plugins.linkbrowser", function(i18n) {
window.LinkBrowserI18n = i18n;
open();
}, function() {
alert("There was an error loading the link browser, please try again");
});
}
return false;
},
makeRichTextLinkInfo = function (linkAlias) {
var t = AJS.Editor.LinkBrowser,
selectedNode = tinyMCE.activeEditor.selection.getNode(),
linkNode = $(selectedNode);
if (linkNode.is("a[href]")) {
var location = linkNode.attr("wikidestination");
if (location){
// for RTE links, we need to see if the alias was put there by the user or by the link renderer
// However, the user may have typed a new alias via the RTE and the aliasspecified attribute might not
// have been updated, in which case we should compare the text against the original aliases.
var alias = null;
if (linkNode.attr("aliasspecified") == "true" || linkAlias != linkNode.attr("originalalias"))
{
alias = linkNode.text();
}
t.selectedNode = selectedNode;
return t.loadRTELink(location, alias, linkNode.attr("href"));
}
}
if (linkAlias && linkAlias.length) {
return t.loadSelection(linkAlias);
}
},
makeMarkupLinkInfo = function (linkAlias) {
var t = AJS.Editor.LinkBrowser,
wikiLink = getSelectedWikiLink();
if (wikiLink) {
return t.parseWikiLink(wikiLink);
}
if (linkAlias && linkAlias.length) {
return t.loadSelection(linkAlias);
}
},
restoreSelection = function() {
if (AJS.Editor.inRichTextMode())
AJS.Editor.Adapter.restoreSelectionState();
else
restoreMarkupSelection();
},
storeMarkupSelection = function() {
var t = AJS.Editor.LinkBrowser,
textarea = $("#markupTextarea");
t.selection = textarea.selectionRange();
t.scrollTop = textarea.scrollTop();
return t.selection.text;
},
restoreMarkupSelection = function() {
var t = AJS.Editor.LinkBrowser,
textarea = $("#markupTextarea");
if (t.selection) {
textarea.selectionRange(t.selection.start, t.selection.end);
}
textarea.scrollTop(t.scrollTop);
},
getSelectedWikiLink = function() {
var t = AJS.Editor.LinkBrowser,
textarea = $("#markupTextarea");
var beforeSelection = t.selection.textBefore;
var wikiText = textarea.val();
var m = /^(?:.|\n)*[^\\](?=\[(?:\\\]|[^\]])+$)/m.exec(" " + beforeSelection + " "); // spaces required for when [ is the first or last character
if (!m) return null;
var startIndex = m[0].substring(1).length;
// now try and find the end of the link we're inside of
m = /\[((?:\\\]|[^\]])+)\]/m.exec(wikiText.substring(startIndex));
if (!m) return null;
textarea.selectionRange(startIndex, startIndex + m[0].length);
t.selection = textarea.selectionRange();
return m[1];
};
return {
ATTACHMENTS_PANEL_ID: "attachments-panel-id",
WEBLINK_PANEL_ID: "weblink-panel-id",
/**
* Loads any I18N required and then launches the dialog.
*
* If the options include an "opener" function, that is used to launch the dialog; otherwise a LinkInfo object is
* created for the current Editor and the default launcher called.
*
* @param options : panelId - (optional) a panel of the Link Browser to open to
* gwtOpener - (optional) a GWT function used to launch the Link Browser
*/
open: function(options) {
options = options || {};
return loadI18nThen(function () {
// prevent it from opening if another popup dialog is open
if ($('.aui-dialog:visible').length){
return false;
}
var linkAlias, isRTE = AJS.Editor.inRichTextMode();
// Store the current selection and scroll position, and get the selected text.
if (isRTE) {
AJS.Editor.Adapter.storeCurrentSelectionState();
linkAlias = tinyMCE.activeEditor.selection.getContent({format : 'text'});
} else {
linkAlias = storeMarkupSelection();
}
if (options.gwtOpener) {
// Any supplied opener function must include required state in its scope.
options.gwtOpener(linkAlias);
} else {
var linkInfo = isRTE ? makeRichTextLinkInfo(linkAlias) : makeMarkupLinkInfo(linkAlias);
AJS.Editor.LinkBrowser.openDialog(linkInfo, options.panelId || "");
}
// Close the Link Browser on Escape key
$(document).keydown(function (e) {
if (e.keyCode == 27 && !AJS.dropDown.current) {
AJS.Editor.LinkBrowser.fireCancelEvent();
$(document).unbind("keydown", arguments.callee);
return AJS.stopEvent(e);
}
});
});
},
// Called from GWT
cancel: function() {
restoreSelection();
AJS.Editor.LinkBrowser.selectedNode = null;
},
// Called from GWT
insert: function(destination, alias, href, aliasspecified, markup) {
restoreSelection();
if (AJS.Editor.inRichTextMode()) {
var linkDetails = {destination: destination, alias: alias, href: href, aliasspecified: aliasspecified};
AJS.Editor.Adapter.insertLink(linkDetails, AJS.Editor.LinkBrowser.selectedNode);
AJS.Editor.LinkBrowser.selectedNode = null;
}
else {
var textArea = $("#markupTextarea");
textArea.selection("[" + markup + "]");
var selection = textArea.selectionRange();
textArea.selectionRange(selection.end, selection.end);
}
},
// Called from GWT
bindUploadAttachment: function(formElement, onSubmit, onError, onSuccess) {
var form = $(formElement);
form.ajaxForm({
dataType: "json",
data: {
contentId: AJS.params.attachmentSourceContentId,
responseFormat: "html" // ensure response comes back as HTML for IE compatibility
},
resetForm: true,
beforeSubmit: function () {
onSubmit();
},
error: function (xhr) {
onError([xhr.responseText]);
},
success: function (response) {
if (response.actionErrors) {
onError(response.actionErrors);
}
else if(response.attachmentsAdded) {
onSuccess(response.attachmentsAdded);
}
}
});
form.find("input:file").change(function () { form.submit(); });
}
};})(AJS.$);
AJS.toInit(function ($) {
AJS.log("LinkBrowser editor plugin src initialising");
$("#editor-insert-link").click(function(e) {
AJS.Editor.LinkBrowser.open();
return AJS.stopEvent(e);
});
$("#markupTextarea").keyup(function (e) {
if (e.ctrlKey && e.keyCode == 75) {// bind ctrl+k to insert link
$("#editor-insert-link").click();
return AJS.stopEvent(e);
}
}).keydown(function (e) {
// prevent firefox's default behaviour
if (e.ctrlKey && e.keyCode == 75) {
return AJS.stopEvent(e);
}
});
});