2016-06-12 18:08:50 +02:00
|
|
|
'use strict';
|
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
const events = require('../events.js');
|
2016-06-12 18:08:50 +02:00
|
|
|
const misc = require('../util/misc.js');
|
|
|
|
const views = require('../util/views.js');
|
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
const template = views.getTemplate('comment-form');
|
|
|
|
|
|
|
|
class CommentFormControl extends events.EventTarget {
|
|
|
|
constructor(hostNode, comment, canCancel, minHeight) {
|
|
|
|
super();
|
2016-06-12 18:08:50 +02:00
|
|
|
this._hostNode = hostNode;
|
|
|
|
this._comment = comment || {text: ''};
|
2016-06-17 20:25:44 +02:00
|
|
|
this._canCancel = canCancel;
|
|
|
|
this._minHeight = minHeight || 150;
|
2016-06-12 18:08:50 +02:00
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
const sourceNode = template({
|
2016-06-12 18:08:50 +02:00
|
|
|
comment: this._comment,
|
|
|
|
});
|
|
|
|
|
|
|
|
const previewTabButton = sourceNode.querySelector('.buttons .preview');
|
|
|
|
const editTabButton = sourceNode.querySelector('.buttons .edit');
|
|
|
|
const formNode = sourceNode.querySelector('form');
|
|
|
|
const cancelButton = sourceNode.querySelector('.cancel');
|
|
|
|
const textareaNode = sourceNode.querySelector('form textarea');
|
|
|
|
|
|
|
|
previewTabButton.addEventListener(
|
|
|
|
'click', e => this._evtPreviewClick(e));
|
|
|
|
editTabButton.addEventListener(
|
|
|
|
'click', e => this._evtEditClick(e));
|
|
|
|
|
|
|
|
formNode.addEventListener('submit', e => this._evtSaveClick(e));
|
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
if (this._canCancel) {
|
2016-06-12 18:08:50 +02:00
|
|
|
cancelButton
|
|
|
|
.addEventListener('click', e => this._evtCancelClick(e));
|
|
|
|
} else {
|
|
|
|
cancelButton.style.display = 'none';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let event of ['cut', 'paste', 'drop', 'keydown']) {
|
|
|
|
textareaNode.addEventListener(event, e => {
|
|
|
|
window.setTimeout(() => this._growTextArea(), 0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
textareaNode.addEventListener('change', e => {
|
2016-06-17 20:25:44 +02:00
|
|
|
this.dispatchEvent(new CustomEvent('change', {
|
|
|
|
detail: {
|
|
|
|
target: this,
|
|
|
|
},
|
|
|
|
}));
|
2016-06-12 18:08:50 +02:00
|
|
|
this._growTextArea();
|
|
|
|
});
|
|
|
|
|
2016-06-14 10:31:48 +02:00
|
|
|
views.replaceContent(this._hostNode, sourceNode);
|
2016-06-12 18:08:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
enterEditMode() {
|
|
|
|
this._freezeTabHeights();
|
|
|
|
this._hostNode.classList.add('editing');
|
|
|
|
this._selectTab('edit');
|
|
|
|
this._growTextArea();
|
|
|
|
}
|
|
|
|
|
|
|
|
exitEditMode() {
|
|
|
|
this._hostNode.classList.remove('editing');
|
|
|
|
this._hostNode.querySelector('.tabs-wrapper').style.minHeight = null;
|
|
|
|
views.clearMessages(this._hostNode);
|
2016-06-12 22:33:31 +02:00
|
|
|
this.setText(this._comment.text);
|
2016-06-12 18:08:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get _textareaNode() {
|
|
|
|
return this._hostNode.querySelector('.edit.tab textarea');
|
|
|
|
}
|
|
|
|
|
|
|
|
get _contentNode() {
|
|
|
|
return this._hostNode.querySelector('.preview.tab .comment-content');
|
|
|
|
}
|
|
|
|
|
|
|
|
setText(text) {
|
|
|
|
this._textareaNode.value = text;
|
|
|
|
this._contentNode.innerHTML = misc.formatMarkdown(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
showError(message) {
|
|
|
|
views.showError(this._hostNode, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
_evtPreviewClick(e) {
|
|
|
|
e.preventDefault();
|
2016-06-12 22:10:20 +02:00
|
|
|
this._contentNode.innerHTML =
|
|
|
|
misc.formatMarkdown(this._textareaNode.value);
|
2016-06-12 18:08:50 +02:00
|
|
|
this._freezeTabHeights();
|
|
|
|
this._selectTab('preview');
|
|
|
|
}
|
|
|
|
|
|
|
|
_evtEditClick(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
this.enterEditMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
_evtSaveClick(e) {
|
|
|
|
e.preventDefault();
|
2016-06-17 20:25:44 +02:00
|
|
|
this.dispatchEvent(new CustomEvent('submit', {
|
|
|
|
detail: {
|
|
|
|
target: this,
|
|
|
|
comment: this._comment,
|
|
|
|
text: this._textareaNode.value,
|
|
|
|
},
|
|
|
|
}));
|
2016-06-12 18:08:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_evtCancelClick(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
this.exitEditMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectTab(tabName) {
|
|
|
|
this._freezeTabHeights();
|
|
|
|
for (let tab of this._hostNode.querySelectorAll('.tab, .buttons li')) {
|
|
|
|
tab.classList.toggle('active', tab.classList.contains(tabName));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_freezeTabHeights() {
|
|
|
|
const tabsNode = this._hostNode.querySelector('.tabs-wrapper');
|
|
|
|
const tabsHeight = tabsNode.getBoundingClientRect().height;
|
|
|
|
tabsNode.style.minHeight = tabsHeight + 'px';
|
|
|
|
}
|
|
|
|
|
|
|
|
_growTextArea() {
|
2016-06-12 22:10:20 +02:00
|
|
|
this._textareaNode.style.height =
|
|
|
|
Math.max(
|
2016-06-17 20:25:44 +02:00
|
|
|
this._minHeight || 0,
|
2016-06-12 18:08:50 +02:00
|
|
|
this._textareaNode.scrollHeight) + 'px';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = CommentFormControl;
|