ihm javascript

pull/1/head
Nicolas Sanchez 3 years ago
commit d9495f6afb

1
.gitignore vendored

@ -0,0 +1 @@
/target

1584
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
[package]
name = "mdwiki"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.0.18", features = ["derive"] }
actix-web = "4"
actix-files = "0.6.2"
askama = { version = "0.11.1", features = ["with-actix-web"] }
askama_actix = "0.13.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
git2 = "0.16.0"

@ -0,0 +1,9 @@
mdwiki
======
Wiki utilisant la syntaxe MarkDown pour être rapide et facile à modifier.
Idéal pour la prise de notes.
Création dynamique de pages en créant un lien dans une page.
Ranges :
https://stackoverflow.com/questions/6249095/how-to-set-the-caret-cursor-position-in-a-contenteditable-element-div

@ -0,0 +1,26 @@
use clap::Parser;
#[derive(Parser)]
pub struct Arguments {
/// IP address
#[arg(short, long, default_value_t = String::from("127.0.0.1"))]
pub ip: String,
/// Port to listen to
#[arg(short, long, default_value_t = 8081)]
pub port: u16,
}
impl Arguments {
pub fn parse_args() -> Arguments {
let args = Arguments::parse();
args
}
}
#[derive(Clone)]
pub struct AppData {
pub name: String,
}

@ -0,0 +1,19 @@
use actix_web::web;
use actix_web::{HttpResponse, Responder, get};
use askama_actix::Template;
use askama_actix::TemplateToResponse;
use crate::commons::AppData;
#[derive(Template)]
#[template(path = "index.html")]
pub struct IndexTemplate {
pub name: String,
}
#[get("/")]
async fn index(data: web::Data<AppData>) -> impl Responder {
let name = data.name.to_owned();
IndexTemplate { name }.to_response()
}

@ -0,0 +1,2 @@
pub mod index;
pub mod commons;

@ -0,0 +1,28 @@
use actix_web::{post, web, App, HttpResponse, HttpServer, Responder};
use actix_files;
use mdwiki::commons::{Arguments, AppData};
use mdwiki::index;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args = Arguments::parse_args();
let ip = args.ip;
let port = args.port;
let appdata = AppData {
name: String::from("MdNotes"),
};
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(appdata.to_owned()))
.service(index::index)
.service(actix_files::Files::new("/static", "./static"))
})
.bind((ip, port))?
.run()
.await
}

@ -0,0 +1,39 @@
html {
background-color: #f5f5f5;
}
div#mdnotes {
font-family: sans-serif;
padding-top: 1rem;
padding-left: 3rem;
padding-right: 3rem;
padding-bottom: 1rem;
background-color: #ffffff;
}
div#mdnotes div.h1 {
font-size: 2rem;
font-weight: bold;
margin-top: 1rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid #666666;
}
div#mdnotes div.h2 {
font-size: 1.5rem;
font-weight: bold;
margin-top: 0.5rem;
margin-bottom: 1rem;
}
div#mdnotes div.h3 {
font-size: 1rem;
font-weight: bold;
margin-top: 0.3rem;
margin-bottom: 0.5rem;
}
div#mdnotes div.h4 {
font-style: italic;
margin-bottom: 0.3rem;
}

@ -0,0 +1,170 @@
function change(evt) {
reId(document.getElementById('mdnotes'));
let res = getStartPositionInLine();
let line = res[0];
if (line == null) {
return;
}
let position = res[1];
let id = line.id;
toMD();
toHTML();
line = document.getElementById(id);
setStartPositionInLine(line, position);
return true;
}
function reId(obj) {
let prevId = '';
let children = obj.childNodes;
for (i = 0; i < children.length; i++) {
let child = children[i];
if (child.classList.contains('mdnotes_line')) {
if (prevId == child.id) {
child.className = 'mdnotes_line';
}
prevId = child.id;
child.id = 'mdnotes_' + i;
}
}
}
function getStartPositionInLine() {
let selection = window.getSelection();
let range = selection.getRangeAt(0).cloneRange();
let obj = range.startContainer;
let position = range.startOffset;
let line = null;
while (obj != null) {
if (obj.previousSibling != null) {
obj = obj.previousSibling;
if (obj.innerText != null) {
position += obj.innerText.length;
} else if (obj.length != null) {
position += obj.length;
}
} else if (obj.parentNode != null && obj.parentNode.classList != null && !obj.parentNode.classList.contains('mdnotes_line')) {
obj = obj.parentNode;
} else if (obj.parentNode != null && obj.parentNode.classList != null && obj.parentNode.classList.contains('mdnotes_line')) {
line = obj.parentNode;
obj = null;
} else {
obj = null;
}
}
return [line, position];
}
function setStartPositionInLine(line, position) {
setStartPositionInDiv(line, position)
}
function setStartPositionInDiv(obj, position) {
let temppos = position;
if (temppos > obj.innerText.length) {
return temppos - obj.innerText.length;
}
let children = obj.childNodes;
for (i = 0; i < children.length; i++) {
let child = children[i];
if (child.nodeType == 3) {
temppos = setStartPositionInText(child, position);
} else {
temppos = setStartPositionInDiv(child, temppos);
if (temppos == 0) {
return temppos;
}
}
}
return temppos;
}
function setStartPositionInText(obj, position) {
if (position > obj.length) {
return position - obj.length;
}
let selection = window.getSelection();
selection.removeAllRanges();
let range = document.createRange();
range.setStart(obj, position);
selection.addRange(range);
return 0;
}
function toHTML() {
let ta = document.getElementById('ta');
let mda = document.getElementById('mdnotes');
mda.innerHTML = '';
let lines = ta.value.split('\n');
for (var i = 0; i < lines.length; i++) {
let obj = document.createElement('div');
let line = lines[i];
if (line == '') {
let br = document.createElement('br');
obj.append(br);
}
let normLine = line.trim();
if (normLine.startsWith('#### ')) {
obj.classList.add('h4');
} else if (normLine.startsWith('### ')) {
obj.classList.add('h3');
} else if (normLine.startsWith('## ')) {
obj.classList.add('h2');
} else if (normLine.startsWith('# ')) {
obj.classList.add('h1');
}
obj.classList.add('mdnotes_line');
if (line !== '') {
obj.innerText = line;
}
obj.id = 'mdnotes_' + i;
mda.append(obj);
}
}
function toMD() {
let mda = document.getElementById('mdnotes');
let content = mda.childNodes;
let text = eltToMD(mda)
let ta = document.getElementById('ta');
ta.value = text;
}
function eltToMD(elt) {
let text = '';
if (getType(elt) == 'TEXT') {
text = elt.nodeValue;
} else if (elt.innerText.length == 0) {
text = '';
} else {
let children = elt.childNodes;
let prevType = 'DIV';
for (let i = 0; i < children.length; i++) {
let type = getType(children[i]);
if (type == 'DIV' && prevType != 'DIV') {
text += "\n";
}
text += eltToMD(children[i]);
if (type == 'DIV') {
text += "\n";
}
prevType = type;
}
}
return text;
}
function getType(elt) {
if (elt.nodeType == 3) {
return 'TEXT'
} else if (elt.nodeType == 1) {
return elt.tagName;
} else {
return 'UNKNOWN';
}
}
toHTML();

@ -0,0 +1,20 @@
<html>
<head>
<title>{{name}}</title>
<link rel="stylesheet" href="static/mdnotes.css">
</head>
<body>
<textarea id="ta" class="mdnotes" style="display: none;">
# Titre 1
Un petit texte
## Titre 2
### Titre 3-1
Encore un joli texte
### Titre 3-2
T'en as marre ???
#### Titre 4
Moi oui !!!</textarea>
<div id="mdnotes" class="mdnotes" oninput="return change(event)" contenteditable="true"></div>
<script type="text/javascript" src="static/mdnotes.js"></script>
</body>
</html>
Loading…
Cancel
Save