ModeConnections.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. var m = require('mithril');
  2. // https://github.com/markdown-it/markdown-it
  3. var markdown = require('markdown-it')()
  4. .use(require('markdown-it-footnote'));
  5. var _dbs = require('./dbs');
  6. var _Header = require('./header');
  7. var _Footer = require('./footer');
  8. var _Ui = require('./ui.js');
  9. // ____ __
  10. // / __ \____ / /_
  11. // / / / / __ \/ __/
  12. // / /_/ / /_/ / /_
  13. // /_____/\____/\__/
  14. var _Dot = {
  15. id:null,
  16. dottype:null,
  17. type:'',
  18. title:'',
  19. text:'',
  20. summary:'',
  21. active:true,
  22. opened:false,
  23. links:null,
  24. parents:[],
  25. lang:_dbs.lang,
  26. setupDotType(vn){
  27. // var rx_id = /^(\d)(app|agd|\d\d|pr|ad|ap|c|p|d|a)(cd|sc|\d\d|d|c|a|l|p|\d)?(e|\d|sc)?(d|c|a|sc)?$/;
  28. // var m = this.id.match(rx_id);
  29. // if(m){
  30. // switch(true){
  31. // case /^\d{2}$/.test(m[2]):
  32. // switch(true){
  33. // case /^cd$/.test(m[3]) : this.dottype = 'corollaire-demo'; break;
  34. // case /^sc$/.test(m[3]) : this.dottype = 'scolie'; break;
  35. // case /^d$/.test(m[3]) : this.dottype = 'demonstration'; break;
  36. // case /^c$/.test(m[3]) :
  37. // switch(true){
  38. // case /^sc$/.test(m[4]): this.dottype = 'scolie'; break;
  39. // case /^d$/.test(m[4]) : this.dottype = 'demonstration'; break;
  40. // case /^d$/.test(m[5]) : this.dottype = 'demonstration'; break;
  41. // case /^sc$/.test(m[5]): this.dottype = 'scolie'; break;
  42. // case /^\d$/.test(m[4]): this.dottype = 'corollaire'; break;
  43. // case !m[4] : this.dottype = 'corollaire'; break;
  44. // }
  45. // break;
  46. // case /^a$/.test(m[3]) : this.dottype = 'axiom'; break;
  47. // case /^l$/.test(m[3]) :
  48. // switch(true){
  49. // case /^d$/.test(m[5]) : this.dottype = 'demonstration'; break;
  50. // case /^sc$/.test(m[5]): this.dottype = 'scolie'; break;
  51. // case !m[5] : this.dottype = 'lemme'; break;
  52. // }
  53. // break;
  54. // case /^p$/.test(m[3]) : this.dottype = 'postulat'; break;
  55. // case /^\d$/.test(m[3]) : this.dottype = '??'; break;
  56. // case /^\d{2}$/.test(m[3]) : this.dottype = '??'; break;
  57. // case !m[3] : this.dottype = 'proposition'; break;
  58. // }
  59. // break;
  60. // case /^app|ap$/.test(m[2]) : this.dottype = 'appendice'; break;
  61. // case /^agd$/.test(m[2]) : this.dottype = 'def-gen-affect'; break;
  62. // case /^pr$/.test(m[2]) : this.dottype = 'preface'; break;
  63. // case /^ad$/.test(m[2]) :
  64. // switch(true){
  65. // case /^e$/.test(m[4]) :this.dottype = 'explication'; break;
  66. // case !m[4] :this.dottype = 'def-affect'; break;
  67. // }
  68. // break;
  69. // case /^c$/.test(m[2]) : this.dottype = 'chapitre'; break;
  70. // case /^p$/.test(m[2]) : this.dottype = 'postulat'; break;
  71. // case /^d$/.test(m[2]) :
  72. // switch(true){
  73. // case /^e$/.test(m[4]) : this.dottype = 'explication'; break;
  74. // case !m[4] : this.dottype = 'definition'; break;
  75. // }
  76. // break;
  77. // case /^a$/.test(m[2]) : this.dottype = 'axiom'; break;
  78. // }
  79. // // }
  80. // }
  81. // console.log(`${this.id} -> ${this.dottype}`,m);
  82. //
  83. // // TODO: fix false ids
  84. // // we have app and ap for appendice (1app | 4ap)
  85. // // 213def ??
  86. // // 209cd demo ou corollaire-demo ??
  87. // // 210csc scolie ou corollaire-scolie ??
  88. // // 213l1d demo ??
  89. },
  90. setupTitle(vn){
  91. this.title = vn.attrs.title;
  92. if(!this.title){
  93. this.title = this.type;
  94. }
  95. },
  96. setuptext(vn){
  97. // console.log('setuptext', vn);
  98. // construct text
  99. this.text = vn.attrs.text || '';
  100. this.rendered_text = markdown.render(this.text);
  101. // construct summary
  102. // TODO: summary needs more work (strip tags, markdown render)
  103. this.summary = this.text.match('([^ ]*[ ]{0,1}){1,6}')[0];
  104. this.summary = this.summary.trim().replace(/_([^_]+)$/g, "_$1_");
  105. this.summary = this.summary.replace(/\[([^\]]+)$/g, "$1");
  106. this.summary = markdown.renderInline(this.summary) + " …";
  107. },
  108. oninit(vn){
  109. this.id = vn.attrs.id;
  110. this.type = vn.attrs.type;
  111. // this.title = vn.attrs.title || "title";
  112. // this.setupDotType(vn);
  113. this.dottype = vn.attrs.dottype;
  114. this.setupTitle(vn);
  115. this.setuptext(vn);
  116. console.log(`${this.id} -> ${this.dottype}`);
  117. if(typeof vn.attrs.active !== 'undefined')
  118. this.active = vn.attrs.active;
  119. // links
  120. this.links = _dbs.data_strct[this.id];
  121. // console.log(this.links);
  122. // parents memorize where do we come from to avoid duplicates and looping nav
  123. if(vn.attrs.parents){
  124. this.parents = this.parents.concat(vn.attrs.parents);
  125. // console.log('_Dot init '+this.id+' parents :',this.parents);
  126. }
  127. },
  128. oncreate(vn){
  129. if(this.active){
  130. vn.dom.classList.remove('disabled');
  131. }else{
  132. vn.dom.classList.add('disabled');
  133. }
  134. },
  135. onbeforeupdate(vn){
  136. // console.log('onbeforeupdate');
  137. if(this.lang != _dbs.lang){
  138. this.lang = _dbs.lang;
  139. this.setuptext(vn);
  140. }
  141. },
  142. view(vn){
  143. if (this.active && this.opened) {
  144. // full view of dot with linked dots
  145. // console.log('_Dot view '+this.id+' parents :',this.parents);
  146. var dot_content = [
  147. // links to
  148. // TODO: add dottype class to nested dots
  149. this.links.to.length
  150. ? m('nav', {'class':'links to'}, this.links.to.map(id => {
  151. // console.log(id);
  152. if(typeof _dbs.data_byid[_dbs.lang][id] !== 'undefined'){
  153. return m(_Dot, {
  154. "id":id,
  155. 'text':_dbs.data_byid[_dbs.lang][id].text,
  156. 'type':'',
  157. // passe the memory of crossed dots plus the current one
  158. 'parents':vn.state.parents.concat([vn.state.id]),
  159. // activate link only if not in parents (already went through it)
  160. 'active':vn.state.parents.indexOf(id) == -1 ? true:false
  161. });
  162. }
  163. })
  164. )
  165. : null,
  166. // id
  167. // m('span', {'class':'id'}, this.id), // this.type+' '+
  168. // bullet
  169. // m('span', {'class':'bullet'}, m.trust('⚫')),
  170. // Title
  171. m('span', {'class':'title'}, m.trust(this.title)),
  172. // full text
  173. m('section', {
  174. 'class':'text',
  175. onmouseover(e){
  176. e.preventDefault();
  177. if(e.target.nodeName == "A" ){
  178. // console.log("over e.target", e.target);
  179. // console.log('over vn', vn);
  180. var id = e.target.getAttribute("href");
  181. // add highlight class
  182. vn.dom.querySelector('nav.links>div[uid="'+id+'"]').classList.add('highlight');
  183. }else{
  184. // remove all hilight class
  185. for (link of vn.dom.querySelectorAll('nav.links>div.dot')) {
  186. link.classList.remove('highlight');
  187. }
  188. }
  189. },
  190. onclick(e){
  191. e.preventDefault();
  192. if(e.target.nodeName == "A" ){
  193. // console.log("over e.target", e.target);
  194. // console.log('over vn', vn);
  195. var id = e.target.getAttribute("href");
  196. // add highlight class
  197. vn.dom.querySelector('nav.links>div[uid="'+id+'"]>.summary').click();
  198. }
  199. }
  200. }, m.trust(this.rendered_text)),
  201. // links from
  202. this.links.from.length
  203. ? m('nav', {'class':'links from'}, this.links.from.map(id => {
  204. // retrun a dot
  205. // TODO: add dottype class to nested dots
  206. return m(_Dot, {
  207. "id":id,
  208. 'text':_dbs.data_byid[_dbs.lang][id].text,
  209. 'type':'',
  210. // passe the memory of crossed dots plus the current one
  211. 'parents':vn.state.parents.concat([vn.state.id]),
  212. // activate link only if not in parents (already went through it)
  213. 'active':vn.state.parents.indexOf(id) == -1 ? true:false
  214. });
  215. })
  216. )
  217. : null
  218. ];
  219. }else{
  220. // preview dot
  221. var dot_content = [
  222. // m('span', {'class':'id'}, this.id), // this.type+' '+
  223. // m('span', {'class':'bullet'}, m.trust('•')),
  224. m('span', {'class':'title'}, m.trust(this.title)),
  225. m('p', {
  226. 'class':'summary',
  227. onclick(e){
  228. // TODO: animate openening (text and links separatly)
  229. vn.state.opened = true;
  230. }
  231. }, m.trust(this.summary))
  232. ];
  233. }
  234. return m('div',{
  235. 'uid':this.id,
  236. 'class':`dot ${this.dottype}`
  237. },
  238. dot_content
  239. );
  240. },
  241. onupdate(vn){
  242. // console.log('_Dot : onupdate', vn);
  243. if(this.active){
  244. if (this.opened){
  245. vn.dom.classList.add('opened');
  246. if(this.links.to.length)
  247. vn.dom.classList.add('to-links');
  248. if(this.links.from.length)
  249. vn.dom.classList.add('from-links');
  250. }else{
  251. vn.dom.classList.remove('opened');
  252. }
  253. }
  254. }
  255. }
  256. /*
  257. down vote
  258. Here's full list of black dotlikes from unicode
  259. ● - ● - Black Circle
  260. ⏺ - ⏺ - Black Circle for Record
  261. ⚫ - ⚫ - Medium Black Circle
  262. ⬤ - ⬤ - Black Large Circle
  263. ⧭ - ⧭ - Black Circle with Down Arrow
  264. 🞄 - 🞄 - Black Slightly Small Circle
  265. • - • - Bullet
  266. ∙ - ∙ - Bullet Operator
  267. ⋅ - ⋅ - Dot Operator
  268. 🌑 - 🌑 - New Moon Symbol
  269. */
  270. // _______ _ __ __
  271. // / ___/ / (_) /__/ /
  272. // / /__/ _ \/ / / _ /
  273. // \___/_//_/_/_/\_,_/
  274. var _Child = {
  275. id:null,
  276. part:null,
  277. type:null,
  278. dottype:null,
  279. // nested:false,
  280. text:'',
  281. oninit(vn){
  282. // console.log('vn.attrs', vn.attrs);
  283. this.id = vn.attrs.id;
  284. this.type = vn.attrs.type;
  285. // vn.state.part = vn.state.slug.match(/^(\d)(.+)/)[1];
  286. this.text = vn.attrs.text;
  287. // this.nested = vn.attrs.nested || false;
  288. this.dottype = vn.attrs.dottype;
  289. },
  290. onbeforeupdate(vn, old){
  291. // this.nested = vn.attrs.nested || false;
  292. this.type = vn.attrs.type;
  293. this.text = vn.attrs.text;
  294. },
  295. view(vn){
  296. return m(_Dot, {"id":this.id, 'text':this.text, 'type':this.type, 'dottype':this.dottype});
  297. }
  298. };
  299. // ______
  300. // / ____/___ ____ ____ ________
  301. // / __/ / __ \/ __ \/ __ \/ ___/ _ \
  302. // / /___/ / / / /_/ / / / / /__/ __/
  303. // /_____/_/ /_/\____/_/ /_/\___/\___/
  304. var _Enonce = {
  305. partid:null,
  306. id:null,
  307. title:null,
  308. text:null,
  309. dottype:null,
  310. // nested:false,
  311. childs:[],
  312. oninit(vn){
  313. // // console.log('Enonce on init', vn);
  314. this.partid = vn.attrs.partid;
  315. this.id = vn.attrs.id;
  316. this.title = vn.attrs.title || "";
  317. this.text = vn.attrs.text;
  318. this.childs = vn.attrs.childs || [];
  319. // this.nested = vn.attrs.nested || false;
  320. this.dottype = vn.attrs.dottype;
  321. },
  322. onbeforeupdate(vn, old) {
  323. // console.log(vn.attrs.childs);
  324. this.title = vn.attrs.title || "";
  325. this.text = vn.attrs.text;
  326. this.childs = vn.attrs.childs || [];
  327. // this.nested = vn.attrs.nested || false;
  328. // if(vn.attrs.id == '1d1') console.log('_Enonce UPDATE, text :', vn.attrs.text);
  329. this.dottype = vn.attrs.dottype;
  330. },
  331. view(vn){
  332. // if(vn.attrs.id == '1d1') console.log('_Enonce VIEW, text :', vn.attrs.text);
  333. return [
  334. // create dot
  335. m(_Dot, {"id":this.id, 'text':this.text,'type':this.title, 'dottype':this.dottype}),
  336. // addd children
  337. this.childs.map(c => { return m(_Child, c); })
  338. ]
  339. }
  340. }
  341. // ____ __
  342. // / __ \____ ______/ /_
  343. // / /_/ / __ `/ ___/ __/
  344. // / ____/ /_/ / / / /_
  345. // /_/ \__,_/_/ \__/
  346. var _Part = {
  347. oninit(vn){
  348. this.id = vn.attrs.id;
  349. this.title = vn.attrs.title || "";
  350. this.enonces = vn.attrs.enonces;
  351. },
  352. onbeforeupdate(vn, old){
  353. // console.log('_Part, onbeforeupdate old',old);
  354. this.title = vn.attrs.title || "";
  355. this.enonces = vn.attrs.enonces;
  356. },
  357. view(vn){
  358. // console.log(vn.attrs.enonces);
  359. return m("section", {
  360. 'id' :this.id,
  361. 'class' :'part'
  362. },
  363. [
  364. // create title node
  365. m("h1", {'class':'part-title', 'part':this.id}, m.trust(markdown.renderInline(this.title))),
  366. // create text node
  367. this.enonces.map(e => {
  368. // console.log(e.text);
  369. // return m(_Enonce, Object.assign({"partid":this.id},e))
  370. switch (e.type) {
  371. case "title":
  372. // handle titles
  373. return m("h2", {'class':'title'}, m.trust(markdown.renderInline(e.title)));
  374. break;
  375. case "filet":
  376. // handle filets
  377. return m("h4", {'class':'filet'}, m.trust(markdown.renderInline(e.title)));
  378. break;
  379. default:
  380. // or build structure
  381. return m(_Enonce, Object.assign({"partid":this.id},e));
  382. }
  383. })
  384. ]
  385. )
  386. }
  387. }
  388. // ____ __
  389. // / _/___ / /__________
  390. // / // __ \/ __/ ___/ __ \
  391. // _/ // / / / /_/ / / /_/ /
  392. // /___/_/ /_/\__/_/ \____/
  393. var _Intro = {
  394. oninit(vn){
  395. console.log('_Intro : oninit : vn', vn);
  396. this.id = vn.attrs.id;
  397. this.text = vn.attrs.text || '';
  398. },
  399. onbeforeupdate(vn, old){
  400. this.id = vn.attrs.id;
  401. this.text = vn.attrs.text || '';
  402. },
  403. view(vn){
  404. return m("section", {'class':'intro'}, m("p",m.trust(markdown.renderInline(this.text))));
  405. }
  406. }
  407. // ______ __ _
  408. // / ____/___ ____ ____ ___ _____/ /_(_)___ ____ _____
  409. // / / / __ \/ __ \/ __ \/ _ \/ ___/ __/ / __ \/ __ \/ ___/
  410. // / /___/ /_/ / / / / / / / __/ /__/ /_/ / /_/ / / / (__ )
  411. // \____/\____/_/ /_/_/ /_/\___/\___/\__/_/\____/_/ /_/____/
  412. module.exports = {
  413. oncreate(vn){
  414. document.body.classList.add('mode-connections');
  415. _Ui.init();
  416. },
  417. view(vn){
  418. // console.log('_ModeConnections view', vn.attrs.lang);
  419. return m('main', {id:"content", 'class':'mode-connections'}, _dbs.data[vn.attrs.lang].map(p => {
  420. if(p.id == 'intro'){
  421. return m(_Intro,p);
  422. }else{
  423. return m(_Part,p);
  424. }
  425. })
  426. );
  427. }
  428. }