mirror of https://github.com/xwiki-labs/cryptpad
Implement autocomplete link and mediatag
This commit is contained in:
parent
135182ea0a
commit
278b51e17e
|
@ -21,7 +21,7 @@
|
|||
"jquery": "~2.1.3",
|
||||
"tweetnacl": "0.12.2",
|
||||
"components-font-awesome": "^4.6.3",
|
||||
"ckeditor": "4.7.3",
|
||||
"ckeditor": "4.10.1",
|
||||
"codemirror": "^5.19.0",
|
||||
"requirejs": "2.3.5",
|
||||
"marked": "0.5.0",
|
||||
|
|
|
@ -10,7 +10,7 @@ CKEDITOR.editorConfig = function( config ) {
|
|||
// document itself and causes problems when it's sent across the wire and reflected back
|
||||
config.removePlugins= 'resize,elementspath';
|
||||
config.resize_enabled= false; //bottom-bar
|
||||
config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64,mathjax';
|
||||
config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64,mathjax,autocomplete,textmatch,cryptpadautocomplete';
|
||||
config.toolbarGroups= [
|
||||
// {"name":"clipboard","groups":["clipboard","undo"]},
|
||||
//{"name":"editing","groups":["find","selection"]},
|
||||
|
|
|
@ -451,6 +451,12 @@ define([
|
|||
if (!common.isLoggedIn()) { return; }
|
||||
common.initFilePicker({
|
||||
onSelect: function (data) {
|
||||
// Supporting inserting links to documents and not only mediatags
|
||||
if (data.filters.link === true) {
|
||||
mediaTagEmbedder(null, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.type !== 'file') {
|
||||
console.log("Unexpected data type picked " + data.type);
|
||||
return;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
var afterLoaded = function (req) {
|
||||
req.cfg = req.cfg || {};
|
||||
if (req.pfx) {
|
||||
reg.cfg.pfx = pfx;
|
||||
req.cfg.onNodeCreated = function (node /*, config, module, path*/) {
|
||||
node.setAttribute('src', req.pfx + node.getAttribute('src'));
|
||||
};
|
||||
|
|
|
@ -700,7 +700,8 @@ define([
|
|||
SFrameChannel: SFrameChannel,
|
||||
Utils: Utils
|
||||
};
|
||||
FP.$iframe = $('<iframe>', {id: 'sbox-filePicker-iframe'}).appendTo($('body'));
|
||||
// var iframeClasses = (typeof cfg === undefined && cfg.classes) ? cfg.classes : "";
|
||||
FP.$iframe = $('<iframe>', {id: 'sbox-filePicker-iframe' /* , class: iframeClasses */ }).appendTo($('body'));
|
||||
FP.picker = FilePicker.create(config);
|
||||
} else if (!cfg.hidden) {
|
||||
FP.$iframe.show();
|
||||
|
|
|
@ -32,7 +32,7 @@ define([
|
|||
var $body = $('body');
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var filters = metadataMgr.getPrivateData().types;
|
||||
|
||||
var origin = metadataMgr.getPrivateData().origin;
|
||||
var hideFileDialog = function () {
|
||||
sframeChan.event('EV_FILE_PICKER_CLOSE');
|
||||
};
|
||||
|
@ -45,16 +45,21 @@ define([
|
|||
var key = Hash.encodeBase64(secret.keys.cryptKey);
|
||||
sframeChan.event("EV_FILE_PICKED", {
|
||||
type: parsed.type,
|
||||
src: src,
|
||||
href: data.url,
|
||||
origin: origin,
|
||||
name: data.name,
|
||||
key: key
|
||||
src: src,
|
||||
key: key,
|
||||
filters : filters
|
||||
});
|
||||
return;
|
||||
}
|
||||
sframeChan.event("EV_FILE_PICKED", {
|
||||
type: parsed.type,
|
||||
href: data.url,
|
||||
name: data.name
|
||||
origin: origin,
|
||||
name: data.name,
|
||||
filters : filters
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -146,6 +151,12 @@ define([
|
|||
$input.focus();
|
||||
};
|
||||
common.getFilesList(filters, todo);
|
||||
if (filters.caretRect) {
|
||||
$(".cp-modal")[0].style.top = (filters.caretRect.top) + "px";
|
||||
$(".cp-modal")[0].style.left = (filters.caretRect.left) + "px";
|
||||
$(".cp-modal")[0].style.width = "500px";
|
||||
$(".cp-modal")[0].style.height = "400px";
|
||||
}
|
||||
};
|
||||
updateContainer();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
( function() {
|
||||
// For simplicity we define the plugin in the sample, but normally
|
||||
// it would be extracted to a separate file.
|
||||
CKEDITOR.plugins.add( 'cryptpadautocomplete', {
|
||||
requires: 'autocomplete,textmatch',
|
||||
init: function(editor) {
|
||||
editor.on( 'instanceReady', function() {
|
||||
var config = {};
|
||||
var view = new CKEDITOR.plugins.autocomplete.view(editor);
|
||||
var autocomplete;
|
||||
var caretRect;
|
||||
var selectionRange;
|
||||
|
||||
// Called when the user types in the editor or moves the caret.
|
||||
// The range represents the caret position.
|
||||
function textTestCallback( range ) {
|
||||
// You do not want to autocomplete a non-empty selection.
|
||||
if ( !range.collapsed ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CKEDITOR.plugins.autocomplete.selectionRange = range;
|
||||
caretRect = view.getViewPosition( range );
|
||||
// Use the text match plugin which does the tricky job of performing
|
||||
// a text search in the DOM. The "matchCallback" function should return
|
||||
// a matching fragment of the text.
|
||||
return CKEDITOR.plugins.textMatch.match( range, matchCallback );
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the position of the matching text.
|
||||
// It matches a word starting from the '#' character
|
||||
// up to the caret position.
|
||||
function matchCallback( text, offset ) {
|
||||
// Get the text before the caret.
|
||||
var left = text.slice( 0, offset ),
|
||||
// Will look for a '#' character followed by a ticket number.
|
||||
matchAt = left.match( /@\d*$/ );
|
||||
matchSlash = left.match( /\/\d*$/ );
|
||||
|
||||
if ( !matchAt && !matchSlash ) {
|
||||
return null;
|
||||
}
|
||||
// we match, but we can't use the remaining of autocomplete
|
||||
var pickerCfg = {
|
||||
types: (matchSlash) ? ['file'] : [],
|
||||
where: ['root'],
|
||||
classes: 'sbox-filePicker-iframe-inplace',
|
||||
caretRect : caretRect,
|
||||
inplace : true,
|
||||
link : (matchSlash) ? false : true
|
||||
};
|
||||
window.APP.framework._.sfCommon.openFilePicker(pickerCfg);
|
||||
return null;
|
||||
}
|
||||
|
||||
config.textTestCallback = textTestCallback;
|
||||
|
||||
// Returns (through its callback) the suggestions for the current query.
|
||||
function dataCallback( matchInfo, callback ) {
|
||||
}
|
||||
|
||||
config.dataCallback = dataCallback;
|
||||
|
||||
// Define the templates of the autocomplete suggestions dropdown and output text.
|
||||
config.itemTemplate = '<li data-id="{id}" class="issue-{type}">#{id}: {name}</li>';
|
||||
config.outputTemplate = '<a href="https://github.com/ckeditor/ckeditor-dev/issues/{id}">{name} (#{id})</a> ';
|
||||
|
||||
// Attach autocomplete to the editor.
|
||||
autocomplete = new CKEDITOR.plugins.autocomplete( editor, config );
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
|
@ -552,13 +552,29 @@ define([
|
|||
$inner.css({ background: unlocked ? '#fff' : '#eee' });
|
||||
});
|
||||
|
||||
framework.setMediaTagEmbedder(function ($mt) {
|
||||
framework.setMediaTagEmbedder(function ($mt, data) {
|
||||
//MEDIATAG
|
||||
if (data.filters.inplace===true) {
|
||||
console.log("Inplace inserting: " + JSON.stringify(data));
|
||||
var selection = editor.getSelection();
|
||||
var range = CKEDITOR.plugins.autocomplete.selectionRange;
|
||||
var crange = editor.createRange();
|
||||
crange.selectNodeContents(range.startContainer)
|
||||
crange.startOffset = range.startOffset - 1;
|
||||
crange.endOffset = range.endOffset;
|
||||
editor.getSelection().selectRanges( [crange] );
|
||||
}
|
||||
|
||||
if (data.filters.link===true) {
|
||||
var href = data.origin + data.href;
|
||||
editor.insertHtml("<a href='" + href + "'>" + data.name + "</a>", 'text' );
|
||||
} else {
|
||||
$mt.attr('contenteditable', 'false');
|
||||
//$mt.attr('tabindex', '1');
|
||||
//MEDIATAG
|
||||
var element = new window.CKEDITOR.dom.element($mt[0]);
|
||||
editor.insertElement(element);
|
||||
editor.widgets.initOn( element, 'mediatag' );
|
||||
}
|
||||
});
|
||||
|
||||
framework.setTitleRecommender(function () {
|
||||
|
@ -944,6 +960,7 @@ define([
|
|||
'import': Messages.pad_mediatagImport,
|
||||
options: Messages.pad_mediatagOptions
|
||||
};
|
||||
Ckeditor.plugins.addExternal('cryptpadautocomplete','/pad/', 'autocomplete-page-plugin.js');
|
||||
Ckeditor.plugins.addExternal('mediatag','/pad/', 'mediatag-plugin.js');
|
||||
Ckeditor.plugins.addExternal('blockbase64','/pad/', 'disable-base64.js');
|
||||
module.ckeditor = editor = Ckeditor.replace('editor1', {
|
||||
|
|
Loading…
Reference in New Issue