ModeConnections.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. type:'',
  17. text:'',
  18. summary:'',
  19. active:true,
  20. opened:false,
  21. links:null,
  22. parents:[],
  23. lang:_dbs.lang,
  24. setuptext(vn){
  25. // console.log('setuptext', vn);
  26. // construct text
  27. this.text = vn.attrs.text || '';
  28. this.rendered_text = markdown.render(this.text);
  29. // construct summary
  30. // TODO: summary needs more work (strip tags, markdown render)
  31. this.summary = this.text.match('([^ ]*[ ]{0,1}){1,6}')[0];
  32. this.summary = this.summary.trim().replace(/_([^_]+)$/g, "_$1_");
  33. this.summary = this.summary.replace(/\[([^\]]+)$/g, "$1");
  34. this.summary = markdown.renderInline(this.summary) + " …";
  35. },
  36. oninit(vn){
  37. this.id = vn.attrs.id;
  38. this.type = vn.attrs.type;
  39. this.title = vn.attrs.title || "title";
  40. this.setuptext(vn);
  41. if(typeof vn.attrs.active !== 'undefined')
  42. this.active = vn.attrs.active;
  43. // links
  44. this.links = _dbs.data_strct[this.id];
  45. // console.log(this.links);
  46. // parents memorize where do we come from to avoid duplicates and looping nav
  47. if(vn.attrs.parents){
  48. this.parents = this.parents.concat(vn.attrs.parents);
  49. // console.log('_Dot init '+this.id+' parents :',this.parents);
  50. }
  51. },
  52. oncreate(vn){
  53. if(this.active){
  54. vn.dom.classList.remove('disabled');
  55. }else{
  56. vn.dom.classList.add('disabled');
  57. }
  58. },
  59. onbeforeupdate(vn){
  60. // console.log('onbeforeupdate');
  61. if(this.lang != _dbs.lang){
  62. this.lang = _dbs.lang;
  63. this.setuptext(vn);
  64. }
  65. },
  66. view(vn){
  67. if (this.active && this.opened) {
  68. // full view of dot with linked dots
  69. // console.log('_Dot view '+this.id+' parents :',this.parents);
  70. var dot_content = [
  71. // links to
  72. this.links.to.length
  73. ? m('nav', {'class':'links to'}, this.links.to.map(id => {
  74. // console.log(id);
  75. if(typeof _dbs.data_byid[_dbs.lang][id] !== 'undefined'){
  76. return m(_Dot, {
  77. "id":id,
  78. 'text':_dbs.data_byid[_dbs.lang][id].text,
  79. 'type':'',
  80. // passe the memory of crossed dots plus the current one
  81. 'parents':vn.state.parents.concat([vn.state.id]),
  82. // activate link only if not in parents (already went through it)
  83. 'active':vn.state.parents.indexOf(id) == -1 ? true:false
  84. });
  85. }
  86. })
  87. )
  88. : null,
  89. // id
  90. m('span', {'class':'id'}, this.id), // this.type+' '+
  91. // bullet
  92. m('span', {'class':'bullet'}, m.trust('⚫')),
  93. // full text
  94. m('section', {
  95. 'class':'text',
  96. onmouseover(e){
  97. e.preventDefault();
  98. if(e.target.nodeName == "A" ){
  99. // console.log("over e.target", e.target);
  100. // console.log('over vn', vn);
  101. var id = e.target.getAttribute("href");
  102. // add highlight class
  103. vn.dom.querySelector('nav.links>div[uid="'+id+'"]').classList.add('highlight');
  104. }else{
  105. // remove all hilight class
  106. for (link of vn.dom.querySelectorAll('nav.links>div.dot')) {
  107. link.classList.remove('highlight');
  108. }
  109. }
  110. },
  111. onclick(e){
  112. e.preventDefault();
  113. if(e.target.nodeName == "A" ){
  114. // console.log("over e.target", e.target);
  115. // console.log('over vn', vn);
  116. var id = e.target.getAttribute("href");
  117. // add highlight class
  118. vn.dom.querySelector('nav.links>div[uid="'+id+'"]>.summary').click();
  119. }
  120. }
  121. }, m.trust(this.rendered_text)),
  122. // links from
  123. this.links.from.length
  124. ? m('nav', {'class':'links from'}, this.links.from.map(id => {
  125. // retrun a dot
  126. return m(_Dot, {
  127. "id":id,
  128. 'text':_dbs.data_byid[_dbs.lang][id].text,
  129. 'type':'',
  130. // passe the memory of crossed dots plus the current one
  131. 'parents':vn.state.parents.concat([vn.state.id]),
  132. // activate link only if not in parents (already went through it)
  133. 'active':vn.state.parents.indexOf(id) == -1 ? true:false
  134. });
  135. })
  136. )
  137. : null
  138. ];
  139. }else{
  140. // preview dot
  141. var dot_content = [
  142. m('span', {'class':'id'}, this.id), // this.type+' '+
  143. m('span', {'class':'bullet'}, m.trust('•')),
  144. m('p', {
  145. 'class':'summary',
  146. onclick(e){
  147. // TODO: animate openening (text and links separatly)
  148. vn.state.opened = true;
  149. }
  150. }, m.trust(this.summary))
  151. ];
  152. }
  153. return m('div',{
  154. 'uid':this.id,
  155. 'class':'dot'
  156. },
  157. dot_content
  158. );
  159. },
  160. onupdate(vn){
  161. // console.log('_Dot : onupdate', vn);
  162. if(this.active){
  163. if (this.opened){
  164. vn.dom.classList.add('opened');
  165. if(this.links.to.length)
  166. vn.dom.classList.add('to-links');
  167. if(this.links.from.length)
  168. vn.dom.classList.add('from-links');
  169. }else{
  170. vn.dom.classList.remove('opened');
  171. }
  172. }
  173. }
  174. }
  175. /*
  176. down vote
  177. Here's full list of black dotlikes from unicode
  178. ● - ● - Black Circle
  179. ⏺ - ⏺ - Black Circle for Record
  180. ⚫ - ⚫ - Medium Black Circle
  181. ⬤ - ⬤ - Black Large Circle
  182. ⧭ - ⧭ - Black Circle with Down Arrow
  183. 🞄 - 🞄 - Black Slightly Small Circle
  184. • - • - Bullet
  185. ∙ - ∙ - Bullet Operator
  186. ⋅ - ⋅ - Dot Operator
  187. 🌑 - 🌑 - New Moon Symbol
  188. */
  189. // _______ _ __ __
  190. // / ___/ / (_) /__/ /
  191. // / /__/ _ \/ / / _ /
  192. // \___/_//_/_/_/\_,_/
  193. var _Child = {
  194. id:null,
  195. part:null,
  196. type:null,
  197. // nested:false,
  198. text:'',
  199. oninit(vn){
  200. // console.log('vn.attrs', vn.attrs);
  201. this.id = vn.attrs.id;
  202. this.type = vn.attrs.type;
  203. // vn.state.part = vn.state.slug.match(/^(\d)(.+)/)[1];
  204. this.text = vn.attrs.text;
  205. // this.nested = vn.attrs.nested || false;
  206. },
  207. onbeforeupdate(vn, old){
  208. // this.nested = vn.attrs.nested || false;
  209. this.type = vn.attrs.type;
  210. this.text = vn.attrs.text;
  211. },
  212. view(vn){
  213. return m(_Dot, {"id":this.id, 'text':this.text, 'type':this.type});
  214. }
  215. };
  216. // ______
  217. // / ____/___ ____ ____ ________
  218. // / __/ / __ \/ __ \/ __ \/ ___/ _ \
  219. // / /___/ / / / /_/ / / / / /__/ __/
  220. // /_____/_/ /_/\____/_/ /_/\___/\___/
  221. var _Enonce = {
  222. partid:null,
  223. id:null,
  224. title:null,
  225. text:null,
  226. // nested:false,
  227. childs:[],
  228. oninit(vn){
  229. // // console.log('Enonce on init', vn);
  230. this.partid = vn.attrs.partid;
  231. this.id = vn.attrs.id;
  232. this.title = vn.attrs.title || "";
  233. this.text = vn.attrs.text;
  234. this.childs = vn.attrs.childs || [];
  235. // this.nested = vn.attrs.nested || false;
  236. },
  237. onbeforeupdate(vn, old) {
  238. // console.log(vn.attrs.childs);
  239. this.title = vn.attrs.title || "";
  240. this.text = vn.attrs.text;
  241. this.childs = vn.attrs.childs || [];
  242. // this.nested = vn.attrs.nested || false;
  243. // if(vn.attrs.id == '1d1') console.log('_Enonce UPDATE, text :', vn.attrs.text);
  244. },
  245. view(vn){
  246. // if(vn.attrs.id == '1d1') console.log('_Enonce VIEW, text :', vn.attrs.text);
  247. return [
  248. // create dot
  249. m(_Dot, {"id":this.id, 'text':this.text,'type':this.title}),
  250. // addd children
  251. this.childs.map(c => { return m(_Child, c); })
  252. ]
  253. }
  254. }
  255. // ____ __
  256. // / __ \____ ______/ /_
  257. // / /_/ / __ `/ ___/ __/
  258. // / ____/ /_/ / / / /_
  259. // /_/ \__,_/_/ \__/
  260. var _Part = {
  261. oninit(vn){
  262. this.id = vn.attrs.id;
  263. this.title = vn.attrs.title || "";
  264. this.enonces = vn.attrs.enonces;
  265. },
  266. onbeforeupdate(vn, old){
  267. // console.log('_Part, onbeforeupdate old',old);
  268. this.title = vn.attrs.title || "";
  269. this.enonces = vn.attrs.enonces;
  270. },
  271. view(vn){
  272. // console.log(vn.attrs.enonces);
  273. return m("section", {
  274. 'id' :this.id,
  275. 'class' :'part'
  276. },
  277. [
  278. // create title node
  279. m("h1", {'class':'part-title', 'part':this.id}, m.trust(markdown.renderInline(this.title))),
  280. // create text node
  281. this.enonces.map(e => {
  282. // console.log(e.text);
  283. // return m(_Enonce, Object.assign({"partid":this.id},e))
  284. switch (e.type) {
  285. case "title":
  286. // handle titles
  287. return m("h2", {'class':'title'}, m.trust(markdown.renderInline(e.title)));
  288. break;
  289. case "filet":
  290. // handle filets
  291. return m("h4", {'class':'filet'}, m.trust(markdown.renderInline(e.title)));
  292. break;
  293. default:
  294. // or build structure
  295. return m(_Enonce, Object.assign({"partid":this.id},e));
  296. }
  297. })
  298. ]
  299. )
  300. }
  301. }
  302. // ____ __
  303. // / _/___ / /__________
  304. // / // __ \/ __/ ___/ __ \
  305. // _/ // / / / /_/ / / /_/ /
  306. // /___/_/ /_/\__/_/ \____/
  307. var _Intro = {
  308. oninit(vn){
  309. console.log('_Intro : oninit : vn', vn);
  310. this.id = vn.attrs.id;
  311. this.text = vn.attrs.text || '';
  312. },
  313. onbeforeupdate(vn, old){
  314. this.id = vn.attrs.id;
  315. this.text = vn.attrs.text || '';
  316. },
  317. view(vn){
  318. return m("section", {'class':'intro'}, m("p",m.trust(markdown.renderInline(this.text))));
  319. }
  320. }
  321. // ______ __ _
  322. // / ____/___ ____ ____ ___ _____/ /_(_)___ ____ _____
  323. // / / / __ \/ __ \/ __ \/ _ \/ ___/ __/ / __ \/ __ \/ ___/
  324. // / /___/ /_/ / / / / / / / __/ /__/ /_/ / /_/ / / / (__ )
  325. // \____/\____/_/ /_/_/ /_/\___/\___/\__/_/\____/_/ /_/____/
  326. module.exports = {
  327. oncreate(vn){
  328. document.body.classList.add('mode-connections');
  329. _Ui.init();
  330. },
  331. view(vn){
  332. // console.log('_ModeConnections view', vn.attrs.lang);
  333. return m('main', {id:"content", 'class':'mode-connections'}, _dbs.data[vn.attrs.lang].map(p => {
  334. if(p.id == 'intro'){
  335. return m(_Intro,p);
  336. }else{
  337. return m(_Part,p);
  338. }
  339. })
  340. );
  341. }
  342. }