Commit 58852778 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'F7783FormElementCodeAnnotation'

parents 88795cdd 78a8a4b2
Pipeline #1467 passed with stage
in 2 minutes and 9 seconds
......@@ -3169,9 +3169,9 @@ abstract class AbstractBuildForm {
throw new UserFormException("Missing parameter '" . FE_TEXT_SOURCE . "'", ERROR_IO_READ_FILE);
}
if ($formElement[FE_TEXT_SOURCE] != '' && !is_readable($formElement[FE_TEXT_SOURCE])) {
throw new UserFormException("Error reading file: " . $formElement[FE_TEXT_SOURCE], ERROR_IO_READ_FILE);
}
# if ($formElement[FE_TEXT_SOURCE] != '' && !is_readable($formElement[FE_TEXT_SOURCE])) {
# throw new UserFormException("Error reading file: " . $formElement[FE_TEXT_SOURCE], ERROR_IO_READ_FILE);
# }
if (!empty($value) && json_decode($value) === null) {
throw new UserFormException("Annotate data: JSON structure not valid", ERROR_BROKEN_JSON_STRUCTURE);
......
......@@ -54,11 +54,12 @@ var QfqNS = QfqNS || {};
this.data = {
url: this.$parent.data("file"),
text: this.$parent.data("text")
};
this.page = page;
this.language = this.$parent.data("highlight") || "typo3conf/ext/qfq/Resources/Public/Json/javascript.json";
console.log(this.data);
this.currentUser = $container.data("uid");
console.log(this.currentUser);
var that = this;
if (this.$target.val()) {
var jImport = $.parseJSON(this.$target.val());
......@@ -72,6 +73,7 @@ var QfqNS = QfqNS || {};
}
}
if (this.data.url) {
// Get data of a file and write it to data.text
$.get(this.data.url, function(response) {
......@@ -238,9 +240,102 @@ var QfqNS = QfqNS || {};
commentController.on('comment.added', function(argument) {
console.log("Catch event: " + that.annotations.length);
console.log("With data: " + argument.data);
that._handleNew(argument.data);
});
commentController.on('comment.edited', function() {
that._updateJSON();
});
commentController.on('comment.removed', function(e) {
console.log(e);
if(that._checkUserRemoval(e.data.uid)) {
console.log("Removed User uid: " + e.data.uid);
}
that._checkLineRemoval();
that._updateJSON();
});
};
n.CodeCorrection.prototype._checkLineRemoval = function() {
var removeLines = [];
for (var i = 0; i < this.annotations.length; i++) {
var comments = this.annotations[i].commentController.exportComments();
if(comments.length == 0) {
removeLines.push(i);
}
}
for (var ii = 0; ii < removeLines.length; ii++) {
this.annotations.splice(removeLines[ii], 1);
}
};
n.CodeCorrection.prototype._handleNew = function(eventData) {
this._addCurrentUser();
this._updateJSON();
};
n.CodeCorrection.prototype._checkUserRemoval = function(uid) {
var removeUser = true;
for (var i = 0; i < this.annotations.length; i++) {
var comments = this.annotations[i].commentController.exportComments();
for (var ii = 0; ii < comments.length; ii++) {
if(comments[ii].uid === uid) {
removeUser = false;
return false;
}
}
}
if (removeUser) {
for (var iii = 0; iii < this.users.length; iii++) {
if (this.users[iii].uid === uid) {
this.users.splice(i, 1);
}
}
}
return true;
};
n.CodeCorrection.prototype._addCurrentUser = function() {
if (!this.checkUserExists(this.currentUser.uid)) {
this.users.push(this.currentUser);
}
};
n.CodeCorrection.prototype.checkUserExists = function(uid) {
for (var i = 0; i < this.users.length; i++) {
if (this.users[i].uid === uid) {
return true;
}
}
return false;
};
n.CodeCorrection.prototype._updateJSON = function() {
var jexport = {};
jexport.annotations = [];
for (var i = 0; i < this.annotations.length; i++) {
var annotation = {
lineNumber: this.annotations[i].lineNumber,
comments: this.annotations[i].commentController.exportComments()
};
jexport.annotations.push(annotation);
}
jexport.users = this.users;
this.$target.val(JSON.stringify(jexport));
var that = this;
if (this.page.qfqForm) {
this.page.qfqForm.eventEmitter.emitEvent('form.changed',
n.EventEmitter.makePayload(that, null));
this.page.qfqForm.changeHandler();
this.page.qfqForm.form.formChanged = true;
} else {
console.log(this.page);
throw("Error: Couldn't initialize qfqForm - not possible to send form.changed event");
}
};
/**
* Places a comment editor under the hook.
......@@ -258,8 +353,8 @@ var QfqNS = QfqNS || {};
comments.lineNumber = lineCount;
comments.commentController = new n.CommentController();
comments.commentController.buildContainer($hook);
comments.commentController.displayEditor();
comments.commentController.setCurrentUser(this.currentUser);
comments.commentController.displayEditor();
this._setListeners(comments.commentController);
this.annotations.push(comments);
}
......@@ -296,5 +391,4 @@ var QfqNS = QfqNS || {};
return false;
};
})(QfqNS);
\ No newline at end of file
......@@ -28,14 +28,19 @@ var QfqNS = QfqNS || {};
this.user = user;
this.$parent = $container;
this.$comment = {};
if (arguments.length == 3) {
this.$text = {};
if (arguments.length === 3) {
this.options = { readonly: false };
} else {
this.options = options;
}
this.childrenController = {};
this.eventEmitter = new EventEmitter();
this.deleted = false;
};
n.Comment.prototype.on = n.EventEmitter.onMixin;
n.Comment.prototype.display = function() {
var displayElement;
displayElement = this._buildComment();
......@@ -73,19 +78,85 @@ var QfqNS = QfqNS || {};
}).appendTo($topLine);
$topLine.appendTo($commentWrap);
var $comment = $('<div />', {
class: "qfqCommentText",
class: "qfqCommentText"
});
$comment.html(this.comment.comment);
$comment.append(this._getCommands());
this.$text= $comment;
$comment.appendTo($commentWrap);
return $commentWrap;
};
n.Comment.prototype._updateText = function(text) {
this.$text.html(text);
this.$text.append(this._getCommands());
};
n.Comment.prototype._getCommands = function () {
var $commentCommands = $("<div />", {
class: "qfqCommentCommands"
});
var $reply = $('<span />', {
class: "glyphicon glyphicon-comment qfqCommentReply"
var that = this;
$commentCommands.append(this._getCommand("Edit", "pencil", function(e) {
that._editMe(e);
}));
$commentCommands.append(this._getCommand("Delete", "trash", function(e) {
that._deleteMe(e);
}));
$commentCommands.append(this._getCommand("Reply", "comment", function(e) {
that._replyToMe(e);
}));
return $commentCommands;
};
n.Comment.prototype._getCommand = function(description, icon, onClick) {
var $command = $('<span />', {
class: "glyphicon glyphicon-" + icon + " qfqCommentCommand",
title: description
});
$reply.appendTo($commentCommands);
$commentCommands.appendTo($comment);
$comment.appendTo($commentWrap);
return $commentWrap;
$command.bind("click", this, onClick);
return $command;
};
n.Comment.prototype._deleteMe = function(e) {
console.log("Delete pressed for:");
console.log(this.comment);
this.deleted = true;
this.$comment.remove();
this.eventEmitter.emitEvent('comment.deleted',
n.EventEmitter.makePayload(this, this.comment));
};
n.Comment.prototype._editMe = function(e) {
console.log("Edit pressed for:");
console.log(this.comment);
this.$comment.hide();
var that = this;
var editor = new QfqNS.Editor();
var $editor = editor.buildEditor(this.comment.comment);
editor.on("editor.submit", function(e) {
that._updateComment(e);
});
this.$comment.after($editor);
};
n.Comment.prototype._replyToMe = function(e) {
console.log("Reply to me:");
console.log(this.comment);
console.log(e);
this.eventEmitter.emitEvent('comment.reply',
n.EventEmitter.makePayload(this, this.comment));
};
n.Comment.prototype._updateComment = function(e) {
console.log(e);
this.comment.comment = e.data.text;
this._updateText(e.data.text);
this.$comment.show();
e.data.$container.remove();
this.eventEmitter.emitEvent('comment.edited',
n.EventEmitter.makePayload(this, this.comment));
};
})(QfqNS);
\ No newline at end of file
......@@ -46,7 +46,7 @@ var QfqNS = QfqNS || {};
* @param event String containing possible change states
* @return {boolean} true on success
*/
n.CommentController.prototype._changeHandler = function(event) {
n.CommentController.prototype._changeHandler = function(event, comment) {
if (event === "edit") {
this.eventEmitter.emitEvent('comment.edited',
n.EventEmitter.makePayload(this, "edit"));
......@@ -54,12 +54,12 @@ var QfqNS = QfqNS || {};
return true;
} else if (event === "new") {
this.eventEmitter.emitEvent('comment.added',
n.EventEmitter.makePayload(this, "add"));
n.EventEmitter.makePayload(this, comment));
console.log("[CommentController] Event comment.add emitted");
return true;
} else if (event === "remove") {
this.eventEmitter.emitEvent('comment.removed',
n.EventEmitter.makePayload(this, "remove"));
n.EventEmitter.makePayload(this, comment));
}
console.error("[CommentController] Changehandler called without valid event");
return false;
......@@ -102,11 +102,25 @@ var QfqNS = QfqNS || {};
var commentObject = new n.Comment(comment, user, this.$container);
commentObject.display();
this.comments.push(commentObject);
this._changeHandler("new");
this._changeHandler("new", commentObject);
this._setListeners(commentObject);
this.updateHeight();
return this.comments.length - 1;
};
n.CommentController.prototype._setListeners = function(commentObject) {
var that = this;
commentObject.on('comment.edited', function(e) {
that.updateComment(e.data);
});
commentObject.on('comment.reply', function(e) {
that.requestReply(e.data);
});
commentObject.on('comment.deleted', function(e) {
that.removeComment(e);
});
};
n.CommentController.prototype.displayComments = function() {
for (var i = 0; this.comments; i++) {
this.comments[i].display();
......@@ -122,6 +136,7 @@ var QfqNS = QfqNS || {};
that._handleEditorSubmit(editor);
});
$editor.appendTo(this.$container);
editor.$textArea.focus();
};
n.CommentController.prototype._handleEditorSubmit = function(editor) {
......@@ -143,11 +158,17 @@ var QfqNS = QfqNS || {};
};
n.CommentController.prototype.removeComment = function(reference) {
this._changeHandler("remove", reference);
};
n.CommentController.prototype.updateComment = function(reference, data) {
n.CommentController.prototype.updateComment = function(data) {
console.log("[Comment Changed] User: " + data.uid +
" Text:" + data.comment.substring(0, 20) + "...");
this.emitEvent("edit");
};
n.CommentController.prototype.requestReply = function(data) {
this.displayEditor();
};
n.CommentController.prototype.updateHeight = function() {
......@@ -160,7 +181,19 @@ var QfqNS = QfqNS || {};
var user = this._searchUsersByUid(users, comments[i].uid);
this.addComment(comments[i], user);
}
this.displayEditor();
if (comments.length === 0) {
this.displayEditor();
}
};
n.CommentController.prototype.exportComments = function() {
var comments = [];
for(var i=0; i < this.comments.length; i++) {
if (!this.comments[i].deleted) {
comments.push(this.comments[i].comment);
}
}
return comments;
};
n.CommentController.prototype._searchUsersByUid = function (users, uid) {
......
......@@ -33,15 +33,20 @@ var QfqNS = QfqNS || {};
n.Editor.prototype.on = n.EventEmitter.onMixin;
n.Editor.prototype.buildEditor = function() {
n.Editor.prototype.buildEditor = function(text) {
var that = this;
this.$container = $("<div />", {
class: "qfqEditorContainer"
});
this.$textArea = $("<div />", {
class: "qfqEditor",
contenteditable: true
contenteditable: true,
tabindex: 0
});
if (text) {
this.$textArea.html(text);
}
this.$textArea.keydown(function() { that.activateSubmit(); });
this._addEditorControls();
var controls = $("<div />", {
......
......@@ -89,9 +89,9 @@ var QfqNS = QfqNS || {};
this.qfqForm = null;
}
var page = this;
// Initialize Fabric to access form events
try {
var page = this;
$(".annotate-graphic").each(function() {
var qfqFabric = new QfqNS.Fabric();
qfqFabric.initialize($(this), page);
......
......@@ -497,6 +497,7 @@ select.qfq-locked:invalid {
};
.qfqLineCount {
user-select: none;
width: 50px;
height: 100%;
text-align: right;
......@@ -590,11 +591,12 @@ select.qfq-locked:invalid {
text-align: right;
}
.qfqCommentReply {
.qfqCommentCommand {
cursor: pointer;
margin-left: 9px;
}
.qfqCommentReply:hover {
.qfqCommentCommand:hover {
color: #9acfea;
}
......
......@@ -14,7 +14,7 @@
</head>
<body style="background-color: #f5f5f5;">
<div class="container-fluid">
<div class="row">
<div class="row">
<div class="col-md-10 ">
<div class="btn-toolbar pull-right" role="toolbar">
<div class="btn-group" role="group">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment