You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
567 lines
18 KiB
HTML
567 lines
18 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block main %}
|
|
<!-- <textarea id="writing-field" rows="4" cols="50"></textarea> -->
|
|
|
|
<div id="topbar">
|
|
|
|
<form method="post">
|
|
{{ form.csrf_token }}
|
|
{{ form.title }}
|
|
{{ form.category }}
|
|
{{ form.writingfield }}
|
|
<input value="submit" id="submit" type="submit"> <h1 style="display:inline-block;"> PARA .DOX</h1>
|
|
</form>
|
|
|
|
<div id="toolbar">
|
|
|
|
<a href="#" id="insertImg">Insert image</a>
|
|
<a href="#" data-command='insertCode'><i class="fa fa-code"></i></a>
|
|
<a href="#" data-command='undo'><i class='fa fa-undo'></i></a>
|
|
<a href="#" data-command='redo'><i class='fa fa-repeat'></i></a>
|
|
<a href="#" data-command='bold'><i class='fa fa-bold'></i></a>
|
|
<a href="#" data-command='italic'><i class='fa fa-italic'></i></a>
|
|
<a href="#" data-command='underline'><i class='fa fa-underline'></i></a>
|
|
<a href="#" data-command='strikeThrough'><i class='fa fa-strikethrough'></i></a>
|
|
<a href="#" data-command='justifyLeft'><i class='fa fa-align-left'></i></a>
|
|
<a href="#" data-command='justifyCenter'><i class='fa fa-align-center'></i></a>
|
|
<a href="#" data-command='justifyRight'><i class='fa fa-align-right'></i></a>
|
|
<a href="#" data-command='justifyFull'><i class='fa fa-align-justify'></i></a>
|
|
<a href="#" data-command='indent'><i class='fa fa-indent'></i></a>
|
|
<a href="#" data-command='outdent'><i class='fa fa-outdent'></i></a>
|
|
<a href="#" data-command='insertUnorderedList'><i class='fa fa-list-ul'></i></a>
|
|
<a href="#" data-command='insertOrderedList'><i class='fa fa-list-ol'></i></a>
|
|
<!--<a href="#" data-command='h1'>H1</a>
|
|
<a href="#" data-command='h2'>H2</a>-->
|
|
<a href="#" data-command='createlink'><i class='fa fa-link'></i></a>
|
|
<a href="#" data-command='unlink'><i class='fa fa-unlink'></i></a>
|
|
<a href="#" data-command='insertimage'><i class='fa fa-image'></i></a>
|
|
<a href="#" data-command='p'>P</a>
|
|
<a href="#" data-command='imgsub'>img sub</a>
|
|
<a href="#" data-command='references'>references</a>
|
|
<a href="#" data-command='subscript'><i class='fa fa-subscript'></i></a>
|
|
<a href="#" data-command='superscript'><i class='fa fa-superscript'></i></a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<form id="upload_img" method="post" enctype="multipart/form-data">
|
|
<label for="file">Select a file</label>
|
|
<input name="file" type="file">
|
|
<button id="submit_img" type="button">Upload</button>
|
|
<p>Result Filename: <span id="resultFilename"> here</span></p>
|
|
<p>Result Filesize: <span id="resultFilesize">here</span></p>
|
|
</form>
|
|
|
|
<div id="code_insert"><pre contenteditable="true">Insert code here</pre><button id="submit_code" type="button">insert</button></div>
|
|
|
|
<div id="writing-field" contenteditable="true"></div>
|
|
<div id="type_log"></div>
|
|
</body>
|
|
|
|
<script>
|
|
var writing_field = $("#writing-field");
|
|
var writing_in_focus = false;
|
|
var last_word = "";
|
|
var current_word = "";
|
|
var number_selected=-1;
|
|
var caret_pos = 0;
|
|
|
|
writing_field.focusin(function() {
|
|
writing_in_focus = true;
|
|
})
|
|
|
|
writing_field.focusout(function() {
|
|
writing_in_focus = false;
|
|
})
|
|
|
|
writing_field.on('keydown', function (e) {
|
|
if (e.keyCode==40||e.keyCode==38||e.keyCode==13) {
|
|
if(number_selected!=-1) e.preventDefault();
|
|
}
|
|
});
|
|
//check for typing or click in textfield
|
|
writing_field.bind("click keyup" ,function(e) {
|
|
|
|
var input = writing_field.text();
|
|
if(e.key== " "){
|
|
last_word = "";
|
|
}
|
|
else{
|
|
last_word = last_word+e.key;
|
|
}
|
|
|
|
if (e.keyCode > 36 && e.keyCode < 41)
|
|
{
|
|
var cursorPos = getCaretPosition(document.getElementById("writing-field"));
|
|
}
|
|
if(e.keyCode==40)
|
|
{
|
|
|
|
number_selected++;
|
|
console.log(number_selected);
|
|
if($('#autocomplete').children().length > 0){
|
|
$('.proposal').css("background-color", "");
|
|
$('.proposal').css("color", "");
|
|
$('.proposal').eq(number_selected).css("background-color", "blue");
|
|
$('.proposal').eq(number_selected).css("color", "white");
|
|
return false;
|
|
}
|
|
|
|
}
|
|
else if(e.keyCode==38)
|
|
{
|
|
number_selected--;
|
|
console.log(number_selected);
|
|
if($('#autocomplete').children().length > 0){
|
|
$('.proposal').css("background-color", "");
|
|
$('.proposal').css("color", "");
|
|
$('.proposal').eq(number_selected).css("background-color", "blue");
|
|
$('.proposal').eq(number_selected).css("color", "white");
|
|
return false;
|
|
}
|
|
|
|
}
|
|
else if(e.keyCode==13 && number_selected!=-1){
|
|
var position = getCaretPosition(document.getElementById("writing-field"));
|
|
console.log("CARET POSITION:::: "+caret_pos)
|
|
console.log("CURRENT WORD:::: "+current_word)
|
|
/*
|
|
var content = writing_field.text();
|
|
var newContent = content.slice(0, caret_pos-current_word.length) + content.slice(caret_pos);
|
|
writing_field.text(newContent);*/
|
|
setSelectionRange(document.getElementById("writing-field"),caret_pos-current_word.length ,caret_pos);
|
|
document.execCommand("delete", false,false);
|
|
// SetCaretPosition(document.getElementById("writing-field"),caret_pos-current_word.length);
|
|
pasteHtmlAtCaret($('.proposal').eq(number_selected).find('b').text()+$('.proposal').eq(number_selected).find('span').text()+" <a class='linkTo' href='"+$('.proposal').eq(number_selected).find('.intext').text()+"'>→ "+$('.proposal').eq(number_selected).find('.intextname').text()+"</a> ");
|
|
//pasteHtmlAtCaret("<a href='"+$('.proposal').eq(number_selected).find('.intext').text()+"'>"+$('.proposal').eq(number_selected).find('b').text()+$('.proposal').eq(number_selected).find('span').text()+"</a>");
|
|
|
|
//document.execCommand("insertHTML", false, "<a href='#'>"+$('.proposal').eq(number_selected).text()+"</a>");
|
|
|
|
number_selected=-1;
|
|
}
|
|
else{
|
|
number_selected=-1;
|
|
}
|
|
caret_pos=getCaretPosition(document.getElementById("writing-field"));
|
|
console.log(caret_pos);
|
|
current_word = getWordAt(writing_field.text(),getCaretPosition(document.getElementById("writing-field"))-1)
|
|
console.log(current_word)
|
|
//typeinfo at the bottom
|
|
$("#type_log").append(e.key );
|
|
updateScroll();
|
|
})
|
|
function getTextNodesIn(node) {
|
|
var textNodes = [];
|
|
if (node.nodeType == 3) {
|
|
textNodes.push(node);
|
|
} else {
|
|
var children = node.childNodes;
|
|
for (var i = 0, len = children.length; i < len; ++i) {
|
|
textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
|
|
}
|
|
}
|
|
return textNodes;
|
|
}
|
|
|
|
function setSelectionRange(el, start, end) {
|
|
if (document.createRange && window.getSelection) {
|
|
var range = document.createRange();
|
|
range.selectNodeContents(el);
|
|
var textNodes = getTextNodesIn(el);
|
|
var foundStart = false;
|
|
var charCount = 0, endCharCount;
|
|
|
|
for (var i = 0, textNode; textNode = textNodes[i++]; ) {
|
|
endCharCount = charCount + textNode.length;
|
|
if (!foundStart && start >= charCount
|
|
&& (start < endCharCount ||
|
|
(start == endCharCount && i <= textNodes.length))) {
|
|
range.setStart(textNode, start - charCount);
|
|
foundStart = true;
|
|
}
|
|
if (foundStart && end <= endCharCount) {
|
|
range.setEnd(textNode, end - charCount);
|
|
break;
|
|
}
|
|
charCount = endCharCount;
|
|
}
|
|
|
|
var sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
} else if (document.selection && document.body.createTextRange) {
|
|
var textRange = document.body.createTextRange();
|
|
textRange.moveToElementText(el);
|
|
textRange.collapse(true);
|
|
textRange.moveEnd("character", end);
|
|
textRange.moveStart("character", start);
|
|
textRange.select();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function updateScroll(){
|
|
$('#type_log').scrollTop($('#type_log')[0].scrollHeight);
|
|
}
|
|
function pasteHtmlAtCaret(html) {
|
|
var sel, range;
|
|
if (window.getSelection) {
|
|
// IE9 and non-IE
|
|
sel = window.getSelection();
|
|
if (sel.getRangeAt && sel.rangeCount) {
|
|
range = sel.getRangeAt(0);
|
|
range.deleteContents();
|
|
|
|
// Range.createContextualFragment() would be useful here but is
|
|
// non-standard and not supported in all browsers (IE9, for one)
|
|
var el = document.createElement("div");
|
|
el.innerHTML = html;
|
|
var frag = document.createDocumentFragment(), node, lastNode;
|
|
while ( (node = el.firstChild) ) {
|
|
lastNode = frag.appendChild(node);
|
|
}
|
|
range.insertNode(frag);
|
|
|
|
// Preserve the selection
|
|
if (lastNode) {
|
|
range = range.cloneRange();
|
|
range.setStartAfter(lastNode);
|
|
range.collapse(true);
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
}
|
|
}
|
|
} else if (document.selection && document.selection.type != "Control") {
|
|
// IE < 9
|
|
document.selection.createRange().pasteHTML(html);
|
|
}
|
|
}
|
|
|
|
|
|
function getWordAt(str, pos) {
|
|
|
|
// Perform type conversions.
|
|
str = String(str);
|
|
pos = Number(pos) >>> 0;
|
|
|
|
// Search for the word's beginning and end.
|
|
var left = str.slice(0, pos + 1).search(/\S+$/),
|
|
right = str.slice(pos).search(/\s/);
|
|
|
|
// The last word in the string is a special case.
|
|
if (right < 0) {
|
|
return str.slice(left);
|
|
}
|
|
|
|
// Return the word, using the located bounds to extract it from the string.
|
|
return str.slice(left, right + pos);
|
|
|
|
}
|
|
|
|
var ie = (typeof document.selection != "undefined" && document.selection.type != "Control") && true;
|
|
var w3 = (typeof window.getSelection != "undefined") && true;
|
|
function getCaretPosition(element) {
|
|
var caretOffset = 0;
|
|
if (w3) {
|
|
var range = window.getSelection().getRangeAt(0);
|
|
var preCaretRange = range.cloneRange();
|
|
preCaretRange.selectNodeContents(element);
|
|
preCaretRange.setEnd(range.endContainer, range.endOffset);
|
|
caretOffset = preCaretRange.toString().length;
|
|
} else if (ie) {
|
|
var textRange = document.selection.createRange();
|
|
var preCaretTextRange = document.body.createTextRange();
|
|
preCaretTextRange.moveToElementText(element);
|
|
preCaretTextRange.setEndPoint("EndToEnd", textRange);
|
|
caretOffset = preCaretTextRange.text.length;
|
|
}
|
|
return caretOffset;
|
|
}
|
|
|
|
|
|
//time between keystrokes
|
|
var last;
|
|
var output = $('#output');
|
|
writing_field.on('input', function() {
|
|
var n = new Date()
|
|
var time = (last - n);
|
|
last = n;
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
['#writing-field'].forEach(function (selector) {
|
|
var element = document.querySelector(selector);
|
|
var fontSize = getComputedStyle(element).getPropertyValue('font-size');
|
|
|
|
var rect = document.createElement('div');
|
|
document.body.appendChild(rect);
|
|
rect.id = "autocomplete"
|
|
rect.style.position = 'absolute';
|
|
rect.style.height = "auto";
|
|
rect.style.width = "auto";
|
|
|
|
['keyup', 'click', 'scroll'].forEach(function (event) {
|
|
element.addEventListener(event, update);
|
|
});
|
|
|
|
function update() {
|
|
|
|
if(event.keyCode != 40 && event.keyCode != 38){
|
|
// Set `debug` to true in order to see the mirror div. Default false.
|
|
var coordinates = getSelectionCoords();
|
|
//console.log('(top, left, height) = (%s, %s, %s)', coordinates.top, coordinates.left, coordinates.height);
|
|
rect.style.top =
|
|
+ document.scrollingElement.scrollTop
|
|
+ coordinates.y
|
|
+ 30
|
|
+ 'px';
|
|
rect.style.left =
|
|
- element.scrollLeft
|
|
+ coordinates.x
|
|
+ 'px';
|
|
getProposals(current_word);
|
|
}
|
|
}
|
|
});
|
|
|
|
function getProposals(input_word){
|
|
|
|
var autocomplete = document.getElementById("autocomplete")
|
|
while (autocomplete.firstChild) {
|
|
autocomplete.removeChild(autocomplete.firstChild);
|
|
}
|
|
|
|
var ajaxfinished = true;
|
|
var requestProposals
|
|
|
|
if(input_word.length>1){
|
|
|
|
if(!ajaxfinished) {requestProposals.abort();}
|
|
|
|
ajaxfinished = false;
|
|
requestProposals = $.ajax({
|
|
url: '/api/beginwith='+current_word+'',
|
|
dataType: 'json',
|
|
success: function (data) {
|
|
ajaxfinished = true;
|
|
data.forEach(function(p){
|
|
var proposal = document.createElement('div');
|
|
autocomplete.appendChild(proposal);
|
|
proposal.className = "proposal";
|
|
var result = p.word;
|
|
proposal.innerHTML = "<div class='incoming'>in</div> <b>"+current_word+"</b>"+"<span>"+result.substring(current_word.length)+"</span><div hidden='True' class='intext'>"+p.intext+"</div><div class='intextname'>"+p.intextname+"</div><div class='context'>"+p.context+"</div><div hidden='True' class='wordnumber'>"+p.wordnumber+"</div>";
|
|
|
|
});
|
|
$(".proposal").on("mousedown",function(e){
|
|
e.preventDefault();
|
|
var position = getCaretPosition(document.getElementById("writing-field"));
|
|
console.log("CARET POSITION:::: "+caret_pos)
|
|
console.log("CURRENT WORD:::: "+current_word)
|
|
/*
|
|
var content = writing_field.text();
|
|
var newContent = content.slice(0, caret_pos-current_word.length) + content.slice(caret_pos);
|
|
writing_field.text(newContent);*/
|
|
setSelectionRange(document.getElementById("writing-field"),caret_pos-current_word.length ,caret_pos);
|
|
document.execCommand("delete", false,false);
|
|
// SetCaretPosition(document.getElementById("writing-field"),caret_pos-current_word.length);
|
|
//" <a class='linkTo' href='"+str(link)+"'>→ "+frompost.title+"</a>"
|
|
pasteHtmlAtCaret($(this).find('b').text()+$(this).find('span').text()+" <a class='linkTo' href='"+$(this).find('.intext').text()+"'>→ "+$(this).find('.intextname').text()+"</a> ");
|
|
$("#writing-field").get(0).focus();
|
|
|
|
SetCaretPosition(document.getElementById("writing-field"),caret_pos+$(this).find('span').text().length+1);
|
|
})
|
|
$(".incoming").on("mousedown",function(e){
|
|
$(".proposal").unbind('mousedown');
|
|
$.ajax({url: "/api/link={{ post.pid }}+wordnum="+$(this).siblings(".wordnumber").first().text()+"+document="+$(this).siblings(".intext").first().text() , success: function(result){
|
|
$("#div1").html(result);
|
|
}});
|
|
|
|
})
|
|
|
|
|
|
}
|
|
});
|
|
|
|
|
|
|
|
}
|
|
else{
|
|
}
|
|
}
|
|
|
|
// Move caret to a specific point in a DOM element
|
|
function SetCaretPosition(el, pos){
|
|
|
|
// Loop through all child nodes
|
|
for(var node of el.childNodes){
|
|
if(node.nodeType == 3){ // we have a text node
|
|
if(node.length >= pos){
|
|
// finally add our range
|
|
var range = document.createRange(),
|
|
sel = window.getSelection();
|
|
range.setStart(node,pos);
|
|
range.collapse(true);
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
return -1; // we are done
|
|
}else{
|
|
pos -= node.length;
|
|
}
|
|
}else{
|
|
pos = SetCaretPosition(node,pos);
|
|
if(pos == -1){
|
|
return -1; // no need to finish the for loop
|
|
}
|
|
}
|
|
}
|
|
return pos; // needed because of recursion stuff
|
|
}
|
|
|
|
function getSelectionCoords() {
|
|
var sel = document.selection, range, rect;
|
|
var x = 0, y = 0;
|
|
if (sel) {
|
|
if (sel.type != "Control") {
|
|
range = sel.createRange();
|
|
range.collapse(true);
|
|
x = range.boundingLeft;
|
|
y = range.boundingTop;
|
|
}
|
|
} else if (window.getSelection) {
|
|
sel = window.getSelection();
|
|
if (sel.rangeCount) {
|
|
range = sel.getRangeAt(0).cloneRange();
|
|
if (range.getClientRects) {
|
|
range.collapse(true);
|
|
if (range.getClientRects().length>0){
|
|
rect = range.getClientRects()[0];
|
|
x = rect.left;
|
|
y = rect.top;
|
|
}
|
|
}
|
|
// Fall back to inserting a temporary element
|
|
if (x == 0 && y == 0) {
|
|
var span = document.createElement("span");
|
|
if (span.getClientRects) {
|
|
// Ensure span has dimensions and position by
|
|
// adding a zero-width space character
|
|
span.appendChild( document.createTextNode("\u200b") );
|
|
range.insertNode(span);
|
|
rect = span.getClientRects()[0];
|
|
x = rect.left;
|
|
y = rect.top;
|
|
var spanParent = span.parentNode;
|
|
spanParent.removeChild(span);
|
|
|
|
// Glue any broken text nodes back together
|
|
spanParent.normalize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return { x: x, y: y };
|
|
}
|
|
|
|
$("#insertImg").click(function (){
|
|
|
|
$("#upload_img").fadeToggle()
|
|
|
|
})
|
|
|
|
|
|
function insertCode(){
|
|
$("#code_insert").fadeOut();
|
|
$("#writing-field").focus();
|
|
SetCaretPosition(document.getElementById("writing-field"),caret_pos);
|
|
pasteHtmlAtCaret($("#code_insert pre").text());
|
|
}
|
|
|
|
function insertImage(filename){
|
|
$("#upload_img").fadeOut();
|
|
$("#writing-field").focus();
|
|
SetCaretPosition(document.getElementById("writing-field"),caret_pos);
|
|
|
|
pasteHtmlAtCaret("<img class='textimage' src='/img/"+filename+"'>");
|
|
|
|
|
|
}
|
|
|
|
$('#submit').click(function () {
|
|
var mysave = $('#writing-field').html();
|
|
$('#writingfield').val(mysave);
|
|
});
|
|
$( window ).on( "load", function() {
|
|
$('#writing-field').html($('#writingfield').val());
|
|
$('.title').hide()
|
|
})
|
|
|
|
$('#submit_code').click(function() {
|
|
insertCode();
|
|
})
|
|
$(function() {
|
|
$('#submit_img').click(function() {
|
|
event.preventDefault();
|
|
var form_data = new FormData($('#upload_img')[0]);
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: '/uploadajax',
|
|
data: form_data,
|
|
contentType: false,
|
|
processData: false,
|
|
dataType: 'json'
|
|
}).done(function(data, textStatus, jqXHR){
|
|
console.log(data);
|
|
console.log(textStatus);
|
|
console.log(jqXHR);
|
|
console.log('Success!');
|
|
$("#resultFilename").text(data['name']);
|
|
insertImage(data['name']);
|
|
$("#resultFilesize").text(data['size']);
|
|
}).fail(function(data){
|
|
alert('error!');
|
|
});
|
|
});
|
|
});
|
|
|
|
$('#toolbar a').click(function(e) {
|
|
var command = $(this).data('command');
|
|
if(command == 'insertCode'){
|
|
$("#code_insert").fadeToggle()
|
|
}
|
|
if (command == 'h1' || command == 'h2' || command == 'p') {
|
|
document.execCommand('formatBlock', false, command);
|
|
}
|
|
if (command == 'forecolor' || command == 'backcolor') {
|
|
document.execCommand($(this).data('command'), false, $(this).data('value'));
|
|
}
|
|
if(command == "imgsub")
|
|
{
|
|
selection = window.getSelection().toString();
|
|
wrappedselection = '<span class="imgsub">' + selection + '</span>';
|
|
document.execCommand('insertHTML', false, wrappedselection);
|
|
}
|
|
if(command == "references")
|
|
{
|
|
selection = window.getSelection().toString();
|
|
wrappedselection = '<span class="references">' + selection + '</span>';
|
|
document.execCommand('insertHTML', false, wrappedselection);
|
|
}
|
|
if (command == 'createlink' || command == 'insertimage') {
|
|
url = prompt('Enter the link here: ','http:\/\/'); document.execCommand($(this).data('command'), false, url);
|
|
}
|
|
else document.execCommand($(this).data('command'), false, null);
|
|
});
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
{% endblock %}
|