ModeConnections.js 12 KB

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