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

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

@ -1,5 +1,11 @@
create table pages (
page_name text primary key,
domain text,
page_name 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 /
#[arg(short, long, default_value_t = String::from("/"))]
pub root: String,
/// sqlite database path
#[arg(short, long, default_value_t = String::from("db/db.sqlite3"))]
pub db: String,
}
impl Arguments {
@ -26,7 +29,7 @@ impl Arguments {
#[derive(Clone)]
pub struct AppData {
pub name: String,
pub root: String,
pub pool: Pool<SqliteConnectionManager>,
pub app_name: String,
pub base_url: String,
pub db_pool: Pool<SqliteConnectionManager>,
}

@ -1,16 +1,55 @@
use actix_web::{error, web, Error};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type Pool = r2d2::Pool<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)]
pub struct Page {
pub domain: String,
pub page_name: 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 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 || {
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 {
page_name: row.get(0)?,
page_text: row.get(1)?,
domain: row.get(0)?,
page_name: row.get(1)?,
page_text: row.get(2)?,
})
})
.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)
}
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 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 || {
let mut stmt = conn
.prepare("insert or replace into pages (page_name, page_text, active) values (?, ?, true)")?;
stmt.execute([page_name, page_text, ])
.prepare("insert or replace into pages (domain, page_name, page_text, active) values (?, ?, ?, true)")?;
stmt.execute([domain, page_name, page_text, ])
})
.await?
.map_err(error::ErrorInternalServerError)
}

@ -5,17 +5,23 @@ use askama_actix::Template;
use askama_actix::TemplateToResponse;
use crate::commons::AppData;
use crate::db;
use crate::db::Domain;
#[derive(Template)]
#[template(path = "index.html")]
pub struct PageTemplate {
pub name: String,
pub root: String,
pub app_name: String,
pub base_url: String,
pub domains: Vec<Domain>,
}
#[get("/")]
async fn index(data: web::Data<AppData>) -> impl Responder {
let name = data.name.to_owned();
let root = data.root.to_owned();
PageTemplate { name, root }.to_response()
let app_name = data.app_name.to_owned();
let base_url = data.base_url.to_owned();
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 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 appdata = AppData {
name: String::from("CheezeNotes"),
root,
pool: pool.clone(),
app_name: String::from("CheezeNotes"),
base_url,
db_pool: pool.clone(),
};
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(appdata.to_owned()))
.service(index::index)
.service(page::page)
.service(page::save_page)
.service(actix_files::Files::new("/static", "./static"))
.service(actix_files::Files::new("/static/modules", "./static/modules"))
.service(page::page)
.service(page::save_page)
})
.bind((ip, port))?
.run()

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

@ -35,6 +35,11 @@ body {
background-color: #dddddd;
}
p.domain {
padding-left: 2rem;
font-size: 2rem;
}
div#content {
position: absolute;
margin: 0;
@ -47,9 +52,11 @@ div#content {
}
div#margindiv {
max-width: 1200px;
/*max-width: 1600px;
margin-left: auto;
margin-right: auto;
margin-right: auto;*/
margin-left: .5rem;
margin-right: .5rem;
top: 0;
bottom: 0;
}
@ -60,8 +67,8 @@ div#cheezenotes {
margin-top: 0;
margin-bottom: 3rem;
padding-top: 1rem;
padding-left: 3rem;
padding-right: 3rem;
padding-left: 1rem;
padding-right: 1rem;
padding-bottom: 1rem;
background-color: #ffffff;
min-height: 100%;
@ -79,9 +86,11 @@ div#buttons {
top: 0;
left: 0;
right: 0;
/*margin-left: .5rem;
margin-right: .5rem;
margin-left: auto;
margin-right: auto;
max-width: 1200px;
max-width: 1600px;*/
}
div#buttons button.button {
@ -142,14 +151,16 @@ div#buttons #lockButtonLabel {
}
div.ta {
margin-left: auto;
margin-left: .5rem;
margin-right: .5rem;
/*margin-left: auto;
margin-right: auto;
max-width: 1200px;
max-width: 1600px;*/
}
textarea#ta {
position: relative;
top: 3rem;
top: 0;
display: none;
width: 100%;
height: 15rem;
@ -171,6 +182,10 @@ div#cheezenotes:focus {
outline: none;
}
div#cheezenotes input.checkbox {
vertical-align: bottom;
}
div#cheezenotes div.line {
border-bottom: 1px solid #dddddd;
padding-top: 0rem;
@ -321,16 +336,17 @@ div#cheezenotes div.lasttablerow span.tablerow {
div#cheezenotes div.cheezenotes_line span.token {
font-weight: 1;
color: #1353b3;
color: transparent;
overflow: hidden;
}
div#cheezenotes div.cheezenotes_line span.token {
font-size: 0;
vertical-align: baseline;
/*transition-property: font-size, color;
transition-duration: .2s;*/
}
div#cheezenotes:focus div.cheezenotes_line span.token {
font-size: 95%;
color: #1353b3;
font-size: 90%;
}
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 = '') {
let ret = saveSelection();
let line = ret[0];
@ -190,4 +205,4 @@ function setEndPositionInText(obj, position) {
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';
const showtokens = [
{ fontSize: 0 },
{ fontSize: '95%' }
{ fontSize: '90%' }
];
const hidetokens = [
{ fontSize: '95%' },
{ fontSize: '90%' },
{ fontSize: 0 }
];
@ -21,14 +21,14 @@ function timeoutSave() {
function showTokens() {
let tokens = document.getElementsByClassName('token');
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() {
let tokens = document.getElementsByClassName('token');
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();
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus();
insertTextAtCaret('#', '');
let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('#&nbsp;');
}
onedit(e);
return false;
}
@ -91,7 +96,12 @@ function onh2button(e) {
e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus();
insertTextAtCaret('##', '');
let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('##&nbsp;');
}
onedit(e);
return false;
}
@ -100,7 +110,12 @@ function onh3button(e) {
e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus();
insertTextAtCaret('###', '');
let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('###&nbsp;');
}
onedit(e);
return false;
}
@ -215,19 +230,6 @@ function oncopy(e) {
//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) {
// alert('drag');
}
@ -327,7 +329,7 @@ function onblur(e) {
disableFormatButtons();
}
function onfocus() {
function onfocus(e) {
redrawTables(cheezenotes, dpwidth());
showTokens();
enableFormatButtons();
@ -354,8 +356,10 @@ function onpopstate(e) {
}).catch((error) => { alert(error); });
}
function init() {
function init(domain, page) {
let cheezenotes = document.getElementById('cheezenotes');
window.domain = domain;
window.page = page;
dpwidth(cheezenotes);

@ -1,5 +1,15 @@
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) {
div.innerHTML = '';
let lines = textarea.value.split('\n');
@ -89,13 +99,12 @@ function onlink(e) {
let cheezenotes = document.getElementById('cheezenotes');
if (cheezenotes.contentEditable == 'false') {
e.preventDefault();
cheezenotes.contentEditable = true;
setEditable();
let link = e.currentTarget;
if (link.host !== document.location.host) {
open(link.href);
} else {
//open(link.href, '_self');
fetch(link.href + "?data=").then((response) => {
fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page).then((response) => {
let ta = document.getElementById('ta');
response.text().then((data) => {
let content = document.getElementById('content');
@ -103,8 +112,24 @@ function onlink(e) {
let top = content.scrollTop;
window.history.replaceState({ top: top, left: left }, "");
window.history.pushState({}, "", link.href);
document.title = 'CheezeNotes - ' + link.getAttribute('data-href');
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.scrollLeft = 0;
});
@ -119,7 +144,7 @@ function onlink(e) {
function onlinkout(e) {
let cheezenotes = document.getElementById('cheezenotes');
if (cheezenotes.contentEditable == 'false') {
cheezenotes.contentEditable = true;
setEditable();
}
}
@ -149,21 +174,27 @@ function formatLine(line) {
} else if (line.match(/^\s*######(\s|$)/i)) {
token = /^(\s*######(\s|$))/i;
elem.classList.add('h6');
elem.classList.add('h');
} else if (line.match(/^\s*#####(\s|$)/i)) {
token = /^(\s*#####(\s|$))/i;
elem.classList.add('h5');
elem.classList.add('h');
} else if (line.match(/^\s*####(\s|$)/i)) {
token = /^(\s*####(\s|$))/i;
elem.classList.add('h4');
elem.classList.add('h');
} else if (line.match(/^\s*###(\s|$)/i)) {
token = /^(\s*###(\s|$))/i;
elem.classList.add('h3');
elem.classList.add('h');
} else if (line.match(/^\s*##(\s|$)/)) {
token = /^(\s*##(\s|$))/i;
elem.classList.add('h2');
elem.classList.add('h');
} else if (line.match(/^\s*#(\s|$)/i)) {
token = /^(\s*#(\s|$))/i;
elem.classList.add('h1');
elem.classList.add('h');
} else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) {
token = /^(\s*>\s*>\s*>(\s|$))/i;
elem.classList.add('bq3');
@ -176,6 +207,14 @@ function formatLine(line) {
token = /^(\s*>(\s|$))/i;
elem.classList.add('bq1');
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 {
elem.classList.add('body');
}
@ -512,12 +551,37 @@ function addLink(line, listLink) {
return line;
}
function formatLink(line) {
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>');
line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '<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>');
line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '<span class="token">[](</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">)</span>');
return line;
/*function formatLink(link) {
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>');
link = link.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/i, '<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="$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 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) {

@ -7,10 +7,13 @@
<meta name="apple-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">
<title>{{name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css">
<title>{{app_name}}</title>
<link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
</head>
<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>
</html>

@ -9,9 +9,9 @@
<meta name="apple-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">
<title>{{name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css">
<script type="module" src="{{ root|safe }}static/modules/cheezenotes.js"></script>
<title>{{app_name}}</title>
<link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
<script type="module" src="{{ base_url|safe }}static/modules/cheezenotes.js"></script>
</head>
<body>
@ -23,7 +23,7 @@
</div>
</div>
<script type="module">
import { init } from '{{ root|safe }}static/modules/cheezenotes.js';
import { init } from '{{ base_url|safe }}static/modules/cheezenotes.js';
{{ init|safe }}
</script>
</body>

Loading…
Cancel
Save