Last active
September 16, 2023 16:49
-
-
Save 0gust1/260638bd34a434e7f3dd to your computer and use it in GitHub Desktop.
Footnotes to sidenote, and maybe links to sidenotes ?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Generate sidenotes using footnotes from Multimarkdown generated content | |
* Idea and principle borrowed from Adrew Clark : http://acdlite.github.io/jquery.sidenotes/ and https://github.com/acdlite/jquery.sidenotes | |
* | |
* This script : - gather footnotes in the passed container selector | |
* - insert the sidenotes in the current text, according to screen size : | |
* - on big screens insert the sidenote *before* the anchor | |
* - on medium screens, insert the sidenote *after* the anchor | |
/** | |
* Gather footnotes and build an array of "sidenotes" ready to be inserted in DOM ? | |
* Not used ATM | |
* @param {String} selector for the container to processfootnotes | |
*/ | |
var processFootNotesToSideNotes = function processFootNotesToSideNotes(rootSel){ | |
var footNotes = document.querySelectorAll(rootSel+' .footnotes ol li'), | |
sidenotes = [], | |
i = 1; //Note numbering | |
//Each footnote | |
Array.prototype.forEach.call(footNotes,function(note){ | |
//console.log('test'); | |
//var docFragment = document.createDocumentFragment(); | |
var noteNode = document.createElement('aside'); | |
var id = note.id.replace('fn:',''); | |
noteNode.classList.add('footnote'); | |
noteNode.setAttribute('data-ref',i); | |
//Append footnote childrens to the sidenote | |
Array.prototype.forEach.call(note.childNodes,function(noteChild){ | |
noteNode.appendChild(noteChild.cloneNode(true)); | |
}); | |
var sidenote = {}; | |
sidenote.id= id; | |
sidenote.node = noteNode; | |
sidenote.num = i; | |
sidenotes.push(sidenote); | |
i++; | |
}); | |
return sidenotes; | |
}; | |
/** | |
*Render sidenotes for large screens : "Sidenotes" | |
*/ | |
var renderSideNotesLarge = function renderSideNotesLarge(sidenotes){ | |
//place sidenotes into the DOM, just before the anchor ref. | |
//remove any previously rendered infocards and/or hide original footnotes | |
}; | |
/** | |
*Render sidenotes for medium screens : "InfoCards" | |
*/ | |
var renderSideNotesMedium = function renderSideNotesMedium(sidenotes){ | |
//place sidenotes into the DOM, just after the anchor ref. | |
//remove any previously rendered sidenotes and/or hide original footnotes | |
}; | |
/** | |
*Render sidenotes for medium screens : "classic footnotes" | |
*/ | |
var renderSideNotesSmall = function renderSideNotesSmall(sidenotes){ | |
//basically, let the original footnotes appear again | |
//hide/remove any previously inserted sidenotes or infocards | |
}; | |
/** | |
* Generate sidenotes using footnotes from Multimarkdown generated content | |
* Idea and principle borrowed from Adrew Clark : http://acdlite.github.io/jquery.sidenotes/ and https://github.com/acdlite/jquery.sidenotes | |
* | |
* This script : - gather footnotes in the current container | |
* - insert the sidenotes in the current text, according to screen size : | |
* - on big screens insert the sidenote *before* the anchor | |
* - on medium screens, insert the sidenote *after* the anchor | |
* | |
* TODO : parametrize selector for footnotes | |
* : parametrize classes and tags generated | |
* : bind a resize event to replace sidenotes when screen size changes | |
* | |
* @param {String} selector for the container to process | |
*/ | |
var processFootNotes = function processFootNotes(rootSel){ | |
var footNotes = document.querySelectorAll(rootSel+' .footnotes ol li'); | |
console.log(footNotes); | |
var i = 1; //Note numbering | |
//Each footnote | |
Array.prototype.forEach.call(footNotes,function(note){ | |
//console.log('test'); | |
//var docFragment = document.createDocumentFragment(); | |
var noteNode = document.createElement('aside'); | |
var id = note.id.replace('fn:',''); | |
//noteNode.id = id; | |
noteNode.classList.add('footnote'); | |
noteNode.setAttribute('data-ref',i); | |
//Append footnote childrens to the sidenote | |
Array.prototype.forEach.call(note.childNodes,function(noteChild){ | |
noteNode.appendChild(noteChild.cloneNode(true)); | |
}); | |
console.log(noteNode.innerHTML); | |
//append the sidenote along the pointing anchor | |
var anchor = document.getElementById('fnref:'+id); | |
//get the anchor parent element (a <p>) | |
var anchorParent = anchor.parentElement.parentElement; | |
/* big screens */ | |
//insert before : wide screen | |
anchorParent.insertBefore(noteNode, anchor.parentElement); | |
/* medium screens */ | |
//insert after : medium screen | |
//anchorParent.insertBefore(noteNode, anchor.nextSibling); | |
/* small screens */ | |
//no need for JS, just hide the sidenotes and show th footnotes via media queries | |
i++; | |
}); | |
}; | |
//module.exports = processFootNotes; | |
Quelques réflexions en vrac :
- pour le responsive, je ne suis pas sûr que cela soit pertinent de rétablir les footnotes pour les petits écrans, au contraire c'est sous cette contrainte que je n'ai pas envie de faire des aller-retours mais d'avoir de l'info contextuelle
- pour les performances aux passages de breakpoints, il faut bien voir que ça ne concerne quasi que les développeurs, les utilisateurs ne s'amusent pas trop à redimensionner leurs fenêtres ;)
- pour le packaging il me semble que l'on peut proposer l'ensemble des solutions les plus populaires mais je suis très naïf là-dessus
- pour les commentaires décentralisés, il manque la notion d'invalidation du cache mais ça peut se travailler <3 Voir à ce sujet http://jakearchibald.com/2014/offline-cookbook/
Merci davidbgk.
- Oui, carrement, je crois que j'était fatigué ^^ J'aurais aimé tester néanmoins (avec différents volumes de contenu, et de notes).
- Je ne fais pas partie de ce genre de dev-front / webdesigners ;) Je pensais surtout au passage portrait / paysage sur tablette et mobile.
- Faire plusieurs "builds" ? À creuser.
- J'adore ce genre d'idées, malheureusement, techniquement, je suis trop lent, pas assez doué et je manque de temps pour le moment pour bidouiller des trucs.
Merci pour ton retour, ça aide. Je vais essayer d'avancer dessus ce week-end.
Bon, j'ai avancé. ça commence à prendre forme.
cf : https://github.com/0gust1/md-vanilla-sidenotes
Là, je commence à réfléchir sur la meilleur façon d'organiser le code pour offrir le maximum d'extensibilité (par rapport à ton idée, par exemple).
Je continue dans les issues du repo. Merci encore.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bon, c'est vraiment le debut du truc... c'est vraiment pas sec. Pour l'instant, seule la fonction
processFootNotes
fonctionne et me sert à tester. J'ai créé un repo (quasi vide pour l'instant) :https://github.com/0gust1/md-vanilla-sidenotes
Je m'inspire de http://acdlite.github.io/jquery.sidenotes/ , mais souhaite me passer de jQuery, et faire quelque chose de plus léger (il y a de très bonnes idées dans le truc de départ, mais aussi d'autres choses plus accessoires).
Quelques jours après avoir commencé à écrire les première lignes de JS, ce lien a tourné sur twitter et résume bien pourquoi tout ceci m'intéresse : https://medium.com/de-correspondent/links-are-broken-these-three-alternatives-have-improved-our-readers-reading-experience-796c302c8930
Le point de départ est un document HTML comportant des "footnotes" balisées un peu de cette façon :
Voici les problématiques auxquelles je réfléchis :
1 : responsive et stylage :
Grosso modo : stylage : gérer le maximum de choses en CSS (plutôt responsabilité de l'implémenteur) : media queries et/ou classes CSS différentes selon le type de sidenotes (sidenotes, infocards ou footnotes).
Par contre, une partie du comportement "responsive" est à gérer par JS. On a 3 états possibles :
Il faut donc 3 fonctions qui seront exécutées en fonction des "passages de breakpoints" détectés et bien sûr de la taille d'écran au chargement de la page.
Sur la page de démo du plugin jquery dont je m'inspire ( http://acdlite.github.io/jquery.sidenotes/ ), l'auteur utilise http://responsejs.com/.
Bref, il nous faut quelque chose capable d'executer des fonctions JS en fonction de la taille de la fenêtre du navigateur.
2 : performance :
J'ai l'impression que l'idéal serait de ne pas se refarcir des requêtes dans le DOM (pour aller chercher le contenu et l'insérer aux bon endroits) à chaque passage de "breakpoint". Je pensais éventuellement maintenir en mémoire une structure de données contenant les notes, qui serait passée en paramètres aux fonctions de placement dans le DOM (c'est ce que j'ai commencé avec la fonction
processFootNotesToSideNotes
).Si possible, j'essaierais bien d'utiliser les docFragments, qui apportent beaucoup en performance en cas d'insertions multiples dans le DOM.
3 : Packaging
Mon coeur balance. J'aime les modules CommonJs, mais du coup je crois que ça implique que l'implémenteur passe par browserify. J'ai vu sur le net des tentatives de faire des genre de modules universels (http://dontkry.com/posts/code/browserify-and-the-universal-module-definition.html) mais franchement, c'est pas beau...
A propos de l'idée de david `bgk (https://larlet.fr/david/stream/2015/02/13/)
C'est vraiment pas éloigné de ce que je cherche à faire, et l'idée du prefetch des liens fait rêver...
En ajoutant les serviceworkers ou un genre de build on est "presque" (manque le push) sur quelque chose qui pourrait faire du commentaire décentralisé ?