Commit 7469efe5 authored by okhin's avatar okhin 🚴

Attachons les fichiers

parent 6b3f2301
Pipeline #2528 failed with stages
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2016 Okhin
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
<?php
/* ----------------------
Mise à jour du serveur
---------------------- */
// L'emplacement du fichier contenant le menu
$file = "../server/menu.json";
// L'emplacement du fichier contenant les éléments supprimés
$deletedFile = "../server/deleted.json";
// Lorsque reçoit une demande de mise à jour du serveur
if (isset($_POST['updateServer']))
{
// Recupère l'objet principal contenu dans le fichier
$content = json_decode(file_get_contents($file));
// Recupère le type de la modification, spécifié par la demande
$type = $_POST['updateServer'];
// Recupère le contenu de la modification, spécifié par la demande
$info = $_POST['info'];
// Recupère la position de l'élément du menu à partir duquel faire la modification, spécifiée par la demande
$path = str_split($_POST['path']);
// Renomme
if ($type == "newName")
$content = newName($content, $info, $path);
// Ajoute
else if ($type == "newPage" || $type == "newFolder")
$content = addElement($content, $info, $path, $type);
// Déplace
else if ($type == "move")
$content = moveElement($content, $info, $path);
// Supprime
else if ($type == "delete")
$content = deleteElement($content, $path);
// Met à jour l'objet principal du fichier
file_put_contents ($file, json_encode($content));
// Envoie au client le contenu du tableau de l'objet principal
echo json_encode($content->content);
}
/* ----------------------
Créer un élément
---------------------- */
function createElement($title, $type)
{
// Crée un nouvel élément
$element = new stdClass;
// Donne au nouvel élément le titre celui indiquée par la demande
$element->title = $title;
// Donne au nouvel élément un ID aléatoire
$element->id = rand(10000000, 99999999);
// Si la demande concerne l'ajout d'une page
if ($type == "newPage")
{
// Donne à l'élément le type "page"
$element->type = "page";
}
// Si la demande concerne l'ajout d'un dossier
else if ($type == "newFolder")
{
// Donne à l'élément le type "folder"
$element->type = "folder";
// Donne à l'élément un tableau qui contiendra ses sous-éléments
$element->content = [];
}
return $element;
}
/* ----------------------
Récupérer un élément
---------------------- */
function getElement($content, $path)
{
$element = $content;
for ($i = 0; $i < count($path); $i++)
{
$element = $element->content[$path[$i]];
}
return $element;
}
/* ----------------------
Récupérer le parent d'un élément
---------------------- */
function getParent($content, $path)
{
$element = $content;
for ($i = 0; $i < count($path) -1; $i++)
{
$element = $element->content[$path[$i]];
}
return $element;
}
/* ----------------------
Renomer
---------------------- */
function newName($content, $info, $path)
{
// Recupère l'élément
$element = getElement($content, $path);
// Donne à l'élément le titre indiqué
$element->title = $info;
// Renvoie l'objet principal modifié
return $content;
}
/* ----------------------
Insérer
---------------------- */
function insertElement($content, $path, $element)
{
// Recupère l'élément cliqué (en fonction duquel le nouvel élément doit être ajouté)
$syb = getElement($content, $path);
// Si l'élément cliqué est un dossier
if ($syb->type == "folder")
{
// Ajoute le nouvel élément au début du dossier
array_unshift($syb->content, $element);
}
// Si l'élément cliqué est une page
else if ($syb->type == "page")
{
// Recupère le dossier parent de la page cliquée
$parent = getParent($content, $path);
// Ajoute le nouvel élément dans le dossier parent, après la page cliquée
array_splice( $parent->content, $path[ count($path) -1 ] +1 , 0, array ( $element ) );
}
return $content;
}
/* ----------------------
Ajouter un nouvel élément
---------------------- */
function addElement($content, $info, $path, $type)
{
// Crée un nouvel élément
$newElement = createElement($info, $type);
return insertElement($content, $path, $newElement);
}
/* ----------------------
Déplacer
---------------------- */
function moveElement($content, $pathTo, $path)
{
$pathTo=str_split($pathTo);
// Vérifie que l'élément à déplacer n'est pas un parent du dossier où on cherche à le déplacer
$continue = false;
if ( count($pathTo) >= count($path) )
{
for ($i = 0; $i < count($path) AND $continue == false; $i++)
{
if ( $pathTo[$i] != $path[$i] )
$continue = true;
}
}
else
{
$continue = true;
}
if ($continue)
{
// Récupère l'élément à déplacer
$element = getElement($content, $path);
// Récupère le parent de l'élément à déplacer
$parent = getParent($content, $path);
// Fait une cope de l'élément à déplacer
$elementCopy = clone $element;
// Indique que l'original de l'élément à déplacé doit être supprimé
$element->type = "removed";
// Insère la copie de l'élément à déplacer à l'endroit indiqué
$content = insertElement($content, $pathTo, $elementCopy);
// Supprime l'original de l'élément à déplacer
for ($i = 0; $i < count($parent->content); $i++)
{
if ($parent->content[$i]->type == "removed")
array_splice( $parent->content, $i , 1 );
}
}
return $content;
}
/* ----------------------
Supprimer
---------------------- */
function deleteElement($content, $path)
{
// Récupère l'élément à supprimer
$element = getElement($content, $path);
// Récupère son parent
$parent = getParent($content, $path);
// Met l'élément dans le fichier des éléments supprimés
file_put_contents ("server/deleted.json", json_encode( $element ), FILE_APPEND );
// Supprime l'élément de son parent
array_splice( $parent->content, $path[ count($path) -1 ] , 1 );
// Renvoie l'objet principal modifié
return $content;
}
?>
function click (e)
{
// Si le clic est fait alors que l'option de déplacement est en cours
if (option.move.active)
{
// Clic gauche
if (e.button == 0)
{
// Active le déplacement à partir de l'élément cliqué
option.move.from(this);
}
// Autre
else
{
e.preventDefault();
option.move.stop();
}
}
// Clic gauche
else if (e.button == 0)
{
// Si l'élément cliqué est le titre d'une page
if (this.classList.contains("page_title"))
{
// Ouvre la page dans l'iframe du pad
pad.open(this);
}
// Si l'élément cliqué est le titre d'un dossier
else if (this.classList.contains("folder_title"))
{
// Change la classe CSS du dossier
if (!this.classList.contains("open"))
{
this.classList.add("open");
}
else
{
this.classList.remove("open");
}
}
}
// Clic droit
else if (e.button == 2)
{
// Empêche l'option du navigateur de s'ouvrir (le clic droit par défaut)
e.preventDefault();
// Ouvre l'option, en lui passant l'élément cliqué et la position de la sourie
option.open(this, e.clientX, e.clientY);
}
}
// Construit chaque élément HTML du menu, à partir de son parent ("element") et de sa place sous ce parent ("index")
function construct ( element , index )
{
// Crée le <li> qui contiendra le titre de l'élément, et lui donne comme classe CSS le type de l'élément ("page" ou "folder")
var item = document.createElement("li");
item.innerHTML = element.title;
item.classList.add(element.type + "_title");
// Retient la position de l'élément dans la hiérarchie du menu, à partir de la position de l'élément parent ("this")
item.path = this.path + index;
// Associe le clic (gauche ou droite) à la fonction appropriée (définie dans < clickMenu.js >)
item.onclick = item.oncontextmenu = click;
// Intègre le <li> dans le <div> de son parent ("this")
this.appendChild(item);
// Donne à l'élément son ID
item.id = element.id;
// Si l'élément est une page
if (element.type == "page")
{
// Si aucune page par défaut n'est encore définit
if ( pad.def == null )
{
// Fait de la première page rencontrée celle ouverte par défaut
pad.def = item;
}
// Si l'ID de la page est celui indiqué dans l'URL
if ( element.id == parseInt ( window.location.hash.slice (1) ) )
{
// Fait de la page celle ouverte au démarage
pad.current = item;
}
}
// Si l'élément est un dossier
else if (element.type == "folder")
{
// Crée le <ul> qui contiendra les éléments du dossier
item.folder = document.createElement("ul");
// Donne à <ul> la classe CSS appropriée
item.folder.classList.add("folder_content");
// Conserve dans <ul> la même position que l'élément principal (pour le transmettre aux enfants)
item.folder.path = item.path;
// Construit les éléments du dossier, l'un après l'autre, en passant l'élément <ul> en paramètre
element.content.forEach(construct, item.folder);
// Intègre l'élement <ul> du dossier à l'élément
this.appendChild(item.folder);
}
}
<!DOCTYPE html><html>
<head>
<title>Le carré</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
<!-- Initialise la page -->
<script src="init.js"></script>
<!-- Construit le menu -->
<script src="construct.js"></script>
<!-- Répond aux clics sur le menu -->
<script src="click.js"></script>
<!-- Actions modifiant le menu -->
<script src="option.js"></script>
<!-- Met à jour le serveur -->
<script src="update.js"></script>
<!-- Affiche les pages dans le pad -->
<script src="pad.js"></script>
<!-- Applet IRC -->
<script src="irc.js"></script>
</html>
// Lorsque la page et ses scripts sont chargés
onload = function ()
{
// Ajoute un ément HTML pour contenir le menu
menu = document.createElement("menu");
menu.id = "menu";
menu.path= "";
// Crée le titre du menu
menu.tag = document.createElement("div");
menu.tag.classList.add("main_title");
menu.img = document.createElement("img");
menu.img.src = "lqdn.svg";
menu.tag.appendChild(menu.img);
menu.h1 = document.createElement("h1");
menu.h1.innerHTML = "Le carré";
menu.tag.appendChild(menu.h1);
menu.appendChild(menu.tag);
document.body.appendChild(menu);
// Établie une connexion avec le serveur
server = new XMLHttpRequest();
server.open("POST", 'updateClient.php', true);
server.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Demande au serveur le contenu du menu
server.send("updateClient=1");
// Lorsque la réponse à la requête est reçue
server.onreadystatechange = function()
{
if (this.readyState == XMLHttpRequest.DONE && this.status == 200)
{
// Récupère le menu et le parse dans un tableau
var response = JSON.parse(server.responseText);
// Construit le menu à partir de chacun de ses éléments de premier niveau
response.forEach(construct, menu);
// Initialise le pad
pad.start();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 142 144" style="enable-background:new 0 0 142 144;" xml:space="preserve">
<g>
<g>
<path d="M-0.5,30.2C6.8,17.5,17.3,7,29.8-0.4H-0.5V30.2"/>
<path d="M-0.5,113.5v30.6h30.3C17.3,136.8,6.8,126.2-0.5,113.5"/>
<path d="M142.4,113.3c-7.3,12.8-17.8,23.4-30.4,30.8h30.4V113.3z"/>
<path d="M112.1-0.4c12.6,7.4,23.1,18,30.4,30.7V-0.4H112.1z"/>
<path d="M58.6,37h52.7v11.4H92.1l-1.7,23.7c-0.3,4.1-0.4,7.6-0.4,10.6c0,7.2,0.9,11.6,2.6,13.2c1.8,1.6,4,2.3,6.5,2.3 c5.3,0,8.4-3.1,9.4-9.4h3c-1.8,14.4-7.9,21.6-18.3,21.6c-4.8,0-8.8-1.4-11.8-4.2c-2.9-2.8-4.3-7-4.3-12.5c0-3.6,0.5-11.3,1.7-23 L81,48.4H63.5c-1.2,18.9-2.6,32.7-4.2,41.4c-1.6,8.7-3.4,14.3-5.3,16.9c-1.9,2.5-4.6,3.8-7.9,3.8c-2.5,0-4.7-0.7-6.5-2.1 c-1.7-1.4-2.5-3.2-2.5-5.5c0-2.2,1.5-5.1,4.4-8.9c4.3-5.5,7.6-11.3,9.7-17.2c2.1-6,3.8-15.4,4.9-28.4h-5.6c-4.5,0-8,1-10.4,2.9 c-2.4,1.9-4.6,4.5-6.7,8.1h-3c1.6-5.6,3.7-10.1,6.2-13.7c2.5-3.6,5.1-5.9,7.8-7C47,37.5,51.7,37,58.6,37 M70.9,4.4 C34.1,4.4,4.2,34.6,4.2,71.8c0,37.2,29.9,67.5,66.7,67.5s66.8-30.3,66.8-67.5C137.7,34.6,107.8,4.4,70.9,4.4 M-0.5,30.2"/>
</g>
</g>
</svg>
\ No newline at end of file
// Élément HTML du menu d'options
var option = document.createElement("div");
option.id = "option";
option.classList.add("hidden");
document.body.appendChild(option);
// Ouverture du menu
option.open = function ( element, x, y )
{
this.target = element;
this.classList.remove("hidden");
this.style.left = (x - 20) + "px";
this.style.top = (y - 10) + "px";
// Affiche/ cache l'option "ouvrir dans un nouvel onglet" si l'élément est une page/ un dossier
if (element.classList.contains("page_title") && option.newTab.classList.contains("hidden"))
option.newTab.classList.remove("hidden");
else if (element.classList.contains("folder_title") && !option.newTab.classList.contains("hidden"))
option.newTab.classList.add("hidden");
}
// Fermeture du menu (lorsqu'appelée ou lorsque la sourie sors de l'élément HTML)
option.close = option.onmouseleave = function ()
{
this.classList.add("hidden");
}
// Ouvrir dans un nouvel onglet (seulement pour les pages)
option.newTab = document.createElement("div");
option.newTab.link = document.createElement("a");
option.newTab.link.target = "_blank";
option.newTab.link.innerHTML = "Ouvrir dans un nouvel onglet";
option.newTab.onclick = function()
{
this.link.href = pad.adress + option.target.id;
};
option.newTab.appendChild(option.newTab.link);
option.appendChild(option.newTab);
// Renommer un élément
option.rename = document.createElement("div");
option.rename.innerHTML = "Renommer";
option.rename.onclick = function()
{
var name = prompt("Renommer", option.target.innerHTML);
if (name != null)
{
update("newName", name, option.target.path);
}
}
option.appendChild(option.rename);
// Ajouter une page
option.newPage = document.createElement("div");
option.newPage.innerHTML = "Ajouter une page";
option.newPage.onclick = function()
{
var name = prompt("Titre de la nouvelle page");
if (name != null)
{
update("newPage", name, option.target.path);
}
}
option.appendChild(option.newPage);
// Ajouter un dossier
option.newFolder = document.createElement("div");
option.newFolder.innerHTML = "Ajouter un dossier";
option.newFolder.onclick = function()
{
var name = prompt("Titre du nouveau dossier");
if (name != null)
{
update("newFolder", name, option.target.path);
}
}
option.appendChild(option.newFolder);
// Déplacer
option.move = document.createElement("div");
option.move.innerHTML = "Déplacer";
option.move.active = false;
option.move.onclick = function()
{
var elements = menu.getElementsByTagName("li");
for (var i = 0; i < elements.length; i++)
{
elements[i].style.cursor = "s-resize";
}
option.move.active = true;
option.close();
}
option.move.from = function (from)
{
update("move", from.path, option.target.path);
this.stop();
}
option.move.stop = function()
{
var elements = menu.getElementsByTagName("li");
for (var i = 0; i < elements.length; i++)
{
elements[i].style.cursor = "pointer";
}
option.move.active = false;
}
option.appendChild(option.move);
// Supprime
option.deleted = document.createElement("div");
option.deleted.innerHTML = "Supprimer";
option.deleted.onclick = function()
{
if (confirm("Voulez-vous vraiment supprimer " + (option.target.classList.contains("page_title") ? "la page" : "le dossier") + " <" + option.target.innerHTML + "> ?"))
update("delete", "", option.target.path);
option.close();
}
option.appendChild(option.deleted);
// Iframe du pad
var pad = document.createElement("iframe");
pad.adress = "https://pad.technopolice.fr/p/carre_";
pad.id = "pad";
pad.current = null;
pad.def = null;
// Ouvre une nouvelle page dans le pad
pad.open = function (element)
{
this.src = this.adress + element.id;
if (this.current != null)
{
this.current.classList.remove("selected");
}
this.current = element;
this.current.classList.add("selected");
window.location.hash = element.id;
}
// Démarre le pad
pad.start = function()
{
// Intègre l'iframe
document.body.appendChild(pad);
// Si aucune page n'est visée dans le hash de l'URL
if (this.current == null)
{
// Vise la page par défaut
this.current = this.def;
}
// Ouvre la page
pad.open(this.current);
// Déplie les dossiers correspondants dans le menu
var child = this.current;
for (var i = 0; i < this.current.path.length-1; i++)
{
var parent = child.parentNode.previousSibling;
parent.classList.add("open");
child = parent;
}
}
@font-face {
font-family: "aileronregular";
font-style: normal;
font-weight: normal;
src: url("fonts/aileron-regular-webfont.woff2") format("woff2"), url("webfonts/aileron-regular-webfont.woff") format("woff");
}
@font-face {
font-family: "aileronheavy";
font-style: normal;
font-weight: normal;
src: url("fonts/aileron-heavy-webfont.woff2") format("woff2"), url("webfonts/aileron-heavy-webfont.woff") format("woff");
}
body
{
margin: 0;
font-family: sans-serif;
background: #eee;
display: flex;
max-width: 1600px;
margin: auto;
font-family: "aileronregular";
}
#wiki, #pad, #irc
{
height: 100vh;
border: none;
}
#pad
{
flex: 10 1 800px;
}
#irc
{
flex: 1 10 550px;
padding-left: 10px;
opacity: 0;
}
#menu
{
flex: 1 2 250px;
padding-top: 0px;
padding-left: 30px;
}
#menu .main_title img
{
width: 3em;
margin-right: 10px;
}
#menu .main_title h1
{
width: 65%;
font-weight: normal;
font-family: "aileronheavy";
margin: 0;
display: inline-block;
margin-bottom: .4em;
}
#menu li
{
font-size: .9em;
color: #444;
font-weight: normal;
cursor: pointer;
padding: .3em 0em;
list-style-position: inside;
}
#menu li:hover
{
text-decoration: underline;
}
#menu ul
{
margin: 0;
padding: 0;
margin-bottom: .5em;