Merge pull request 'develop' (#30) from develop into main

Reviewed-on: cheeze.fr/mdnotes#30
main
sanchezn 3 years ago
commit a60a5ba1ba

2
Cargo.lock generated

@ -518,6 +518,7 @@ dependencies = [
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
"uuid 1.3.0",
] ]
[[package]] [[package]]
@ -2431,6 +2432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"rand",
"serde", "serde",
] ]

@ -9,6 +9,8 @@ edition = "2021"
clap = { version = "4.0.18", features = ["derive"] } clap = { version = "4.0.18", features = ["derive"] }
uuid = {version = "1.3.0", features=["v4", "fast-rng"]}
actix-web = "4" actix-web = "4"
actix-files = "0.6.2" actix-files = "0.6.2"
actix-session = { version = "0.7.2", features = ["cookie-session"] } actix-session = { version = "0.7.2", features = ["cookie-session"] }

@ -1,5 +1,11 @@
create table pages ( create table pages (
page_name text primary key, domain text,
page_name text,
page_text text, page_text text,
active boolean default true not null active boolean default true not null,
primary key (domain, page_name)
);
create table pages_histo (
); );

Binary file not shown.

@ -0,0 +1,54 @@
[retour](/BPCE-SI/BPCE-SI-Notes)
# formation ROA Devops et MCO
_le 16/03/2023_
**formateur :** Jean-Marc Meunier
**Code projet (clarity) :** PR002611
**Support :**
- [Documentation Myway ROA](https://confluence.f.bbg/display/MWROA/Documentation+Myway+ROA)
- [Modernisation PIC Myway ROA](https://confluence.f.bbg/display/MWROA/02-Modernisation+PIC+Myway+ROA)
## Objectif
**Devops :** Migrer les ressources ROA sur la nouvelle version de la plateforme.
- passage vers java 8
- passer de tfs vers bitbucket
- changement d'installeur (XLR)
- changement de Jenkins
**MCO :** Maintenance en Condition Opérationnelle
## Ce qui change
- Jave 7 -> Java 8
- JBOSS 6.4 -> 7
- TFS -> Bitbucket
- Pack-it, install-it -> XLD, XLR
- Nexus -> Artifactory
- Sonar 7 -> Sonar 8, Checkmarx
## Pré-requis
### git
- `it config --global --list`
- **install git :** pulse SIT-PKG001
- **config git :** user.name, user.email, désactiver la certification SSL
### Bitbucket
Créer un jeton bitbucket (nomprénom) en écriture du projjet et du dépôt (le password sera le jeton généré). **Ne pas perdre le jeton impossible de le consulter _a posteriori_**
- **nommage projet :** [CODE CIA]-[Techno(MYWAYROA)]-[CODE APPLICATION ARIS]-[DOMAINE-ARIS]
- **nommage ressource :** [BLOC APPLICATIF ARIS]-[API]-V[VERSION MAJEURE]
-- Chercher dans ls TFS dans le pom.xml ou dans Aris
Pour une création de dépôt, faire une demande
### Artifactory
[Artifcatory](https://artifactory.mycloud.intrabpce.fr/ui/)
- Créer également un jeton (consultable par la suite).
- `C:\Users\S0006310\.m2\settings.xml` dans server mettre le username et le jeton (password).
- Modifier les url pour la toolbox
### Configuration nouveau projet
- Créer le projet dans mycloud.
- Prévenir via un ticket **SIT-MYWAY004**.
- Prévenir la production applicative.
- Prévenir l'équipe XLR pour créer le template ou modifier le template existant.
- Configuration JBOSS
- Configuration Jenkins
## Migration d'une ressource
- Télécharger le zip de l'outil [GitTfs-0.31.0.zip](https://confluence.f.bbg/download/attachments/1258063573/GitTfs-0.31.0.zip?version=1&modificationDate=1613397108000&api=v2)
- paramétrer le PATH vers le répertoire d'install
- `git-tfs clone [source_TFS] [répertoire local git]`
- récupérer l'outil sur artifactory pour la migration JBOSS [](https://artifactory.f.bbg/artifactory/CEH62-maven-releases/fr/itce/sie/myway/uld-ressource-migration) et copier le fichier *with-ressource*
- `call "D:\otoolbox-sie\Java\jdk1.8.0_151\bin\java.exe" -jar ".\uld-ressource-migration-x.y.z-jar-with-resources.jar" run -projectInput "D:\otoolbox-local\sources\CEF42-MYWAYROA-PTMYWAY-OUTINFR\PTMYWAYZ-OUTILSSIE-V2"`
- aller voir le fichier `outilssie-v3.csv` pour les logs
-- si pb, consulter la [migration manuelle](https://confluence.f.bbg/display/MWROA/02-Migration+manuelle)

@ -13,6 +13,9 @@ pub struct Arguments {
/// root of the url ending and starting with / /// root of the url ending and starting with /
#[arg(short, long, default_value_t = String::from("/"))] #[arg(short, long, default_value_t = String::from("/"))]
pub root: String, pub root: String,
/// sqlite database path
#[arg(short, long, default_value_t = String::from("db/db.sqlite3"))]
pub db: String,
} }
impl Arguments { impl Arguments {
@ -26,7 +29,7 @@ impl Arguments {
#[derive(Clone)] #[derive(Clone)]
pub struct AppData { pub struct AppData {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub pool: Pool<SqliteConnectionManager>, pub db_pool: Pool<SqliteConnectionManager>,
} }

@ -1,16 +1,55 @@
use actix_web::{error, web, Error}; use actix_web::{error, web, Error};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>; pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>;
pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>; pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>;
#[allow(unused)]
fn uuid4() -> String {
let id = Uuid::new_v4();
id.to_string()
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Page { pub struct Page {
pub domain: String,
pub page_name: String, pub page_name: String,
pub page_text: String, pub page_text: String,
} }
pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>, Error> { pub struct Domain {
pub domain: String,
pub domain_name: String,
}
pub async fn get_domains(pool: &Pool) -> Result<Vec<Domain>, Error> {
let pool = pool.clone();
let conn = web::block(move || pool.get())
.await?
.map_err(error::ErrorInternalServerError)?;
web::block(move || {
let mut stmt = conn
.prepare("SELECT distinct domain, REPLACE(domain, '_', ' ') from pages WHERE active=true order by domain")?;
stmt.query_map([], |row| {
Ok(Domain {
domain: row.get(0)?,
domain_name: row.get(1)?,
})
})
.and_then(Iterator::collect)
})
.await?
.map_err(error::ErrorInternalServerError)
}
pub async fn get_page_by_name(
pool: &Pool,
domain: String,
pagename: String,
) -> Result<Vec<Page>, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())
@ -19,12 +58,13 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>
web::block(move || { web::block(move || {
let mut stmt = conn let mut stmt = conn
.prepare("SELECT page_name, page_text from pages WHERE active=true and page_name=?")?; .prepare("SELECT domain, page_name, page_text from pages WHERE active=true and domain=? and page_name=?")?;
stmt.query_map([pagename], |row| { stmt.query_map([domain, pagename], |row| {
Ok(Page { Ok(Page {
page_name: row.get(0)?, domain: row.get(0)?,
page_text: row.get(1)?, page_name: row.get(1)?,
page_text: row.get(2)?,
}) })
}) })
.and_then(Iterator::collect) .and_then(Iterator::collect)
@ -33,7 +73,12 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>
.map_err(error::ErrorInternalServerError) .map_err(error::ErrorInternalServerError)
} }
pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> Result<usize, Error> { pub async fn update_page(
pool: &Pool,
domain: String,
page_name: String,
page_text: String,
) -> Result<usize, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())
@ -42,10 +87,9 @@ pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> R
web::block(move || { web::block(move || {
let mut stmt = conn let mut stmt = conn
.prepare("insert or replace into pages (page_name, page_text, active) values (?, ?, true)")?; .prepare("insert or replace into pages (domain, page_name, page_text, active) values (?, ?, ?, true)")?;
stmt.execute([page_name, page_text, ]) stmt.execute([domain, page_name, page_text, ])
}) })
.await? .await?
.map_err(error::ErrorInternalServerError) .map_err(error::ErrorInternalServerError)
} }

@ -5,17 +5,23 @@ use askama_actix::Template;
use askama_actix::TemplateToResponse; use askama_actix::TemplateToResponse;
use crate::commons::AppData; use crate::commons::AppData;
use crate::db;
use crate::db::Domain;
#[derive(Template)] #[derive(Template)]
#[template(path = "index.html")] #[template(path = "index.html")]
pub struct PageTemplate { pub struct PageTemplate {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub domains: Vec<Domain>,
} }
#[get("/")] #[get("/")]
async fn index(data: web::Data<AppData>) -> impl Responder { async fn index(data: web::Data<AppData>) -> impl Responder {
let name = data.name.to_owned(); let app_name = data.app_name.to_owned();
let root = data.root.to_owned(); let base_url = data.base_url.to_owned();
PageTemplate { name, root }.to_response()
let domains = db::get_domains(&data.db_pool).await.unwrap();
PageTemplate { app_name, base_url, domains }.to_response()
} }

@ -14,25 +14,26 @@ async fn main() -> std::io::Result<()> {
let ip = args.ip; let ip = args.ip;
let port = args.port; let port = args.port;
let root = args.root; let base_url = args.root;
let db = args.db;
let manager = SqliteConnectionManager::file("db/db.sqlite3"); let manager = SqliteConnectionManager::file(db);
let pool = Pool::new(manager).unwrap(); let pool = Pool::new(manager).unwrap();
let appdata = AppData { let appdata = AppData {
name: String::from("CheezeNotes"), app_name: String::from("CheezeNotes"),
root, base_url,
pool: pool.clone(), db_pool: pool.clone(),
}; };
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
.app_data(web::Data::new(appdata.to_owned())) .app_data(web::Data::new(appdata.to_owned()))
.service(index::index) .service(index::index)
.service(page::page)
.service(page::save_page)
.service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static", "./static"))
.service(actix_files::Files::new("/static/modules", "./static/modules")) .service(actix_files::Files::new("/static/modules", "./static/modules"))
.service(page::page)
.service(page::save_page)
}) })
.bind((ip, port))? .bind((ip, port))?
.run() .run()

@ -1,10 +1,9 @@
use actix_web::http::header::ContentType; use actix_web::http::header::ContentType;
use actix_web::web::Query;
use actix_web::{get, put, Responder}; use actix_web::{get, put, Responder};
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
use serde::Deserialize; use serde::Deserialize;
use std::fs;
use askama_actix::Template; use askama_actix::Template;
use askama_actix::TemplateToResponse; use askama_actix::TemplateToResponse;
@ -14,48 +13,57 @@ use crate::db;
#[derive(Template)] #[derive(Template)]
#[template(path = "page.html")] #[template(path = "page.html")]
pub struct PageTemplate { pub struct PageTemplate {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub md: String, pub md: String,
pub init: String, pub init: String,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[allow(non_snake_case)]
struct QueryParams { struct QueryParams {
pub data: Option<String>, pub data: Option<String>,
pub fromDomain: Option<String>,
pub fromPage: Option<String>,
}
fn new_page_text(
page_name: String,
domain_from: &Option<String>,
page_from: &Option<String>,
) -> String {
let mut retour = String::from("");
if let (Some(domain_f), Some(page_f)) = (domain_from, page_from) {
retour = format!("[retour](/{}/{})\n", domain_f, page_f);
}
retour + "# " + page_name.replace("_", " ").as_str()
} }
async fn get_data(data: & web::Data<AppData>, pagename: String) -> String { async fn get_data(
let fut_page_datas = db::get_page_by_name(&data.pool, pagename.to_owned()); data: &web::Data<AppData>,
domain: String,
page_name: String,
params: &Query<QueryParams>,
) -> String {
let fut_page_datas =
db::get_page_by_name(&data.db_pool, domain.to_owned(), page_name.to_owned());
let page_datas = fut_page_datas.await.unwrap(); let page_datas = fut_page_datas.await.unwrap();
let md;
match page_datas.first() { match page_datas.first() {
None => { None => new_page_text(page_name, &params.fromDomain, &params.fromPage),
let filename = String::from("pages/") + pagename.as_str() + ".md"; Some(dat) => (*dat.page_text).to_string(),
md = match fs::read_to_string(filename) {
Ok(txt) => {
db::update_page(&data.pool, pagename.to_owned(), txt.to_owned())
.await
.unwrap();
txt
}
Err(_) => String::from("# ") + pagename.replace("_", " ").as_str(),
};
}
Some(dat) => md = (*dat.page_text).to_string(),
} }
md
} }
#[get("/page/{page}")] #[get("/{domain}/{page}")]
async fn page( async fn page(
path: web::Path<(String,)>, path: web::Path<(String, String)>,
data: web::Data<AppData>, data: web::Data<AppData>,
params: web::Query<QueryParams>, params: web::Query<QueryParams>,
) -> impl Responder { ) -> impl Responder {
let pagename = &path.0; let domain = &path.0;
let page_name = &path.1;
let md = get_data(&data, pagename.to_owned()).await; let md = get_data(&data, domain.to_owned(), page_name.to_owned(), &params).await;
match &params.data { match &params.data {
Some(_) => { Some(_) => {
@ -66,30 +74,31 @@ async fn page(
None => {} None => {}
} }
let name = data.name.to_owned() + " - " + pagename.as_str(); let app_name = data.app_name.to_owned() + " - " + page_name.as_str();
let root = data.root.to_owned(); let base_url = data.base_url.to_owned();
//let init = String::from("init();"); //let init = String::from("init();");
let init = format!("init();"); let init = format!("init({:?}, {:?});", domain, page_name);
PageTemplate { PageTemplate {
name, app_name,
root, base_url,
md, md,
init, init,
} }
.to_response() .to_response()
} }
#[put("/page/{page}")] #[put("/{domain}/{page}")]
async fn save_page( async fn save_page(
body: String, body: String,
path: web::Path<(String,)>, path: web::Path<(String, String)>,
data: web::Data<AppData>, data: web::Data<AppData>,
) -> impl Responder { ) -> impl Responder {
let pagename = &path.0; let domain = &path.0;
let pagename = &path.1;
if pagename == "index" { if pagename == "index" {
return HttpResponse::Ok(); return HttpResponse::Ok();
} }
db::update_page(&data.pool, pagename.to_owned(), body) db::update_page(&data.db_pool, domain.to_owned(), pagename.to_owned(), body)
.await .await
.unwrap(); .unwrap();
HttpResponse::Ok() HttpResponse::Ok()

@ -35,6 +35,11 @@ body {
background-color: #dddddd; background-color: #dddddd;
} }
p.domain {
padding-left: 2rem;
font-size: 2rem;
}
div#content { div#content {
position: absolute; position: absolute;
margin: 0; margin: 0;
@ -46,10 +51,12 @@ div#content {
overflow: auto; overflow: auto;
} }
div #margindiv { div#margindiv {
max-width: 1200px; /*max-width: 1600px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;*/
margin-left: .5rem;
margin-right: .5rem;
top: 0; top: 0;
bottom: 0; bottom: 0;
} }
@ -60,8 +67,8 @@ div#cheezenotes {
margin-top: 0; margin-top: 0;
margin-bottom: 3rem; margin-bottom: 3rem;
padding-top: 1rem; padding-top: 1rem;
padding-left: 3rem; padding-left: 1rem;
padding-right: 3rem; padding-right: 1rem;
padding-bottom: 1rem; padding-bottom: 1rem;
background-color: #ffffff; background-color: #ffffff;
min-height: 100%; min-height: 100%;
@ -79,9 +86,11 @@ div#buttons {
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
/*margin-left: .5rem;
margin-right: .5rem;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 1200px; max-width: 1600px;*/
} }
div#buttons button.button { div#buttons button.button {
@ -142,14 +151,16 @@ div#buttons #lockButtonLabel {
} }
div.ta { div.ta {
margin-left: auto; margin-left: .5rem;
margin-right: .5rem;
/*margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 1200px; max-width: 1600px;*/
} }
textarea#ta { textarea#ta {
position: relative; position: relative;
top: 3rem; top: 0;
display: none; display: none;
width: 100%; width: 100%;
height: 15rem; height: 15rem;
@ -171,6 +182,10 @@ div#cheezenotes:focus {
outline: none; outline: none;
} }
div#cheezenotes input.checkbox {
vertical-align: bottom;
}
div#cheezenotes div.line { div#cheezenotes div.line {
border-bottom: 1px solid #dddddd; border-bottom: 1px solid #dddddd;
padding-top: 0rem; padding-top: 0rem;
@ -321,16 +336,17 @@ div#cheezenotes div.lasttablerow span.tablerow {
div#cheezenotes div.cheezenotes_line span.token { div#cheezenotes div.cheezenotes_line span.token {
font-weight: 1; font-weight: 1;
color: #1353b3; color: transparent;
overflow: hidden; overflow: hidden;
}
div#cheezenotes div.cheezenotes_line span.token {
font-size: 0; font-size: 0;
vertical-align: baseline;
/*transition-property: font-size, color;
transition-duration: .2s;*/
} }
div#cheezenotes:focus div.cheezenotes_line span.token { div#cheezenotes:focus div.cheezenotes_line span.token {
font-size: 95%; color: #1353b3;
font-size: 90%;
} }
div#cheezenotes div.body { div#cheezenotes div.body {

@ -1,3 +1,18 @@
function insertAtLineStart(txtBefore) {
let ret = saveSelection();
let line = ret[0];
let txt = line.innerText;
if (txt == '\n') {
txt = "";
}
line.innerHTML = txtBefore + txt;
let span = document.createElement('span');
span.innerHTML = txtBefore;
ret[1] = ret[1] + span.innerText.length;;
ret[3] = ret[3] + span.innerText.length;;
loadSelection(ret);
}
function insertTextAtCaret(txtBefore, txtAfter = '') { function insertTextAtCaret(txtBefore, txtAfter = '') {
let ret = saveSelection(); let ret = saveSelection();
let line = ret[0]; let line = ret[0];
@ -190,4 +205,4 @@ function setEndPositionInText(obj, position) {
return 0; return 0;
} }
export { saveSelection, loadSelection, insertTextAtCaret }; export { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart };

@ -1,13 +1,13 @@
import { saveSelection, loadSelection, insertTextAtCaret } from './caret.js'; import { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart } from './caret.js';
import { formatLine, load, save, formatTable, redrawTables, appendData, dpwidth } from './md.js'; import { formatLine, load, save, formatTable, redrawTables, appendData, dpwidth } from './md.js';
const showtokens = [ const showtokens = [
{ fontSize: 0 }, { fontSize: 0 },
{ fontSize: '95%' } { fontSize: '90%' }
]; ];
const hidetokens = [ const hidetokens = [
{ fontSize: '95%' }, { fontSize: '90%' },
{ fontSize: 0 } { fontSize: 0 }
]; ];
@ -21,14 +21,14 @@ function timeoutSave() {
function showTokens() { function showTokens() {
let tokens = document.getElementsByClassName('token'); let tokens = document.getElementsByClassName('token');
for (let i = 0; i < tokens.length; i++) { for (let i = 0; i < tokens.length; i++) {
tokens[i].animate(showtokens, { duration: 200, iterations: 1 }); tokens[i].animate(showtokens, { duration: 50, iterations: 1 });
} }
} }
function hideTokens() { function hideTokens() {
let tokens = document.getElementsByClassName('token'); let tokens = document.getElementsByClassName('token');
for (let i = 0; i < tokens.length; i++) { for (let i = 0; i < tokens.length; i++) {
tokens[i].animate(hidetokens, { duration: 200, iterations: 1 }); tokens[i].animate(hidetokens, { duration: 50, iterations: 1 });
} }
} }
@ -82,7 +82,12 @@ function onh1button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('#', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('#&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -91,7 +96,12 @@ function onh2button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('##', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('##&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -100,7 +110,12 @@ function onh3button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('###', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('###&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -215,19 +230,6 @@ function oncopy(e) {
//alert(e.clipboardData.getData('text/plain')); //alert(e.clipboardData.getData('text/plain'));
} }
function onlockbutton(e) {
let lockButton = document.getElementById('lockButton');
let lockButtonLabel = document.getElementById('lockButtonLabel');
let cheezenotes = document.getElementById('cheezenotes');
if (lockButton.checked) {
cheezenotes.contentEditable = false;
lockButtonLabel.innerText = 'visibility';
} else {
cheezenotes.contentEditable = true;
lockButtonLabel.innerText = 'visibility_off';
}
}
function ondrag(e) { function ondrag(e) {
// alert('drag'); // alert('drag');
} }
@ -327,7 +329,7 @@ function onblur(e) {
disableFormatButtons(); disableFormatButtons();
} }
function onfocus() { function onfocus(e) {
redrawTables(cheezenotes, dpwidth()); redrawTables(cheezenotes, dpwidth());
showTokens(); showTokens();
enableFormatButtons(); enableFormatButtons();
@ -354,8 +356,10 @@ function onpopstate(e) {
}).catch((error) => { alert(error); }); }).catch((error) => { alert(error); });
} }
function init() { function init(domain, page) {
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
window.domain = domain;
window.page = page;
dpwidth(cheezenotes); dpwidth(cheezenotes);

@ -1,5 +1,15 @@
import { saveSelection, loadSelection } from "./caret.js"; import { saveSelection, loadSelection } from "./caret.js";
function setEditable() {
let editModeButton = document.getElementById('editModeButton');
let cheezenotes = document.getElementById('cheezenotes');
if (editModeButton.classList.contains('buttonoff')) {
cheezenotes.contentEditable = false;
} else {
cheezenotes.contentEditable = true;
}
}
function load(textarea, div) { function load(textarea, div) {
div.innerHTML = ''; div.innerHTML = '';
let lines = textarea.value.split('\n'); let lines = textarea.value.split('\n');
@ -89,22 +99,37 @@ function onlink(e) {
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
if (cheezenotes.contentEditable == 'false') { if (cheezenotes.contentEditable == 'false') {
e.preventDefault(); e.preventDefault();
cheezenotes.contentEditable = true; setEditable();
let link = e.currentTarget; let link = e.currentTarget;
if (link.host !== document.location.host) { if (link.host !== document.location.host) {
open(link.href); open(link.href);
} else { } else {
//open(link.href, '_self'); fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page).then((response) => {
fetch(link.href + "?data=").then((response) => {
let ta = document.getElementById('ta'); let ta = document.getElementById('ta');
response.text().then((data) => { response.text().then((data) => {
let content = document.getElementById('content'); let content = document.getElementById('content');
let left = content.scrollLeft; let left = content.scrollLeft;
let top = content.scrollTop; let top = content.scrollTop;
window.history.replaceState({top: top, left: left}, ""); window.history.replaceState({ top: top, left: left }, "");
window.history.pushState({}, "", link.href); window.history.pushState({}, "", link.href);
document.title = 'CheezeNotes - ' + link.getAttribute('data-href');
ta.value = data; ta.value = data;
load(document.getElementById('ta'), document.getElementById('cheezenotes')); let url = link.getAttribute('data-href').split('/');
let page = url[0];
let domain = window.domain;
if (url.length == 3) {
domain = url[1];
page = url[2];
}
window.domain = domain;
window.page = page;
load(document.getElementById('ta'), cheezenotes);
/*let editModeButton = document.getElementById('editModeButton');
if (editModeButton.classList.contains('buttonoff')) {
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.contentEditable = false;
}*/
content.scrollTop = 0; content.scrollTop = 0;
content.scrollLeft = 0; content.scrollLeft = 0;
}); });
@ -119,7 +144,7 @@ function onlink(e) {
function onlinkout(e) { function onlinkout(e) {
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
if (cheezenotes.contentEditable == 'false') { if (cheezenotes.contentEditable == 'false') {
cheezenotes.contentEditable = true; setEditable();
} }
} }
@ -149,21 +174,27 @@ function formatLine(line) {
} else if (line.match(/^\s*######(\s|$)/i)) { } else if (line.match(/^\s*######(\s|$)/i)) {
token = /^(\s*######(\s|$))/i; token = /^(\s*######(\s|$))/i;
elem.classList.add('h6'); elem.classList.add('h6');
elem.classList.add('h');
} else if (line.match(/^\s*#####(\s|$)/i)) { } else if (line.match(/^\s*#####(\s|$)/i)) {
token = /^(\s*#####(\s|$))/i; token = /^(\s*#####(\s|$))/i;
elem.classList.add('h5'); elem.classList.add('h5');
elem.classList.add('h');
} else if (line.match(/^\s*####(\s|$)/i)) { } else if (line.match(/^\s*####(\s|$)/i)) {
token = /^(\s*####(\s|$))/i; token = /^(\s*####(\s|$))/i;
elem.classList.add('h4'); elem.classList.add('h4');
elem.classList.add('h');
} else if (line.match(/^\s*###(\s|$)/i)) { } else if (line.match(/^\s*###(\s|$)/i)) {
token = /^(\s*###(\s|$))/i; token = /^(\s*###(\s|$))/i;
elem.classList.add('h3'); elem.classList.add('h3');
elem.classList.add('h');
} else if (line.match(/^\s*##(\s|$)/)) { } else if (line.match(/^\s*##(\s|$)/)) {
token = /^(\s*##(\s|$))/i; token = /^(\s*##(\s|$))/i;
elem.classList.add('h2'); elem.classList.add('h2');
elem.classList.add('h');
} else if (line.match(/^\s*#(\s|$)/i)) { } else if (line.match(/^\s*#(\s|$)/i)) {
token = /^(\s*#(\s|$))/i; token = /^(\s*#(\s|$))/i;
elem.classList.add('h1'); elem.classList.add('h1');
elem.classList.add('h');
} else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) { } else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) {
token = /^(\s*>\s*>\s*>(\s|$))/i; token = /^(\s*>\s*>\s*>(\s|$))/i;
elem.classList.add('bq3'); elem.classList.add('bq3');
@ -176,6 +207,14 @@ function formatLine(line) {
token = /^(\s*>(\s|$))/i; token = /^(\s*>(\s|$))/i;
elem.classList.add('bq1'); elem.classList.add('bq1');
elem.classList.add('bq'); elem.classList.add('bq');
} else if (line.match(/^\s*\[[xXvV]?\]\s+/i)) {
//token = /^(\s*\[[xXvV]?\]\s+)/i;
let checked = '';
if (line.match(/^\s*\[[xXvV]\]\s+/i)) {
checked = ' checked="checked"';
}
line = line.replace(/^(\s*\[[xXvV]?\]\s+)/i, '<input class="checkbox" type="checkbox"' + checked + '><span class="token">$1</span></input>')
elem.classList.add('checkbox');
} else { } else {
elem.classList.add('body'); elem.classList.add('body');
} }
@ -512,12 +551,37 @@ function addLink(line, listLink) {
return line; return line;
} }
function formatLink(line) { /*function formatLink(link) {
line = line.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/ig, '<span class="token">[!</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="$3">$2</img><span class="token">]($3)</span>'); link = link.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/i, '<span class="token">[!</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="$3">$2</img><span class="token">]($3)</span>');
line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '<span class="token">[</span><a class="link" data-href="$3" href="$3">$2</a><span class="token">]($3)</span>'); link = link.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/i, '<span class="token">[</span><a class="link" data-href="$3" href="$3">$2</a><span class="token">]($3)</span>');
line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '<span class="token">[</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">]()</span>'); link = link.replace(/(\[([^\]]+?)\]\(\))/i, '<span class="token">[</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">]()</span>');
line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '<span class="token">[](</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">)</span>'); link = link.replace(/(\[\]\(([^\)]+?)\))/i, '<span class="token">[](</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">)</span>');
return line; return link;
}*/
function formatLink(link) {
let matches = link.match(/\[(.*)\]\((.*)\)/);
let libelle = matches[1];
let url = matches[2];
if (url == '' && libelle == '') {
return link;
}
let href = url;
if (href == '') {
href = libelle;
}
if (href.match(/^[^\:\/]+\/.*$/)) {
href = '/' + href;
}
if (libelle == '') {
return '<span class="token">[](</span><a class="link" data-href="' + href + '" href="' + href + '">' + url + '</a><span class="token">)</span>';
} else {
if (libelle.startsWith('!')) {
return '<span class="token">[' + libelle + '</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="' + href + '" title="' + libelle.substring(1) + '" /><span class="token">](' + url + ')</span>';
} else {
return '<span class="token">[</span><a class="link" data-href="' + href + '" href="' + href + '">' + libelle + '</a><span class="token">](' + url + ')</span>';
}
}
} }
function addBold(line) { function addBold(line) {

@ -7,10 +7,13 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>{{name}}</title> <title>{{app_name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css"> <link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
</head> </head>
<body> <body>
<h1></h1> <h1>{{app_name}}</h1>
{% for domain in domains %}
<p class="domain"><a href="{{ base_url|safe }}{{ domain.domain }}">{{ domain.domain_name }}</a></p>
{% endfor %}
</body> </body>
</html> </html>

@ -9,9 +9,9 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>{{name}}</title> <title>{{app_name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css"> <link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
<script type="module" src="{{ root|safe }}static/modules/cheezenotes.js"></script> <script type="module" src="{{ base_url|safe }}static/modules/cheezenotes.js"></script>
</head> </head>
<body> <body>
@ -23,7 +23,7 @@
</div> </div>
</div> </div>
<script type="module"> <script type="module">
import { init } from '{{ root|safe }}static/modules/cheezenotes.js'; import { init } from '{{ base_url|safe }}static/modules/cheezenotes.js';
{{ init|safe }} {{ init|safe }}
</script> </script>
</body> </body>

Loading…
Cancel
Save