new text editor: tinyMCE
This commit is contained in:
39
files/db/update_v4_to_v5.sql
Normal file
39
files/db/update_v4_to_v5.sql
Normal file
File diff suppressed because one or more lines are too long
12
inc/catc.php
12
inc/catc.php
@@ -130,6 +130,13 @@ class CATC extends Main
|
|||||||
|
|
||||||
/* Notes*/
|
/* Notes*/
|
||||||
|
|
||||||
|
public function getNoteOld($iCourseId) {
|
||||||
|
$oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId);
|
||||||
|
$asNote = $oNote->getNoteOld();
|
||||||
|
|
||||||
|
return self::getJsonResult(!empty($asNote), '', $asNote);
|
||||||
|
}
|
||||||
|
|
||||||
public function getNote($iCourseId) {
|
public function getNote($iCourseId) {
|
||||||
$oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId);
|
$oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId);
|
||||||
$asNote = $oNote->getNote();
|
$asNote = $oNote->getNote();
|
||||||
@@ -137,10 +144,9 @@ class CATC extends Main
|
|||||||
return self::getJsonResult(!empty($asNote), '', $asNote);
|
return self::getJsonResult(!empty($asNote), '', $asNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setNote($iCourseId, $asOps) {
|
public function setNote($iCourseId, $sNotes) {
|
||||||
if(is_string($asOps)) $asOps = json_decode($asOps, true);
|
|
||||||
$oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId);
|
$oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId);
|
||||||
$sError = $oNote->setNote($asOps);
|
$sError = $oNote->setNote($sNotes);
|
||||||
$bSuccess = ($sError=='');
|
$bSuccess = ($sError=='');
|
||||||
|
|
||||||
$asData = ($bSuccess)?array('led_time' => $oNote->getNote()['led_time']):array();
|
$asData = ($bSuccess)?array('led_time' => $oNote->getNote()['led_time']):array();
|
||||||
|
|||||||
18
inc/note.php
18
inc/note.php
@@ -35,10 +35,10 @@ class Note extends PhpObject {
|
|||||||
return array(Db::getId(Auth::USER_TABLE) => $this->iUserId, Db::getId(Course::COURSE_TABLE) => $this->iCourseId);
|
return array(Db::getId(Auth::USER_TABLE) => $this->iUserId, Db::getId(Course::COURSE_TABLE) => $this->iCourseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNote() {
|
public function getNoteOld() {
|
||||||
$asCourse = $this->oDb->selectRow(self::NOTE_TABLE, $this->getNoteKeys());
|
$asCourse = $this->oDb->selectRow(self::NOTE_TABLE, $this->getNoteKeys());
|
||||||
if(!empty($asCourse)) {
|
if(!empty($asCourse)) {
|
||||||
$asCourse['notes'] = json_decode($asCourse['notes'], true);
|
$asCourse['notes'] = json_decode($asCourse['notes_old'], true);
|
||||||
$asCourse['led_date'] = date('d/m/Y', strtotime($asCourse['led']));
|
$asCourse['led_date'] = date('d/m/Y', strtotime($asCourse['led']));
|
||||||
$asCourse['led_time'] = date('H:i');
|
$asCourse['led_time'] = date('H:i');
|
||||||
}
|
}
|
||||||
@@ -46,11 +46,21 @@ class Note extends PhpObject {
|
|||||||
return $asCourse;
|
return $asCourse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setNote($asOps) {
|
public function getNote() {
|
||||||
|
$asCourse = $this->oDb->selectRow(self::NOTE_TABLE, $this->getNoteKeys());
|
||||||
|
if(!empty($asCourse)) {
|
||||||
|
$asCourse['led_date'] = date('d/m/Y', strtotime($asCourse['led']));
|
||||||
|
$asCourse['led_time'] = date('H:i');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $asCourse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNote($sNotes) {
|
||||||
$sError = '';
|
$sError = '';
|
||||||
|
|
||||||
if($this->iUserId > 0 && $this->iCourseId > 0) {
|
if($this->iUserId > 0 && $this->iCourseId > 0) {
|
||||||
$asData = array_merge($this->getNoteKeys(), array('notes'=>json_encode($asOps)));
|
$asData = array_merge($this->getNoteKeys(), array('notes'=>$sNotes));
|
||||||
$iNoteId = $this->oDb->insertUpdateRow(self::NOTE_TABLE, $asData, array_keys($this->getNoteKeys()));
|
$iNoteId = $this->oDb->insertUpdateRow(self::NOTE_TABLE, $asData, array_keys($this->getNoteKeys()));
|
||||||
if(!$iNoteId) $sError = $this->oDb->getLastError();
|
if(!$iNoteId) $sError = $this->oDb->getLastError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ elseif($sAction!='' && $bLoggedIn)
|
|||||||
{
|
{
|
||||||
switch ($sAction)
|
switch ($sAction)
|
||||||
{
|
{
|
||||||
|
case 'get_note_old':
|
||||||
|
$sResult = $oCATC->getNoteOld($iId);
|
||||||
|
break;
|
||||||
case 'get_note':
|
case 'get_note':
|
||||||
$sResult = $oCATC->getNote($iId);
|
$sResult = $oCATC->getNote($iId);
|
||||||
break;
|
break;
|
||||||
|
|||||||
247
masks/convert.html
Normal file
247
masks/convert.html
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
<div id="convert" class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><a id="prev">Previous</a></div>
|
||||||
|
<div class="col"><a id="next">next</a></div>
|
||||||
|
<div class="col"><a id="res">Result</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div id="notes_feedback"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row h-100">
|
||||||
|
<div class="col w-50"><div id="notes_old"></div></div>
|
||||||
|
<div class="col w-50"><textarea id="tiny"></textarea></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="scripts/quill.min.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/quill.mods.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
Quill.register({'modules/better-table': quillBetterTable}, true);
|
||||||
|
|
||||||
|
class Editor {
|
||||||
|
constructor(sEditorId, bReadOnly) {
|
||||||
|
this.keystrokes = 0;
|
||||||
|
this.readOnly = bReadOnly || false;
|
||||||
|
this.sCursorPos = '';
|
||||||
|
|
||||||
|
//DOM Elements
|
||||||
|
this.$Editor = $(sEditorId);
|
||||||
|
|
||||||
|
this.onKeyStroke = function() {};
|
||||||
|
|
||||||
|
this.oQuill = new Quill(sEditorId, {
|
||||||
|
theme: 'snow',
|
||||||
|
placeholder: 'Notes',
|
||||||
|
readOnly: bReadOnly,
|
||||||
|
modules: {
|
||||||
|
table: false,
|
||||||
|
'better-table': {
|
||||||
|
operationMenu: {
|
||||||
|
items: {
|
||||||
|
mergeCells: false,
|
||||||
|
unmergeCells: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keyboard: {
|
||||||
|
bindings: quillBetterTable.keyboardBindings
|
||||||
|
},
|
||||||
|
toolbar: [
|
||||||
|
['bold', 'italic', 'underline', 'strike'],
|
||||||
|
//['blockquote', 'code-block'],
|
||||||
|
[{ 'color': [] }, { 'background': [] }],
|
||||||
|
[{ 'header': 1 }, { 'header': 2 }, 'blockquote'],
|
||||||
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||||
|
//[{ 'script': 'sub'}, { 'script': 'super' }],
|
||||||
|
//[{ 'indent': '-1'}, { 'indent': '+1' }],
|
||||||
|
//[{ 'direction': 'rtl' }],
|
||||||
|
//[{ 'size': ['small', false, 'large', 'huge'] }],
|
||||||
|
//[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
||||||
|
//[{ 'font': [] }],
|
||||||
|
[{ 'align': [] }],
|
||||||
|
['table'],
|
||||||
|
['link', 'image'],
|
||||||
|
['clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var oToolbar = this.oQuill.getModule('toolbar');
|
||||||
|
oToolbar.addHandler('table', () => {
|
||||||
|
let tableModule = this.oQuill.getModule('better-table');
|
||||||
|
tableModule.insertTable(3, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._initEvents();
|
||||||
|
this._postInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
_initEvents() {
|
||||||
|
//Key strokes
|
||||||
|
this.$Editor.keydown((e) => {
|
||||||
|
if($.inArray(e.which, [13, 37, 38, 39, 40]) == -1) this.onKeyStroke(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
//On text modification
|
||||||
|
this.oQuill.on('text-change', (delta, oldDelta, sSource) => {this._incKeyStrokes();});
|
||||||
|
}
|
||||||
|
|
||||||
|
_postInit(iPage) {
|
||||||
|
if(!this.readOnly) this.oQuill.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
_incKeyStrokes() {
|
||||||
|
this.keystrokes += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
getContent() {
|
||||||
|
return this.oQuill.getContents().ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
setContent(asOps) {
|
||||||
|
this.oQuill.setContents(asOps);
|
||||||
|
this._postInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
const rEmpty = /^(<p>(<br>|<br\/>|<br\s\/>|\s+|)<\/p>|)$/gm;
|
||||||
|
return rEmpty.test(this.oQuill.getText().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
quill2Html(asDelta) {
|
||||||
|
var tempCont = document.createElement('div');
|
||||||
|
(new Quill(tempCont)).setContents(asDelta);
|
||||||
|
return tempCont.getElementsByClassName('ql-editor')[0].innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
oCATC.pageInit = function(asHash, bFirstPage) {
|
||||||
|
self.tmp('id_course', asHash.items[0]);
|
||||||
|
|
||||||
|
$('#prev').attr('href', '#convert-'+(parseInt(self.tmp('id_course')) - 1));
|
||||||
|
$('#next').attr('href', '#convert-'+(parseInt(self.tmp('id_course')) + 1));
|
||||||
|
$('#res').attr('href', '#course-'+(self.tmp('id_course')));
|
||||||
|
|
||||||
|
//Setup Quill
|
||||||
|
oEditor = new Editor('#notes_old');
|
||||||
|
oEditor.onKeyStroke = (e) => {
|
||||||
|
if(e.which == 83 && e.ctrlKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
save(true);
|
||||||
|
}
|
||||||
|
else save();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Setup TinyMCE (new)
|
||||||
|
tinymce.init({
|
||||||
|
selector: '#tiny',
|
||||||
|
menubar: false,
|
||||||
|
height: "10000px",
|
||||||
|
plugins: [
|
||||||
|
'advlist autolink lists link image charmap print preview anchor',
|
||||||
|
'searchreplace visualblocks code fullscreen',
|
||||||
|
'insertdatetime media table paste save'
|
||||||
|
],
|
||||||
|
toolbar:
|
||||||
|
'save | '+
|
||||||
|
'formatselect | '+
|
||||||
|
'bold italic underline strikethrough forecolor | '+
|
||||||
|
'alignleft aligncenter alignright alignjustify | '+
|
||||||
|
'bullist numlist outdent indent | '+
|
||||||
|
'link table image | '+
|
||||||
|
'removeformat',
|
||||||
|
save_onsavecallback: function(oEditor) { save(true); },
|
||||||
|
content_style: 'body{font-family:Helvetica,Arial,sans-serif; font-size:13px;} p{margin:0; padding:0;}',
|
||||||
|
setup: function(ed) {
|
||||||
|
ed.on('init', function(e) {
|
||||||
|
//Load notes (old)
|
||||||
|
Tools.ajax(
|
||||||
|
'get_note_old',
|
||||||
|
(asData) => {
|
||||||
|
oEditor.setContent(asData.notes);
|
||||||
|
|
||||||
|
$Content = $('.ql-editor').clone();
|
||||||
|
$($Content.find('ol li[data-list=bullet]').removeAttr('data-list').parent().get().reverse()).each(function(iKey, oElem) {
|
||||||
|
$(this).replaceWith($('<ul>'+$(this).html()+'</ul>'));
|
||||||
|
});
|
||||||
|
|
||||||
|
tinymce.activeEditor.setContent($Content.html());
|
||||||
|
save(true);
|
||||||
|
},
|
||||||
|
{id: self.tmp('id_course')},
|
||||||
|
() => {console.log('Note not found for course ID = '+self.tmp('id_course'))}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
oCATC.onSamePageMove = function(asHash) {
|
||||||
|
location.reload();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function noteFeedback(sType, sMsg) {
|
||||||
|
var $Feedback = $('#notes_feedback');
|
||||||
|
if(sMsg != $Feedback.find('.alert').text()) {
|
||||||
|
$Feedback.finish().fadeOut($Feedback.is(':empty')?0:'fast', function(){
|
||||||
|
$(this)
|
||||||
|
.empty()
|
||||||
|
.append($('<div>', {'class':'alert note-'+sType}).text(sMsg))
|
||||||
|
.fadeIn('fast')
|
||||||
|
.delay(5000)
|
||||||
|
.fadeOut('fast');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function save(bForce, bOnUnload) {
|
||||||
|
bForce = bForce || false;
|
||||||
|
bOnUnload = bOnUnload || false;
|
||||||
|
if(bOnUnload) bForce = true;
|
||||||
|
|
||||||
|
if(typeof oSaveTimer != 'undefined') clearTimeout(oSaveTimer);
|
||||||
|
var bSave = (/*oEditor.keystrokes % 20 == 0 || */bForce);
|
||||||
|
|
||||||
|
if(bSave) {
|
||||||
|
if(self.tmp('saving') && !bOnUnload) {
|
||||||
|
oSaveTimer = setTimeout(function(){save(true);}, 500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var sContent = tinymce.activeEditor.getContent();
|
||||||
|
if(self.tmp('id_course') != 0) {
|
||||||
|
self.tmp('saving', true);
|
||||||
|
noteFeedback('info', 'Saving...');
|
||||||
|
Tools.ajax(
|
||||||
|
'set_note',
|
||||||
|
function(asData) {
|
||||||
|
self.tmp('saving', false);
|
||||||
|
var sMsg = 'Note saved ('+asData.led_time+')';
|
||||||
|
if($.type(noteFeedback)=='function') noteFeedback('notice', sMsg);
|
||||||
|
else oCATC.feedback('success', sMsg);
|
||||||
|
},
|
||||||
|
{id: self.tmp('id_course'), content: sContent},
|
||||||
|
function(sError) {
|
||||||
|
self.tmp('saving', false);
|
||||||
|
var sMsg = 'Not saved! An error occured: '+sError;
|
||||||
|
if($.type(noteFeedback)=='function') noteFeedback('error', sMsg);
|
||||||
|
else oCATC.feedback('error', sMsg);
|
||||||
|
oSaveTimer = setTimeout(save, 1000);
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
'POST',
|
||||||
|
'json',
|
||||||
|
bOnUnload
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else noteFeedback('error', 'No Course ID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oSaveTimer = setTimeout(function(){save(true);}, 1000*5);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="notes_box" class="col-9 h-100">
|
<div id="notes_box" class="col-9 h-100">
|
||||||
<div id="notes_feedback"></div>
|
<div id="notes_feedback"></div>
|
||||||
<div id="notes"></div>
|
<form id="notes" method="post"><textarea id="tiny"></textarea></form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="template-items">
|
<div class="template-items">
|
||||||
@@ -31,27 +31,40 @@ oCATC.pageInit = function(asHash, bFirstPage) {
|
|||||||
//Setup layout
|
//Setup layout
|
||||||
self.setPageTitle(self.consts.courses[self.tmp('id_course')].description);
|
self.setPageTitle(self.consts.courses[self.tmp('id_course')].description);
|
||||||
|
|
||||||
//Setup Quill
|
//Setup TinyMCE
|
||||||
oEditor = new Editor('#notes');
|
tinymce.init({
|
||||||
oEditor.onKeyStroke = (e) => {
|
selector: '#tiny',
|
||||||
if(e.which == 83 && e.ctrlKey) {
|
height: '100%',
|
||||||
e.preventDefault();
|
menubar: false,
|
||||||
save(true);
|
plugins: [
|
||||||
}
|
'advlist autolink lists link image charmap print preview anchor',
|
||||||
else save();
|
'searchreplace visualblocks code fullscreen',
|
||||||
};
|
'insertdatetime media table paste autosave save hr'
|
||||||
//oQuill.keyboard.addBinding({key: 'S', ctrlKey: true}, function(){saveNotes(true);});
|
],
|
||||||
|
toolbar:
|
||||||
//Load notes
|
'save undo redo | '+
|
||||||
|
'formatselect | '+
|
||||||
|
'bold italic underline strikethrough forecolor | '+
|
||||||
|
'alignleft aligncenter alignright alignjustify | '+
|
||||||
|
'bullist numlist outdent indent hr | '+
|
||||||
|
'link table image | '+
|
||||||
|
'removeformat',
|
||||||
|
save_onsavecallback: function(oEditor) { save(true); },
|
||||||
|
autosave_interval: "10s",
|
||||||
|
setup: function(ed) {
|
||||||
|
ed.on('init', function(e) {
|
||||||
Tools.ajax(
|
Tools.ajax(
|
||||||
'get_note',
|
'get_note',
|
||||||
(asData) => {
|
(asData) => {
|
||||||
oEditor.setContent(asData.notes);
|
tinymce.activeEditor.setContent(asData.notes);
|
||||||
noteFeedback('notice', 'Last update at '+asData.led_time+' on '+asData.led_date);
|
noteFeedback('notice', 'Last update at '+asData.led_time+' on '+asData.led_date);
|
||||||
},
|
},
|
||||||
{id: self.tmp('id_course')},
|
{id: self.tmp('id_course')},
|
||||||
() => {console.log('Note not found for course ID = '+self.tmp('id_course'))}
|
() => {console.log('Note not found for course ID = '+self.tmp('id_course'))}
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//Setup File Upload
|
//Setup File Upload
|
||||||
$('#fileupload')
|
$('#fileupload')
|
||||||
@@ -85,7 +98,7 @@ oCATC.pageInit = function(asHash, bFirstPage) {
|
|||||||
loadDocs();
|
loadDocs();
|
||||||
|
|
||||||
//Scrollbar
|
//Scrollbar
|
||||||
$('#doc_list_box, #notes').mCustomScrollbar({
|
$('#doc_list_box').mCustomScrollbar({
|
||||||
axis: 'y',
|
axis: 'y',
|
||||||
scrollInertia: 0,
|
scrollInertia: 0,
|
||||||
autoExpandScrollbar: true,
|
autoExpandScrollbar: true,
|
||||||
@@ -93,6 +106,10 @@ oCATC.pageInit = function(asHash, bFirstPage) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oCATC.onSamePageMove = function(asHash) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
oCATC.onQuitPage = function(sExitMode) {
|
oCATC.onQuitPage = function(sExitMode) {
|
||||||
return save(true, (sExitMode==self.consts.exitmodes.closing));
|
return save(true, (sExitMode==self.consts.exitmodes.closing));
|
||||||
};
|
};
|
||||||
@@ -148,14 +165,14 @@ function save(bForce, bOnUnload) {
|
|||||||
if(bOnUnload) bForce = true;
|
if(bOnUnload) bForce = true;
|
||||||
|
|
||||||
if(typeof oSaveTimer != 'undefined') clearTimeout(oSaveTimer);
|
if(typeof oSaveTimer != 'undefined') clearTimeout(oSaveTimer);
|
||||||
var bSave = (oEditor.keystrokes % 20 == 0 || bForce);
|
var bSave = (/*oEditor.keystrokes % 20 == 0 || */bForce); //FIXME: redo auto save
|
||||||
|
|
||||||
if(bSave) {
|
if(bSave) {
|
||||||
if(self.tmp('saving') && !bOnUnload) {
|
if(self.tmp('saving') && !bOnUnload) {
|
||||||
oSaveTimer = setTimeout(function(){save(true);}, 500);
|
oSaveTimer = setTimeout(function(){save(true);}, 500);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var sContent = oEditor.getContent();
|
var sContent = tinymce.activeEditor.getContent();
|
||||||
if(self.tmp('id_course') != 0) {
|
if(self.tmp('id_course') != 0) {
|
||||||
self.tmp('saving', true);
|
self.tmp('saving', true);
|
||||||
noteFeedback('info', 'Saving...');
|
noteFeedback('info', 'Saving...');
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
<script type="text/javascript" src="scripts/jquery.min.js"></script>
|
<script type="text/javascript" src="scripts/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="scripts/bootstrap.bundle.min.js"></script>
|
<script type="text/javascript" src="scripts/bootstrap.bundle.min.js"></script>
|
||||||
<script type="text/javascript" src="scripts/jquery.mods.js"></script>
|
<script type="text/javascript" src="scripts/jquery.mods.js"></script>
|
||||||
<script type="text/javascript" src="scripts/quill.min.js"></script>
|
<script type="text/javascript" src="scripts/tinymce/tinymce.min.js"></script>
|
||||||
<script type="text/javascript" src="scripts/quill.mods.js"></script>
|
<script type="text/javascript" src="scripts/tinymce/jquery.tinymce.min.js"></script>
|
||||||
<script type="text/javascript" src="[#]filepath_js_common[#]"></script>
|
<script type="text/javascript" src="[#]filepath_js_common[#]"></script>
|
||||||
<script type="text/javascript" src="[#]filepath_js_catc[#]"></script>
|
<script type="text/javascript" src="[#]filepath_js_catc[#]"></script>
|
||||||
<link rel="icon" type="image/png" href="images/favicon.png">
|
<link rel="icon" type="image/png" href="images/favicon.png">
|
||||||
|
|||||||
100
scripts/catc.js
100
scripts/catc.js
@@ -354,6 +354,7 @@ function CATC(asGlobals)
|
|||||||
//Officially a new page
|
//Officially a new page
|
||||||
var bFirstPage = (sCurrPage == '');
|
var bFirstPage = (sCurrPage == '');
|
||||||
self.vars('page', sNextPage);
|
self.vars('page', sNextPage);
|
||||||
|
self.setPageTitle('');
|
||||||
|
|
||||||
//Update Page Title
|
//Update Page Title
|
||||||
var sDetail = asHash.items[0] || '';
|
var sDetail = asHash.items[0] || '';
|
||||||
@@ -431,102 +432,3 @@ function CATC(asGlobals)
|
|||||||
return $('.template-items').find('.'+sItemName).clone();
|
return $('.template-items').find('.'+sItemName).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Quill.register({'modules/better-table': quillBetterTable}, true);
|
|
||||||
|
|
||||||
class Editor {
|
|
||||||
constructor(sEditorId, bReadOnly) {
|
|
||||||
this.keystrokes = 0;
|
|
||||||
this.readOnly = bReadOnly || false;
|
|
||||||
this.sCursorPos = '';
|
|
||||||
|
|
||||||
//DOM Elements
|
|
||||||
this.$Editor = $(sEditorId);
|
|
||||||
|
|
||||||
this.onKeyStroke = function() {};
|
|
||||||
|
|
||||||
this.oQuill = new Quill(sEditorId, {
|
|
||||||
theme: 'snow',
|
|
||||||
placeholder: 'Notes',
|
|
||||||
readOnly: bReadOnly,
|
|
||||||
modules: {
|
|
||||||
table: false,
|
|
||||||
'better-table': {
|
|
||||||
operationMenu: {
|
|
||||||
items: {
|
|
||||||
mergeCells: false,
|
|
||||||
unmergeCells: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
keyboard: {
|
|
||||||
bindings: quillBetterTable.keyboardBindings
|
|
||||||
},
|
|
||||||
toolbar: [
|
|
||||||
['bold', 'italic', 'underline', 'strike'],
|
|
||||||
//['blockquote', 'code-block'],
|
|
||||||
[{ 'color': [] }, { 'background': [] }],
|
|
||||||
[{ 'header': 1 }, { 'header': 2 }, 'blockquote'],
|
|
||||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
|
||||||
//[{ 'script': 'sub'}, { 'script': 'super' }],
|
|
||||||
//[{ 'indent': '-1'}, { 'indent': '+1' }],
|
|
||||||
//[{ 'direction': 'rtl' }],
|
|
||||||
//[{ 'size': ['small', false, 'large', 'huge'] }],
|
|
||||||
//[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
//[{ 'font': [] }],
|
|
||||||
[{ 'align': [] }],
|
|
||||||
['table'],
|
|
||||||
['link', 'image'],
|
|
||||||
['clean']
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var oToolbar = this.oQuill.getModule('toolbar');
|
|
||||||
oToolbar.addHandler('table', () => {
|
|
||||||
let tableModule = this.oQuill.getModule('better-table');
|
|
||||||
tableModule.insertTable(3, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._initEvents();
|
|
||||||
this._postInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
_initEvents() {
|
|
||||||
//Key strokes
|
|
||||||
this.$Editor.keydown((e) => {
|
|
||||||
if($.inArray(e.which, [13, 37, 38, 39, 40]) == -1) this.onKeyStroke(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
//On text modification
|
|
||||||
this.oQuill.on('text-change', (delta, oldDelta, sSource) => {this._incKeyStrokes();});
|
|
||||||
}
|
|
||||||
|
|
||||||
_postInit(iPage) {
|
|
||||||
if(!this.readOnly) this.oQuill.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
_incKeyStrokes() {
|
|
||||||
this.keystrokes += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
getContent() {
|
|
||||||
return this.oQuill.getContents().ops;
|
|
||||||
}
|
|
||||||
|
|
||||||
setContent(asOps) {
|
|
||||||
this.oQuill.setContents(asOps);
|
|
||||||
this._postInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty() {
|
|
||||||
const rEmpty = /^(<p>(<br>|<br\/>|<br\s\/>|\s+|)<\/p>|)$/gm;
|
|
||||||
return rEmpty.test(this.oQuill.getText().trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
quill2Html(asDelta) {
|
|
||||||
var tempCont = document.createElement('div');
|
|
||||||
(new Quill(tempCont)).setContents(asDelta);
|
|
||||||
return tempCont.getElementsByClassName('ql-editor')[0].innerHTML;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
.doc-item {
|
.doc-item {
|
||||||
|
background: white;
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
@@ -27,26 +28,23 @@
|
|||||||
|
|
||||||
#notes_box {
|
#notes_box {
|
||||||
#notes {
|
#notes {
|
||||||
height: calc(100% - 27.35px);
|
height: 100%;
|
||||||
border: 2px solid $gray-400;
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
padding: 1em 0.5em 1em 0;
|
|
||||||
background: $gray-200;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#notes_feedback {
|
#notes_feedback {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 27.35px;
|
height: 39px;
|
||||||
width: 50%;
|
width: 350px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 0.5em;
|
padding: 0 13px;
|
||||||
line-height: 27.35px;
|
line-height: 39px;
|
||||||
|
|
||||||
&.note-error {
|
&.note-error {
|
||||||
color: $col_main_2;
|
color: $col_main_2;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
@import 'scrollbar/jquery.mCustomScrollbar.scss';
|
@import 'scrollbar/jquery.mCustomScrollbar.scss';
|
||||||
|
|
||||||
|
.mCustomScrollBox {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar,
|
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar,
|
||||||
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar,
|
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar,
|
||||||
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar {
|
.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar {
|
||||||
|
|||||||
53
style/_tiny.scss
Normal file
53
style/_tiny.scss
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#notes {
|
||||||
|
.tox {
|
||||||
|
&.tox-tinymce {
|
||||||
|
border-color: $gray-400;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.tox-statusbar {
|
||||||
|
border-top-color: $gray-400;
|
||||||
|
}
|
||||||
|
.tox-tbtn svg {
|
||||||
|
//fill: theme-color-level("primary", 2);
|
||||||
|
fill: $col_main_1;
|
||||||
|
}
|
||||||
|
.tox-tbtn__select-label {
|
||||||
|
color: $col_main_1;
|
||||||
|
}
|
||||||
|
.tox-toolbar, .tox-toolbar__overflow, .tox-toolbar__primary {
|
||||||
|
background: url("data:image/svg+xml;charset=utf8,%3Csvg height='39px' viewBox='0 0 40 39px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='38px' width='100' height='1' fill='%23cbbdb5'/%3E%3C/svg%3E") left 0 top 0 #fff;
|
||||||
|
}
|
||||||
|
.tox-statusbar__branding {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tox {
|
||||||
|
.tox-collection__group {
|
||||||
|
.tox-collection__item-label,
|
||||||
|
.tox-collection--list .tox-collection__item--enabled,
|
||||||
|
.tox-collection--list .tox-collection__item--active:not(.tox-collection__item--state-disabled),
|
||||||
|
.tox-collection__item {
|
||||||
|
color: $col_main_1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tox-collection--list .tox-collection__group,
|
||||||
|
.tox-menu,
|
||||||
|
.tox-insert-table-picker > div {
|
||||||
|
border-color: $gray-400 !important;
|
||||||
|
}
|
||||||
|
.tox-insert-table-picker .tox-insert-table-picker__selected {
|
||||||
|
background-color: theme-color-level("primary", -2) !important;
|
||||||
|
border-color: $col_main_1 !important;
|
||||||
|
}
|
||||||
|
.tox-collection--list .tox-collection__item--active {
|
||||||
|
background-color: $gray-300 !important;
|
||||||
|
}
|
||||||
|
.tox-collection__item-caret svg {
|
||||||
|
fill: $col_main_1 !important;
|
||||||
|
}
|
||||||
|
.tox-insert-table-picker__label {
|
||||||
|
color: $col_main_1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$col_main_1: #907465; //Brown
|
$col_main_1: #796155; //Brown old: #907465
|
||||||
$col_main_2: #C81F3F; //Red
|
$col_main_2: #C81F3F; //Red
|
||||||
|
|
||||||
$font_para: 'Quicksand';
|
$font_para: 'Quicksand';
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
@import 'bootstrap';
|
@import 'bootstrap';
|
||||||
@import 'quill';
|
@import 'quill';
|
||||||
|
@import 'tiny';
|
||||||
@import 'scrollbar';
|
@import 'scrollbar';
|
||||||
|
|
||||||
/* Template (theme) */
|
/* Template (theme) */
|
||||||
|
|||||||
Reference in New Issue
Block a user